elasticsearch高级搜索功能多维度分享

目录

一、业务搜索核心功能

二、高级搜索匹配功能

三、搜索排序功能


elasticsearch高级搜索功能多维度分享,这也是实战的比较之路,此次我们全面分享常用的业务情景,全覆盖功能分享,让大家有一览众山小的感觉,废话少数,现在开始!

一、业务搜索核心功能

1、返回指定字段

GET /nandao_scenic/_search
{
  "_source": ["title","city"], 
  "query": {
    "term": {
      "city": {
        "value": "北京市"
      }
    }
  }
}

java 语言

public List getScenicField(String keyword) {
        SearchRequest searchRequest = new SearchRequest("scenic");//客户端请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
        searchSourceBuilder.query(new TermQueryBuilder("city", keyword));//构建query
        searchSourceBuilder.fetchSource(new String[]{"title", "city"}, null);//设定希望返回的字段数组
     //   searchSourceBuilder.from(20);
       // searchSourceBuilder.size(10);
        searchRequest.source(searchSourceBuilder);
        List resultList = new ArrayList();
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
            return resultList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 2、结果计数

GET /nandao_scenic/_count
{
   "query": {
    "term": {
      "city": {
        "value": "北京市"
      }
    }
  }
}

java语言

 public long getCityCount() {
        CountRequest countRequest = new CountRequest("scenic");//客户端count请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
        searchSourceBuilder.query(new TermQueryBuilder("city", "北京"));//构建query
        countRequest.source(searchSourceBuilder);//设置查询
        try {
            CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);//执行count
            return countResponse.getCount();//返回count结果
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

 3、结果分页

GET /nandao_scenic/_search
{
   "from": 0,
   "size": 20, 
  "query": {
    "term": {
      "city": {
        "value": "北京市"
      }
    }
  }
}

设置分页最大值:

PUT /nandao_scenic/_settings
{
  "index":{
    "max_result_window":10001
  }
}

 es不适合深度分页,影响性能。

java语言

 public List getScenicField(String keyword) {
        SearchRequest searchRequest = new SearchRequest("scenic");//客户端请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
        searchSourceBuilder.query(new TermQueryBuilder("city", keyword));//构建query
        searchSourceBuilder.fetchSource(new String[]{"title", "city"}, null);//设定希望返回的字段数组
        searchSourceBuilder.from(20);
        searchSourceBuilder.size(10);
        searchRequest.source(searchSourceBuilder);
        List resultList = new ArrayList();
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
            return resultList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

4、性能分析:开启

GET /nandao_scenic/_search
{
  "profile": "true", 
  "query": {
    "term": {
      "city": {
        "value": "北京市"
      }
    }
  }
}

5、评分分析

GET /nandao_scenic/_explain/003
{
  "query": {
    "term": {
      "city": {
        "value": "北京市"
      }
    }
  }
}

二、高级搜索匹配功能

1、查询所有文档

GET /nandao_scenic/_search
{
  "_source": ["title","city"], 
  "query": {
    "match_all": {
      "boost": 2
    }
  }
}

java客户端



public void matchAllSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery().boost(2.0f);//新建match_all查询,并设置boost值为2.0
        searchSourceBuilder.query(matchAllQueryBuilder);
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }


public void printResult(SearchRequest searchRequest) {
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
            SearchHits searchHits = searchResponse.getHits();//获取搜索结果集
            for (SearchHit searchHit : searchHits) {//遍历搜索结果集
                String index = searchHit.getIndex();//获取索引名称
                String id = searchHit.getId();//获取文档_id
                Float score = searchHit.getScore();//获取得分
                String source = searchHit.getSourceAsString();//获取文档内容
                System.out.println("index=" + index + ",id=" + id + ",score=" + score + ",source=" + source);//打印数据
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2、term 级别查询

2.1、term 查询

GET /nandao_scenic/_search
{
 "query": {
   "term": {
     "city": {
       "value": "北京市"
     }
   }
 }
}

2.2、terms查询

GET /nandao_scenic/_search
{
 "query": {
   "terms": {
     "city": [
       "北京市",
       "河南"
       ]
   }
 }
}

java客户端

 public void termsSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termsQuery("city", "北京", "天津"));//构建terms查询
        searchRequest.source(searchSourceBuilder);//设置查询请求
        printResult(searchRequest);//打印搜索结果
    }

 2.3、range查询

GET /nandao_scenic/_search
{
 "query": {
   "range": {
     "price": {
       "gte":50,
       "lte":100
     }
   }
 }
}

java语言客户端

 public void rangeSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建range查询
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("create_time").gte("20220115120000").lte("20220116120000");
        searchSourceBuilder.query(queryBuilder);
        searchRequest.source(searchSourceBuilder);//设置查询请求
        printResult(searchRequest);//打印搜索结果
    }

2. 4、exists 查询

GET /nandao_scenic/_search
{
 "query": {
   "exists": {
    "field": "tag"
   }
 }
}

java语言

  public void existsSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.existsQuery("tag"));
        searchRequest.source(searchSourceBuilder);
        printResult(searchRequest);
    }

 3、布尔类型

3.1、must查询

GET /nandao_scenic/_search
{
 "query": {
    "bool": {
      "must": [
        {
          "term": {
            "city": {
              "value": "北京市"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 220
            }
          }
        }
      ]
    }
 }
}

java语言

  public void mustSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市term查询
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(350).lte(400);//构建价格range查询
        boolQueryBuilder.must(termQueryIsReady).must(rangeQueryBuilder);//进行关系“与”查询
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

3.2、should查询

GET /nandao_scenic/_search
{
 "query": {
    "bool": {
      "should": [
        {
          "term": {
            "city": {
              "value": "北京市"
            }
          }
        },
        {
           "term": {
            "city": {
              "value": "北京市"
            }
          }
        }
      ]
    }
 }
}

java语言

public void shouldSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市为“北京”的term查询
        TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "天津");//构建城市为“天津”的term查询
        boolQueryBuilder.should(termQueryIsReady).should(termQueryWritter);//进行关系“或”查询
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

3.3、must not 查询

GET /nandao_scenic/_search
{
 "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "city": {
              "value": "北京市"
            }
          }
        },
        {
           "term": {
            "city": {
              "value": "河南"
            }
          }
        }
      ]
    }
 }
}

java客户端

    public void mustNotSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市为“北京”的term查询
        TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "天津");//构建城市为“天津”的term查询
        boolQueryBuilder.mustNot(termQueryIsReady).mustNot(termQueryWritter);//进行关系“必须不”查询
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

3.4、filter 查询

GET /nandao_scenic/_search
{
 "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "city": {
              "value": "北京市"
            }
          }
        },
        {
           "term": {
            "full": true
          }
        }
      ]
    }
 }
}

java客户端

public void filterSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.termQuery("city", "北京"));
        boolQueryBuilder.filter(QueryBuilders.termQuery("full", false));
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        printResult(searchRequest);
    }

4、Constant Scope 查询

GET /nandao_scenic/_search
{
  "_source": ["city"], 
 "query": {
   "constant_score": {
     "filter": {
       "match":{
         "city":"北京市"
       }
     }
   }
 }
}

java语言

public void constantScoreSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        ConstantScoreQueryBuilder constantScoreQueryBuilder = new ConstantScoreQueryBuilder(QueryBuilders.termQuery("amenities", "停车场"));//构建城市为“北京”的term查询
        searchSourceBuilder.query(constantScoreQueryBuilder);
        constantScoreQueryBuilder.boost(2.0f);
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

5、Function score 查询

GET /nandao_scenic/_search
{
  "_source": ["city"], 
 "query": {
   "function_score": {
     "query": {
       "term": {
         "city": {
           "value": "北京市"
         }
       }
     },
     "functions": [
       {
         "random_score": {}
       }
     ],
     "score_mode": "sum"
   }
 }
}

java语言

public void functionScoreSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQuery = QueryBuilders.termQuery("city", "北京");//构建term查询
        ScoreFunctionBuilder scoreFunction = ScoreFunctionBuilders.randomFunction();//构建随机函数
        //构建function_score查询
        FunctionScoreQueryBuilder funcQuery = QueryBuilders.functionScoreQuery(termQuery, scoreFunction).boostMode(CombineFunction.SUM);
        searchSourceBuilder.query(funcQuery);
        searchRequest.source(searchSourceBuilder);//设置查询请求
        printResult(searchRequest);//打印搜索结果
    }

 6、全文搜索

6.1、match 查询:只要包含一个字就能搜出来

GET /nandao_scenic/_search
{
  "_source": ["title"], 
     "query": {
       "match": {
           "title": "水山寺"
       }
     }
}

java客户端

  public void matchSearch() {
        SearchRequest searchRequest = new SearchRequest();//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("title", "山水寺").operator(Operator.AND));//新建match查询,并设置operator值为and
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

6.2、multi_match 查询

GET /nandao_scenic/_search
{
  "_source": ["title","city"], 
     "query": {
       "multi_match": {
         "query": "山市",
         "fields": [
           "city",
           "title"
           ]
       }
     }
}

java客户端

 public void multiMatchSearch() {
        SearchRequest searchRequest = new SearchRequest();//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("山市", "title", "city"));//新建multi_match查询,从"title"和"amenities"字段查询"假日"
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

 6.3、multi_phrase 查询

GET /nandao_scenic/_search
{
   "query": {
     "match_phrase": {
       "title": "台山"
     }
   }
}

java语言

 public void matchPhraseSearch() {
        SearchRequest searchRequest = new SearchRequest();//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchPhraseQuery( "title", "台山").slop(2)); 
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

 7、基于地理位置查询

GET /nandao_scenic/_search
{
  "_source": ["title","city"],
   "query": {
     "geo_distance": {
       "distance": "5km",
       "location":{
         "lat":"34.333",
         "lon":"23.56"
       }
     }
   }
}

java 客户端

public void geoDistanceSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //新建geo_distance查询,设置基准点坐标和周边距离
        searchSourceBuilder.query(QueryBuilders.geoDistanceQuery("location").distance(5, DistanceUnit.KILOMETERS).point(40.026919, 116.47473));
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

 多边形:

GET /nandao_scenic/_search
{
  
   "query": {
     "geo_polygon": {
       "location":{
         "points":[
           {
               "lat":"39.959829",
         "lon":"116.417088"
           },
           {
               "lat":"39.960272",
         "lon":"116.432035"
           },
           {
               "lat":"39.965802",
         "lon":"116.421399"
           }
           ]
       }
     }
   }
}

java语言

  public void geoPolygonSearch() {
        SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //新建geo_distance查询,设置基准点坐标和周边距离
        List geoPointList = new ArrayList();//新建多边形顶点列表
        //添加多边形顶点
        geoPointList.add(new GeoPoint(39.959829, 116.417088));
        geoPointList.add(new GeoPoint(39.960272, 116.432035));
        geoPointList.add(new GeoPoint(39.965802, 116.421399));
        searchSourceBuilder.query(QueryBuilders.geoPolygonQuery("location", geoPointList));//新建geo_polygon查询
        searchRequest.source(searchSourceBuilder);//设置查询
        printResult(searchRequest);//打印结果
    }

8、实战场景之一:京东搜索商品,前缀查询

PUT /nandao_scenic_sug
{
  "mappings": {
    "properties": {
      "query_word":{
        "type": "completion"
      }
    }
  }
}

查询

GET /nandao_scenic_sug/_search
{
  "suggest": {
    "scenic_zh_sug": {
      "prefix":"北京",
      "completion": {
        "field": "query_word"
      }
    }
  }
}

 java语言

 public void suggestSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("nandao_scenic_sug");//创建搜索请求,指定索引名称为scenic_sug
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建completion类型搜索建议
        CompletionSuggestionBuilder comSuggest = SuggestBuilders.completionSuggestion("query_word").prefix("北京");
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("scenic_zh_sug", comSuggest);//添加搜索建议,"scenic_zh_sug"为自定义名称
        searchSourceBuilder.suggest(suggestBuilder);//设置suggest请求
        searchRequest.source(searchSourceBuilder);//设置查询请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);//进行搜索,获取搜索结果
        CompletionSuggestion suggestion = response.getSuggest().getSuggestion("scenic_zh_sug");//获取suggest结果
        System.out.println("sug result:");
        //遍历suggest结果,并进行打印
        for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()) {
            System.out.println("sug:" + option.getText().string());
        }
    }

三、搜索排序功能

1、按照普通字段排序

GET /nandao_scenic/_search
{
  "_source": ["title","city","price"],
  "query": {
    "match": {
      "title": "山"
    }
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      },
      "city": {
        "order": "desc"
      }
    }
  ]
}

java客户端

public void commonSort() {
        SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("title", "山"));//构建match查询
        searchRequest.source(searchSourceBuilder);//设置查询请求
        searchSourceBuilder.sort("price", SortOrder.DESC);//设置按照价格降序
        searchSourceBuilder.sort("praise", SortOrder.DESC);//设置按照口碑值降序
        printResult(searchRequest);//打印搜索结果
    }

 2、按照地理位置排序

GET /nandao_scenic/_search
{
  "_source": ["title","city","location"],
  "query": {
    "geo_distance": {
       "distance": "5km",
       "location":{
         "lat":"34.333",
         "lon":"23.56"
       }
     }
  },
  "sort": [
    {
      "geo_distance": {
       "location":{
         "lat":"34.333",
         "lon":"23.56"
       },
       "order": "desc",
       "unit":"km",
       "distance_type":"plane"
     }
    }
  ]
}

java客户端

 public void geoDistanceSearchSort() throws IOException {
        SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建geo_distance查询,搜索距离中心点5公里范围内的酒店
        searchSourceBuilder.query(QueryBuilders.geoDistanceQuery("location").distance(5, DistanceUnit.KILOMETERS).point(39.915143, 116.4039));
        //创建geo_distance_sort排序,设定按照与中心点的距离升序排序
        GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", 39.915143, 116.4039)
                .point(39.915143, 116.4039).unit(DistanceUnit.KILOMETERS).order(SortOrder.ASC);
        searchSourceBuilder.sort(geoDistanceSortBuilder);//设置排序规则
        searchRequest.source(searchSourceBuilder);//设置查询
        //开始搜索
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = searchResponse.getHits();//获取搜索结果
        System.out.println("search result distance sort:");
        //开始遍历搜索结果
        for (SearchHit searchHit : searchHits) {
            //得到酒店距离中心点的距离
            double geoDistance = (double) searchHit.getSortValues()[0];
            //以Map形式获取文档_source内容
            Map sourceMap = searchHit.getSourceAsMap();
            Object title = sourceMap.get("title");
            Object city = sourceMap.get("city");
            //打印结果
            System.out.println("title=" + title + ",city=" + city + ",geoDistance:" + geoDistance);
        }
    }

 到此,es高级搜索功能分享完毕,大家一定要多多练习,定会很快掌握,下篇我们分享文本搜索相关功能,敬请期待!

你可能感兴趣的:(ELK日志管理框架,elasticsearch)