当前位置:   article > 正文

Elasticsearch中【文档查询】DSL语句以及对应的Java实现

Elasticsearch中【文档查询】DSL语句以及对应的Java实现

目录

全文检索查询

精准查询

布尔查询 

排序、分页查询

高亮

地理查询

复合查询


Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:

  • 查询所有:查询出所有数据,一般测试用。例如:match_all

  • 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

    • match_query 

    • multi_match_query

  • 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:

    • ids

    • range

    • term

  • 地理(geo)查询:根据经纬度查询。例如:

    • geo_distance

    • geo_bounding_box

  • 复合(compound)查询复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:

    • bool

    • function_score

全文检索查询

单字段查询DSL:

  1. GET /indexName/_search
  2. {
  3.   "query": {
  4.     "match": {
  5.       "字段名""查询内容"
  6.     }
  7.   }
  8. }

例子:

多字段查询DSL:(搜索字段越多,对查询性能影响越大 ,所以建议在创建索引时使用copy_to字段约束,将需要参与搜索的字段复制到all字段中)

        例如创建索引时,"name"字段设置了"copy_to"参数,将其值复制到"all"字段中。这意味着当你在Elasticsearch中索引一个文档时,文档的"name"字段的值会被同时复制到"all"字段中。这样一来,如果你想要在文档的所有字段中进行全文本搜索,只需要搜索"all"单个字段即可,而不需要分别搜索每个字段。

         这样对all进行单字段查询,性能也有很大提高。

  1. GET /indexName/_search
  2. {
  3.   "query": {
  4.     "multi_match": {
  5.       "query""搜索内容",
  6.       "fields": ["字段名1"" 字段名2"]
  7.     }
  8.   }
  9. }

Java实现全文查询:

依赖引入可查看我另一张博文第三部分:

  1. //1.准备Request
  2. SearchRequest request = new SearchRequest("hotel");
  3. //2.准备DSL
  4. request.source()
  5. .query(QueryBuilders.matchAllQuery());
  6. //3.发生请求
  7. SearchResponse response = client.search(request, RequestOptions.DEFAULT);

 对SearchResponse返回结果进行处理:

  1. //获取最外层的hits
  2. SearchHits hits = response.getHits();
  3. //获取总条数
  4. TotalHits totalHits = hits.getTotalHits();
  5. //获取里层的hits
  6. SearchHit[] searchHits = hits.getHits();
  7. //遍历每条数据
  8. for (SearchHit hit : searchHits) {
  9. //获取文档 _id
  10. String docId = hit.getId();
  11. //获取每条数据的_source部分(json数据),获取后做下一步处理
  12. String sourceAsString = hit.getSourceAsString();
  13. }

返回数据格式

各种查询主要不同的 是query()中构建的是何种查询,例如这里是match_all查询

构建match查询

QueryBuilders.matchQuery("name","酒店")

精准查询

DSL语句:

  1. GET /jungle_study/_search
  2. {
  3. "query": {
  4. "term": {
  5. "city": {
  6. "value": "北京"
  7. }
  8. }
  9. }
  10. }

构建精确查询

QueryBuilders.termQuery("city","北京")

布尔查询 

复合查询的一种

bool查询中的逻辑关系:

  • must:必须匹配的条件,可以理解为“

  • should:选择性匹配的条件,可以理解为“

  • must_not:必须不匹配的条件,不参与打分

  • filter:必须匹配的条件,不参与打分

DSL:(查询name字段有酒店,并且价格范围在100-500之间的数据)

  1. GET /jungle_study/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "term": {
  8. "city": "北京"
  9. }
  10. },
  11. {
  12. "range": {
  13. "price": {
  14. "gte": 100,
  15. "lte": 500
  16. }
  17. }
  18. }
  19. ]
  20. }
  21. }
  22. }

gte : >=  大于或等于

lte  : <=  小于或等于

gt   : >    大于

lt    : <    小于

构建布尔查询

  1. QueryBuilders.boolQuery();
  2. //添加查询条件
  3. boolQuery.must(QueryBuilders.termQuery("city","上海")); //精确查询,添加city精确匹配条件
  4. boolQuery.filter(QueryBuilders.rangeQuery("price").gte(100).lte(500)); //范围查询 ,添加条件价格在100-250之间

排序、分页查询

DSL:(排序和分页与query同级)

from :从哪条数据开始查

size :查询条数

sort :根据price(价格)倒叙排列查询结果

对应Java代码

  1. // 页码,每页大小
  2. int page = 1, size = 5;
  3. // 准备Request
  4. SearchRequest request = new SearchRequest("jungle_study");
  5. // 准备DSL
  6. request.source().query(QueryBuilders.matchAllQuery());
  7. // 排序 sort
  8. request.source().sort("price", SortOrder.ASC);
  9. // 分页 计算from 和 size
  10. request.source().from((page - 1) * size).size(size);

从DSL可以看出query和sort、from、size是同级,所以也是request.source()去点

高亮

根据搜索关键词对结果做高亮,就是在关键词中添加   <em></em> html标签

 DSL:(也是与query同级)

对查询内容 “酒店” 做高亮,高亮结果是与原数据  _source  同级的  highlight

当我们是使用  all  字段(对所有做过copy_to约束的字段)去做搜索时,需要配置require_field_match属性为false,表示不与查询字段  all  做匹配

 Java代码:

  1. //用request.source()去点,进行配置高亮
  2. request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));

获取高亮结果:

  1. // 根据字段名获取高亮结果
  2. HighlightField highlightField = highlightFields.get("name");
  3. //不为空时才做下一步处理,
  4. if (highlightField != null) {
  5. // 获取高亮值
  6. String name = highlightField.getFragments()[0].string();
  7. //可以覆盖原来的值
  8. }

地理查询

矩形范围查询DSL:

top_left : 左上坐标点    

bottom_right  :右下坐标点

范围查询

查询一个坐标点的五公里范围内的数据

  1. #根据中心点做范围查询
  2. GET /jungle_study/_search
  3. {
  4. "query": {
  5. "geo_distance": {
  6. "distance": "5km",
  7. "location": "31.21,121.5"
  8. }
  9. }
  10. }

"121.5" 是经度(longitude)

"31.21" 是纬度(latitude)

Java中实现:

构建矩形范围查询条件

  1. GeoBoundingBoxQueryBuilder location = QueryBuilders.geoBoundingBoxQuery("location");
  2. //左上坐标点
  3. GeoPoint geoPoint = location.topLeft();
  4. geoPoint.resetLat(31.21);
  5. geoPoint.resetLon(121.5);
  6. //右下坐标点
  7. GeoPoint bottomRight = location.bottomRight();
  8. bottomRight.resetLat(31.21);
  9. bottomRight.resetLon(121.5);

 构建距离范围查询条件

QueryBuilders.geoDistanceQuery("location").distance("5km");

复合查询

常见的有两种 布尔查询 算分函数查询

查询结果中有  _score  代表与搜索词条的关联度打分,结果按照分值降序排列,分越高则排在最前

 ES中使用BM25算法进行词条和文档的相关度做打分。

DSL:

  1. GET /jungle_study/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "term": { "user.id": "kimchy" }
  7. },
  8. "boost": 1.2
  9. }
  10. }
  11. }

 Java实现:

  1. @Test
  2. void testFunctionScore() {
  3. //1.准备Request
  4. SearchRequest request = new SearchRequest("jungle_study");
  5. //构建条件
  6. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  7. boolQuery.must(QueryBuilders.termQuery("city","北京")); //精确匹配
  8. boolQuery.filter(QueryBuilders.rangeQuery("price").gte(100).lte(500)); //范围查询 ,价格在100 - 250
  9. // 2.算分控制
  10. FunctionScoreQueryBuilder functionScoreQuery =
  11. QueryBuilders.functionScoreQuery(
  12. // 原始查询,相关性算分的查询
  13. boolQuery,
  14. // function score的数组
  15. new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
  16. // 其中的一个function score 元素
  17. new FunctionScoreQueryBuilder.FilterFunctionBuilder(
  18. // 过滤条件
  19. QueryBuilders.termQuery("isAD", true),
  20. // 算分函数
  21. ScoreFunctionBuilders.weightFactorFunction(10)
  22. )
  23. });
  24. request.source().query(functionScoreQuery);
  25. }

 代码与DSL对比说明:

 有关复合查询的官方文档地址:Constant score query | Elasticsearch Guide [7.16] | Elastic

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/525565
推荐阅读
相关标签
  

闽ICP备14008679号