• Elasticsearch简单的使用步骤以及查询模块的实现


    1)搭建ES服务器(单机、集群)
    2)创建映射,建立实体和索引库的映射关系,使用spring-data-elasticsearch
      //ES提供的接口,可以对索引库进行CRUD操作;T建立了和索引库映射关系的对象、ID为T对象中的主键类型
      ElasticsearchRepository<T,ID>

      //操作索引库
      ElasticSearchTemplate
    3)索引库维护(初始化数据导入全量索引、增量索引、索引同步、定时索引(全量索引、增量索引),手动索引)

    ES支持的搜索功能:

    分页查询、精确查询、范围查询、排序、分页、高亮、分组、正则、模糊、前后缀、一值多域、一域多值

     

    RestHighLevelClient实现搜索

    //RestHighLevelClient实现搜索功能
    //3个重要查询对象SearchRequest、SearchSourceBuilder(排序、分页、高亮、分组)、BoolQueryBuilder
    @Autowired
    private RestHighLevelClient restHighLevelClient;//准备工作,注入RestHighLevelClient
    public Map search(Map<String,String> searchMap) {
    //1.封装查询请求,指定“索引库”,“类型”
    SearchRequest searchRequest=new SearchRequest("sku");
    searchRequest.types("doc"); //设置查询的类型
    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//布尔查询构建器
    //1.1 关键字搜索
       if (StringUtils.isNotEmpty(searchMap.get("keywords"))){
    boolQueryBuilder.must(QueryBuilders.matchQuery("name",searchMap.get("keywords"));
      }
    //1.2 静态过滤,key固定
    if(searchMap.get("category")!=null){
    boolQueryBuilder.filter(QueryBuilders.termQuery("categoryName", searchMap.get("category"));
    }
    //1.4 动态过滤,key是拼接后得到
    for(String key: searchMap.keySet() ){
    if( key.startsWith("spec.") ){//如果是规格参数
    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key+".keyword", searchMap.get(key));
    boolQueryBuilder.filter(termQueryBuilder);
    }
    }
    //1.5 数值区间过滤
    if(searchMap.get("price")!=null ){
    String[] price = searchMap.get("price").split("-");
    if (prices.length == 2){
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(prices[1]));
          }
           boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(prices[0]));
    }
    searchSourceBuilder.query(boolQueryBuilder);
    //分页
    searchSourceBuilder.from(fromIndex);//开始索引设置
    searchSourceBuilder.size(pageSize);//每页记录数设置
    //排序
    searchSourceBuilder.sort("排序的域", "顺序DESC|ASC");
    //高亮设置
    HighlightBuilder highlightBuilder=new HighlightBuilder();
    highlightBuilder.field("name").preTags("<font style='color:red'>").postTags("</font>");
    searchSourceBuilder.highlighter(highlightBuilder);
    searchRequest.source(searchSourceBuilder);
    //聚合查询(商品分类)
    TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName");
    searchSourceBuilder.aggregation(termsAggregationBuilder);
    //2.封装查询结果
    Map resultMap=new HashMap();
    try {
    SearchResponse searchResponse  = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHits searchHits = searchResponse.getHits();
    long totalHits = searchHits.getTotalHits();
    System.out.println("记录数:"+totalHits);
    SearchHit[] hits = searchHits.getHits();

    //2.1 商品列表
    List<Map<String,Object>> resultList=new ArrayList<Map<String, Object>>();
    for(SearchHit hit:hits){
    Map<String, Object> skuMap = hit.getSourceAsMap();
    //name高亮处理
    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
    HighlightField name = highlightFields.get("name");
    Text[] fragments = name.fragments();
    skuMap.put("name",fragments[0].toString());//用高亮的内容替换原内容
    resultList.add(skuMap);
    }
    resultMap.put("rows",resultList);
    //2.2 商品分类列表
    Aggregations aggregations = searchResponse.getAggregations();
    Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
    Terms terms = (Terms) aggregationMap.get("sku_category");
    List<? extends Terms.Bucket> buckets =  terms.getBuckets();
    List<String> categoryList=new ArrayList();
    for( Terms.Bucket bucket:buckets ){
    categoryList.add(bucket.getKeyAsString());
    }
    resultMap.put("categoryList",categoryList);
    String categoryName = "";//商品分类名称
    if (searchMap.get("category") == null) { // 如果没有分类条件
    if (categoryList.size() > 0) {
    categoryName = categoryList.get(0);//提取分类列表的第一个分类
    }
    } else {
    categoryName = searchMap.get("category");//取出参数中的分类
    }
    //2.3 品牌列表
    if(searchMap.get("brand")==null) {
    List<Map> brandList = brandMapper.findListByCategoryName(categoryName);//查询品牌列表
    resultMap.put("brandList", brandList);
    }

    //2.4 规格列表
    List<Map> specList = specMapper.findListByCategoryName(categoryName);//规格列表
    for(Map spec:specList){
    String[] options = ((String) spec.get("options")).split(",");//规格选项列表
    spec.put("options",options);
    }
    resultMap.put("specList",specList);

    //2.5 页码
    long totalCount = searchHits.getTotalHits();  //总记录数
    long pageCount = (totalCount%pageSize==0 )?totalCount/pageSize:(totalCount/pageSize+1);//总页数
    resultMap.put("totalPages",pageCount);

    } catch (IOException e) {
    e.printStackTrace();
    }
    return resultMap;
    }

    ElasticsearchTemplate实现搜索

    //ElasticsearchTemplate(Sring-data-ElasticSearch)实现搜索功能
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;//准备工作,注入ElasticsearchTemplate
    //(1)构建搜索条件对象NativeSearchQueryBuilder:SearchRequest+SearchSourceBuilder
    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    //(2)构建多条件拼接查询对象BoolQueryBuilder
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    //(3)往多条件拼接条件对象BoolQueryBuilder中添加条件
    //boolQuery.must|should|mustNot|filter(QueryBuilders.xxxx)
      //xxxx表示查询类型,例如:term、match、range(正则、模糊、前后缀)
    ...????...//其它条件省略
    //(4)多条件查询对象BoolQueryBuilder,放入整理查询对象中
    nativeSearchQueryBuilder.withQuery(boolQuery);
    //(5)使用NativeSearchQueryBuilder设置分组、分页、排序、高亮查询条件
    //nativeSearchQueryBuilder.addAggregation|withPageable|withSort|withHighlightFields
    ...????...
    //(6)获取查询结果“页面展示数据结果集--->‘高亮结果集’”、“搜索面板条件数据”、“分页数据”
    AggregatedPage<SkuInfo> resultInfo = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class, new SearchResultMapper() {
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
    //1.查询“页面展示数据结果集--->‘高亮结果集’”
    List<T> list = new ArrayList<>();
    //获取查询命中结果数据
    SearchHits hits = searchResponse.getHits();
    if (hits != null){
    //有查询结果
    for (SearchHit hit : hits) {
    //SearchHit转换为skuinfo
    SkuInfo skuInfo = JSON.parseObject(hit.getSourceAsString(), SkuInfo.class);
                   //获取高亮数据,封装到”页面展示数据结果集“中
    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
    if (highlightFields != null && highlightFields.size()>0){
    //替换数据
    skuInfo.setName(highlightFields.get("name").getFragments()[0].toString());
    }
    list.add((T) skuInfo);
    }
    }
    return new AggregatedPageImpl<T>(list,pageable,hits.getTotalHits(),searchResponse.getAggregations());
    }
    });
    //2.“搜索面板条件数据”,分组查询结果
    //封装品牌的分组结果
    StringTerms brandTerms = (StringTerms) resultInfo.getAggregation(skuBrand);
    List<String> brandList = brandTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());
    //封装规格分组结果
    StringTerms specTerms= (StringTerms) resultInfo.getAggregation(skuSpec);
    List<String> specList = specTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());
    //3.“分页数据”
    long total = resultInfo.getTotalElements();//总条数
    int totalPages = resultInfo.getTotalPages()//总页数
    //4.查询结果封装
    Map<String,Object> resultMap = new HashMap<>();
    //总记录数
    resultMap.put("total",resultInfo.getTotalElements());
    //总页数
    resultMap.put("totalPages",resultInfo.getTotalPages());
    //数据集合
    resultMap.put("rows",resultInfo.getContent());
    //搜索面板-品牌列表
    resultMap.put("brandList",brandList);
    //搜索面板-规格列表
    resultMap.put("specList",this.formartSpec(specList));
    //搜索条件数据回显(定义在controller层进行返回)

     

  • 相关阅读:
    8.14-T1村通网(pupil)
    8.10-Day2T3 镇守府
    8.10-Day2T2 吃喝大法好
    8.10-Day2T1最小值
    8.10-DayT3游走(wander)
    8.10-Day1T2圈(circle)
    8.10-Day1T1-数字(number)
    bzoj2462: [BeiJing2011]矩阵模板
    8.7-Day1T1
    k8s高可用部署后续:SLB
  • 原文地址:https://www.cnblogs.com/zagwk/p/12686753.html
Copyright © 2020-2023  润新知