elasticsearch搜索引擎的常用方法(二) term和terms,match,range,sort等

1、term和terms

term和terms等查询,不会对查询对字段进行分词处理,适合于date、num、id等确切数据进行搜索

如果需要查询keywords,则查询等keywords必须是查询字段中可以分出来的词,如果不是,则无法查询到数据。

例如:age字段包含的值为80后、90后。使用term查询,{"term":{"age":"80后"}} 这样是无法查询到age是"80后"的数据的,因为term不会对"80后"进行分词,而es中存储的age字段,会把"80后"分成“80”和“后”,没有“80后”,所以使用term无法查询到

term查询某一个关键词的数据:

# 查询content含有“学习”关键词的数据

GET index_1/_search

{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "content": "学习"
        }
      }
    }
  }
}

terms查询某些关键词的数据:

# 查询content中含有“学习”和“生活”的数据

GET index_1/_search

{
  "query": {
    "bool": {
      "filter": {
        "terms": {
          "content": [
            "学习",
            "生活"
          ]
        }
      }
    }
  }
}

 

2、match

match的所有方法,都会对字段进行分词,所查询的字段数据只要包含分词后结果的一个,就会被查询到

例如:age的数据包含有80后、90后,使用 {"match":{"age":"80后"}} 查询,会把所有的数据都查询出来。

分析:match会把“80后”分词为“80”和“后”,而es也会讲age分词为“80“、“后”,“90”、“后”,所有数据都包含”后“,所以会被全部查找出来

match查找age是80后的字段:

GET index_1/_search

{
  "query": {
    "bool": {
      "filter": {
        "match": {
          "age": "80后"
        }
      }
    }
  }
}


结果:
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 6433,
    "max_score": 0,
    "hits": [
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "1",
        "_score": 0,
        "_source": {
          "age": "70后"
          ...}
      },
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "2",
        "_score": 0,
        "_source": {
          "age": "80后"
          ...}
      },
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "2",
        "_score": 0,
        "_source": {
          "age": "90后"
          ...}
      }
    ]
  }
}

match_phrase:短语匹配查询,必须匹配短语中的所有分词,并且保证各个分词的相对位置不变

例如:age的数据包含有80后、90后,使用 {"match_phrase":{"age":"80后"}} 查询,只会把age字段是“80后”的数据查询出来。

分析:match_phrase会把“80后”分词为“80”和“后”,而es也会讲age分词为“80“、“后”,“90”、“后”,查询的时候,只会查询“80”后面的分词是“后”的数据

match_phrase查找age是80后的字段:

GET index_1/_search

{
  "query": {
    "bool": {
      "filter": {
        "match_phrase": {
          "age": "80后"
        }
      }
    }
  }
}


结果:
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 6433,
    "max_score": 0,
    "hits": [
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "1",
        "_score": 0,
        "_source": {
          "age": "80后"
          ...}
      },
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "2",
        "_score": 0,
        "_source": {
          "age": "80后"
          ...}
      },
      {
        "_index": "index_1",
        "_type": "type_1",
        "_id": "2",
        "_score": 0,
        "_source": {
          "age": "80后"
          ...}
      }
    ]
  }
}

multi_match:查询多个字段包含某个关键词的数据

# 查询content或education中含有"大学"的数据

GET index_1/_search

{
  "query": {
    "bool": {
      "filter": {
        "multi_match": {
          "query": "大学",
          "fields": ["content", "education"]
        }
      }
    }
  }
}

match_all:查询所有文档

GET index_1/_search

{
  "query": {
    "match_all": {}
  }
}

 

3、range

range范围查找,查找某一范围的所有数据

gt:大于

gte:大于等于

lt:小于

lte:小于等于

# 查询时间大于等于2019-08-10 10:08:29,小于等于2019-08-13 10:08:29的数据

GET index_4/_search

{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "date": {
            "gte": "2019-08-10 10:08:29", 
            "lte": "2019-08-13 10:08:29"
          }    
        }
      }
    }
  }
}

 

4、sort

sort按照某些字段对数据进行排序,可以是一个字段,也可以是多个字段

desc:降序

asc:生序

# 查询数据按照时间的降序排列

GET index_1/_search

{
  "sort": [
    {
      "date": {
        "order": "desc"
      }
    }
  ], 
  "query": {
    "match_all": {}
  }
}

 

5、_source

对于搜索的结果,只关注某些字段的值

# 查询所有的数据的name和age

GET index_1/_search

{
  "_source": ["name", "age"], 
  "query": {
    "match_all": {}
  }
}

 

6、from和size

from:从某个位置开始查询,最小为0,某些情况下可以为-1(下一篇说明)

size:查询长度

from+size不能大于10000,否则es会报错(下一篇解决)

# 查询前20条数据,并按照date的降序排列

GET index_1/_search

{
  "from": 0,
  "size": 20, 
  "sort": [
    {
      "date": {
        "order": "desc"
      }
    }
  ], 
  "query": {
    "match_all": {}
  }
}

 

7、fuzzy

模糊匹配

value:查询包含某关键字

boost:增加查询的权值,默认值是1.0,必须于value同用,涉及字段_score(es默认按照_score排序)

fuzziness:设置匹配的最小相似度,默认值0.5,对于字符串,取值0-1(包括0和1);对于数值,取值可能大于1;对于日期取值为1d,1m等

prefix_length:公共前缀长度,默认为0

max_expansions:指定可被扩大到的最大词条数,默认为无限制

GET index_4/_search

{
  "query": {
   "fuzzy": {
     "type": {
       "value": "分期", 
       "boost": 0.5
     }
   }
  }
}

 

8、wildcard

通配符查询

*:匹配0或多个字符

?:匹配任意字符

注意:使用wildcard的字段类型需要是keyword,切不分词;尽量少用,效率较低

GET index_1/_search

{
  "query": {
    "wildcard": {
      "content": {
        "value": "*学习*"
      }
    }
  }
}

 

9、仅列出一些es常用的方法,持续更新中。。。

<think>好的,我现在需要回答用户关于Elasticsearch Java API中查询关键字、组合查询、分页、排序高亮的问题。首先,我得确认用户需要的是Java API的具体应用,而不仅仅是概念。用户提到的关键词包括matchtermrangeterms,组合查询的must、should、must_not、filter,还有分页、排序高亮。 首先,我应该回顾一下这些查询类型在Elasticsearch中的基本用法,然后对应到Java API的实现方式。比如,match查询对应的是全文检索,而term是精确匹配。需要区分它们的使用场景API构建方法。 接下来是组合查询,用户提到了must、should、must_notfilter。这些属于布尔查询的部分,Java API中会用到BoolQueryBuilder。需要说明如何组合这些子查询,并注意filter不参与相关性评分的特点。 分页方面,用户可能想知道如何设置fromsize参数。在Java API中,这应该是在SearchSourceBuilder里设置。排序的话,需要用到SortBuilder,比如fieldSort来指定字段顺序。 高亮部分,需要配置HighlightBuilder,指定字段样式。比如添加highlight字段,设置preTagspostTags。 然后,我需要考虑用户可能的实际应用场景,比如如何将这些查询组合在一起,构建一个完整的搜索请求。可能需要给出一个完整的代码示例,但要注意结构清晰,分步骤解释。 同时,要确保代码符合当前常用Elasticsearch Java客户端版本,比如是否使用的是RestHighLevelClient还是新的Java API Client。假设用户使用的是较新的版本,但可能需要说明不同版本之间的差异,不过用户没有指定,所以可能默认使用常见的RestHighLevelClient的写法。 还要注意异常处理API的正确使用方式,比如如何执行查询,处理响应结果。但用户可能更关注查询的构建部分,所以示例代码可以重点展示构建过程,省略一些繁琐的细节。 需要检查术语是否正确,比如terms查询用于多值精确匹配,range用于范围查询。组合查询中的filter上下文是否真的不计算分数,这点很重要,会影响性能。 可能还需要提到分页的深度分页问题,即from + size的限制,以及推荐使用search_after的方法,但用户问的是基础分页,所以先解释基本的fromsize。 排序部分要注意多字段排序的情况,以及是否可以使用脚本排序,但用户可能只需要基础示例。 高亮方面,要说明如何定义高亮标签,可能自定义前后标签,比如<em>标签,以及如何处理高亮结果的提取。 最后,整合所有部分到一个示例中,展示一个完整的搜索请求构建过程,包括查询、分页、排序高亮。确保代码正确,语法无误,并且有必要的注释说明每个步骤的作用。 可能还需要提醒用户注意依赖的导入,比如Elasticsearch客户端的依赖配置,以及正确处理响应中的高亮字段结果解析。 总结一下,回答的结构应该是先分点介绍每个查询类型功能,然后给出相应的Java API代码片段,最后整合成一个完整的示例,帮助用户理解如何在实际项目中应用这些功能。</think>以下是Elasticsearch Java API核心功能的详细说明及代码示例: 1. **查询关键字** ```java // Match查询(全文检索) MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", "elasticsearch"); // Term查询(精确匹配) TermQueryBuilder termQuery = QueryBuilders.termQuery("status", 1); // Range查询(范围查询RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price") .gte(100).lte(500); // Terms查询(多值精确匹配) TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("tags", "java", "search"); ``` 2. **组合查询(BoolQuery)** ```java BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery("content", "分布式")) // AND条件 .should(QueryBuilders.termQuery("category", "技术")) // OR条件 .mustNot(QueryBuilders.termQuery("isDeleted", true)) // NOT条件 .filter(QueryBuilders.rangeQuery("publish_date").gte("2023-01-01")); // 过滤条件(不参与评分) ``` 3. **分页与排序** ```java SearchSourceBuilder sourceBuilder = new SearchSourceBuilder() .from(0) // 起始位置 .size(10) // 每页数量 .sort(new FieldSortBuilder("price").order(SortOrder.ASC)) // 价格升序 .sort(SortBuilders.scoreSort().order(SortOrder.DESC)); // 相关性评分降序 ``` 4. **高亮显示** ```java HighlightBuilder highlightBuilder = new HighlightBuilder() .field("content") // 设置高亮字段 .preTags(""<em>) // 高亮前缀 .postTags("</em>") // 高亮后缀 .highlighterType("unified"); // 高亮类型 sourceBuilder.highlighter(highlightBuilder); ``` **完整示例代码**: ```java SearchRequest searchRequest = new SearchRequest("articles"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 构建组合查询 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery("content", "分布式")) .filter(QueryBuilders.rangeQuery("publish_date").gte("2023-01-01")); // 设置分页排序 sourceBuilder.query(boolQuery) .from(0) .size(10) .sort("publish_date", SortOrder.DESC); // 配置高亮 HighlightBuilder highlightBuilder = new HighlightBuilder() .field("content") .preTags("<strong>") .postTags("</strong>"); sourceBuilder.highlighter(highlightBuilder); // 执行查询 searchRequest.source(sourceBuilder); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); // 处理结果 for (SearchHit hit : response.getHits()) { // 获取高亮内容 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); if (highlightFields.containsKey("content")) { Text[] fragments = highlightFields.get("content").fragments(); String highlightedContent = fragments[0].string(); } } ``` **关键注意事项**: 1. 版本兼容性:示例基于Elasticsearch 7.x的Java High Level REST Client 2. 分页限制:深度分页避免使用from+size(最大10000),推荐search_after 3. 性能优化:filter上下文适合频繁使用的过滤条件(缓存机制) 4. 高亮策略:根据需要选择不同的highlighterType(unified/plain/fvh) 5. 结果处理:注意处理分片失败(response.getFailedShards()) 建议结合Spring Data Elasticsearch等封装库使用,可简化API操作。对于新项目,推荐使用官方新的Java API Client(elasticsearch-java)。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉宸尘⁴⁰⁴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值