ElasticSearch 搜索功能实现

ElasticSearch。

获取文档记录。

查询条件:

需要分词的字段sku名称 sku描述分词、定义分词器
有可能用于过滤的字段平台属性、三级分类、价格要索引
其他需要显示的字段skuId 图片路径不索引

封装elasticsearch的数据结构

public class PmsSearchSkuInfo implements Serializable {

    @Id
        private String id; /*id*/
    private String skuName; /*名称*/
    private String skuDesc; /*描述*/
    private String catalog3Id; /*三级分类id*/
    private String price; /*价格*/
    private String skuDefaultImg; /*图片*/
    private double hotScore; /*热度*/
    private String productId; /*spuid*/
    private List<PmsSkuAttrValue> pmsSkuAttrValue; /*sku销售属性*/
    
}

封装搜索参数

public class PmsSearchParam implements Serializable {

    private String catalog3Id;
    private String keyword;
    private String[] valueId;
}

指定索引的数据结构

PUT gmall
{
  "mappings": {
    "SkuInfo":{
      "properties": {
        "id":{
          "type": "keyword"
          , "index": false
        },
        "price":{
          "type": "double"
        },
         "skuName":{
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "skuDesc":{
          "type": "text",
          "analyzer": "ik_smart"
        },
        "catalog3Id":{
          "type": "keyword"
        },
        "skuDefaultImg":{
          "type": "keyword",
          "index": false
        },
        "skuAttrValueList":{
          "properties": {
            "valueId":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}



查询结果:

  • sku的列表(关键词高亮)
  • sku设计了哪些属性和属性值
  • 命中个数,用于分页;
GET gmall/SkuInfo/_search
{
  "query": {
    "bool": {
      "filter": [
          {"terms":{ "skuAttrValueList.valueId": ["46","45"]}},
          {"term":{"catalog3Id":"61"}}
        ],
        "must": 
            { "match": { "skuName": "128" }  }
    }
  }
  , "highlight": {
    "fields": {"skuName":{}}
  },
  "from": 3,
  "size": 1, 
  "sort":{"hotScore":{"order":"desc"}},
  "aggs": {
    "groupby_attr": {
      "terms": {
        "field": "skuAttrValueList.valueId"  
      }
    } 
    
  }
}

jest客户端包,方便组合复杂的查询json;

Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。官网

@Override
    public List<PmsSearchSkuInfo> list(PmsSearchParam pmsSearchParam){

        String dslStr = getSearchDsl(pmsSearchParam);
        System.err.println(dslStr);

        /*用api执行复杂查询*/
        List<PmsSearchSkuInfo> pmsSearchSkuInfos = new ArrayList<>();
        Search search = new Search.Builder(dslStr).addIndex("gmall0105").addType("PmsSkuInfo").build();
        SearchResult execute = null;
        try {
            execute = jestClient.execute(search);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<SearchResult.Hit<PmsSearchSkuInfo, Void>> hits = execute.getHits(PmsSearchSkuInfo.class);
        for (SearchResult.Hit<PmsSearchSkuInfo, Void> hit : hits) {
            PmsSearchSkuInfo pmsSearchSkuInfo = hit.source;
            /*替换高亮关键字*/
            Map<String, List<String>> highlight = hit.highlight;
            /*当不用关键字搜索时,Map<String, List<String>> highlight = hit.highlight;
            * 得到空的highlight,为了防止highlight.get("skuName").get(0);出现空指针异常
            * */
            if (highlight!=null){
                String skuName = highlight.get("skuName").get(0);
                pmsSearchSkuInfo.setSkuName(skuName);
            }
            pmsSearchSkuInfos.add(pmsSearchSkuInfo);
        }
        System.out.println(pmsSearchSkuInfos.size());
        return pmsSearchSkuInfos;
    }
private String getSearchDsl(PmsSearchParam pmsSearchParam) {

        String[] valueId = pmsSearchParam.getValueId();
        String keyword = pmsSearchParam.getKeyword();
        String catalog3Id = pmsSearchParam.getCatalog3Id();

        /*jest的dsl工具*/
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        /*bool*/
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        /*filter   , 在filter里面可以加term   , 相当于"pmsSkuAttrValue.valueId":"2" , 多个term可以new一个TermsQueryBuilder*/
        if (!StringUtils.isEmpty(catalog3Id)){
            TermQueryBuilder termQueryBuilder = new TermQueryBuilder("catalog3Id" , catalog3Id);
            boolQueryBuilder.filter(termQueryBuilder);
        }
        if (valueId!=null){
            for (String skuAttrValue : valueId) {
                TermQueryBuilder termQueryBuilder = new TermQueryBuilder("pmsSkuAttrValue.valueId" , skuAttrValue);
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }
        /*must   ,  在must里面可以加match  , 相当于"skuName": "P30Pro"*/
        if (!StringUtils.isEmpty(keyword)){
            MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName" , keyword);
            boolQueryBuilder.must(matchQueryBuilder);
        }
        /*query*/
        searchSourceBuilder.query(boolQueryBuilder);
        /*from*/
        searchSourceBuilder.from(0);
        /*size*/
        searchSourceBuilder.size(20);
        /*highlight ,关键字高亮显示*/
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.field("skuName");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlight(highlightBuilder);
        /*sort排序 , 按照id升序 , 降序 ,这里存在String与long类型转换问题,待解决*/
        searchSourceBuilder.sort("id" , SortOrder.DESC);

        /*最后转化成String返回给前台*/
        return searchSourceBuilder.toString();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值