ES常见搜索字段介绍,hits,took,timeout

本文介绍ES搜索结果中各字段。空搜索是搜索API最基础形式,返回集群所有索引下的文档。hits包含匹配文档总数及前十个文档;took表示搜索耗时;shard显示参与分片总数及成败情况;timeout告知查询是否超时,默认不超时,可指定超时时间。

ES搜索结果中各个字段介绍

转自 https://blog.youkuaiyun.com/qq_36868951/article/details/108127909

空搜索

搜索API的最基础的形式是没有指定任何查询的空搜索,它简单地返回集群中所有索引下的所有文档:

GET /_search

返回的结果(为了界面简洁编辑过的)像这样:

{
   "hits" : {
      "total" :       14,
      "hits" : [
        {
          "_index":   "us",
          "_type":    "tweet",
          "_id":      "7",
          "_score":   1,
          "_source": {
             "date":    "2014-09-17",
             "name":    "John Smith",
             "tweet":   "The Query DSL is really powerful and flexible",
             "user_id": 2
          }
       },
        ... 9 RESULTS REMOVED ...
      ],
      "max_score" :   1
   },
   "took" :           4,
   "_shards" : {
      "failed" :      0,
      "successful" :  10,
      "total" :       10
   },
   "timed_out" :      false
}

hits

返回结果中最重要的部分是hits,它包含total字段来表示匹配到的文档总数,并且一个hits数组包含所查询结果的前十个文档。所以hits其实就是你想查询的内容。可以在查询语句中添加size,获得更多的hits。

在 hits 数组中每个结果包含文档的 _index_type_id,加上_source字段。这意味着我们可以直接从返回的搜索结果中使用整个文档。这不像其他的搜索引擎,仅仅返回文档的ID,需要你单独去获取文档。

每个结果还有一个 _score,它衡量了文档与查询的匹配程度。默认情况下,首先返回最相关的文档结果,就是说,返回的文档是按照 _score 降序排列的。在这个例子中,我们没有指定任何查询,故所有的文档具有相同的相关性,因此对所有的结果而言 1 是中性的_score

max_score值是与查询所匹配文档的_score的最大值。

took

took 值告诉我们执行整个搜索请求耗费了多少毫秒。

shard

_shards部分告诉我们在查询中参与分片的总数,以及这些分片成功了多少个失败了多少个。正常情况下我们不希望分片失败,但是分片失败是可能发生的。如果我们遭遇到一种灾难级别的故障,在这个故障中丢失了相同分片的原始数据和副本,那么对这个分片将没有可用副本来对搜索请求作出响应。假若这样,Elasticsearch 将报告这个分片是失败的,但是会继续返回剩余分片的结果。

timeout

timed_out值告诉我们查询是否超时。默认情况下,搜索请求不会超时。如果低响应时间比完成结果更重要,你可以指定 timeout 为 10 或者 10ms(10毫秒),或者 1s(1秒):

GET /_search?timeout=10ms

在请求超时之前,Elasticsearch 将会返回已经成功从每个分片获取的结果。

应当注意的是 timeout 不是停止执行查询,它仅仅是告知正在协调的节点返回到目前为止收集的结果并且关闭连接。在后台,其他的分片可能仍在执行查询即使是结果已经被发送了。

使用超时是因为 SLA(服务等级协议)对你是很重要的,而不是因为想去中止长时间运行的查询。

`SearchRequest` 是 Elasticsearch Java High Level Client 中用于构建和执行搜索请求的核心类。它允许你向 Elasticsearch 发送复杂的查询请求,支持分页、排序、高亮、聚合等多种功能。 --- ### 一、基本结构 一个 `SearchRequest` 需要指定: - 索引名(可以是多个) - 搜索源构造器 `SearchSourceBuilder`:定义查询条件、分页、排序等 - 可选的 `RequestOptions`(通常使用默认) --- ### 二、完整使用示例 ```java import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.sort.SortOrder; public void executeSearch(RestHighLevelClient client, String index) throws Exception { // 1. 创建 SearchRequest,指定索引 SearchRequest searchRequest = new SearchRequest(index); // 或传入多个索引: "index1", "index2" // 2. 构建查询内容 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 示例:match_all 查询 sourceBuilder.query(QueryBuilders.matchAllQuery()); // 可选:设置分页(from=起始位置,size=返回数量) sourceBuilder.from(0); sourceBuilder.size(10); // 可选:是否超时内强制返回(不影响结果准确性) sourceBuilder.timeout(TimeValue.timeValueSeconds(60)); // 可选:排序 sourceBuilder.sort("age", SortOrder.DESC); // 将 sourceBuilder 添加到 request searchRequest.source(sourceBuilder); // 3. 执行请求 SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); // 4. 处理响应 System.out.println("Total hits: " + response.getHits().getTotalHits().value); System.out.println("Took: " + response.getTook().getMillis() + "ms"); // 遍历结果 for (SearchHit hit : response.getHits().getHits()) { System.out.println("ID: " + hit.getId()); System.out.println("Source: " + hit.getSourceAsString()); // 如果存储了 _source 字段,则可用 getSourceAsMap() } } ``` --- ### 三、常见查询类型(搭配 QueryBuilders) | 查询方式 | 示例代码 | |--------|---------| | **Match All** | `QueryBuilders.matchAllQuery()` | | **Term Query(精确匹配)** | `QueryBuilders.termQuery("name.keyword", "Alice")` | | **Match Query(全文检索)** | `QueryBuilders.matchQuery("content", "java elasticsearch")` | | **Multi-match** | `QueryBuilders.multiMatchQuery("search text", "title", "description")` | | **Range Query** | `QueryBuilders.rangeQuery("age").gte(18).lte(65)` | | **Bool Query(组合查询)** | 见下方示例 | #### Bool 查询示例(AND / OR / NOT) ```java sourceBuilder.query( QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery("status", "active")) // 必须满足 .mustNot(QueryBuilders.termQuery("deleted", true)) // 不能满足 .should(QueryBuilders.termQuery("priority", "high")) // 建议满足(影响评分) .should(QueryBuilders.termQuery("priority", "medium")) .filter(QueryBuilders.rangeQuery("createdDate").gte("2023-01-01")) // 过滤,不影响评分 ); ``` --- ### 四、高级功能 #### 1. 字段过滤(只返回某些字段) ```java sourceBuilder.fetchSource(new String[]{"name", "email"}, new String[]{}); // 包含字段,排除字段 ``` #### 2. 高亮显示 ```java HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("content"); // 对 content 字段高亮 highlightBuilder.preTags("").postTags(""); sourceBuilder.highlighter(highlightBuilder); ``` 响应中通过 `hit.getHighlightFields()` 获取高亮片段。 #### 3. 聚合分析(Aggregations) ```java sourceBuilder.aggregation( AggregationBuilders.terms("by_status").field("status.keyword").size(10) ); sourceBuilder.aggregation( AggregationBuilders.avg("avg_age").field("age") ); ``` 响应中通过 `response.getAggregations().get("by_status")` 提取聚合结果。 #### 4. 分页与滚动(Scroll)适用于大数据集 > 注意:`RestHighLevelClient` 不推荐用 `from+size` 深度分页(性能差),应使用 Scroll 或 Search After。 简单 scroll 示例: ```java sourceBuilder.size(100); searchRequest.source(sourceBuilder); searchRequest.scroll(TimeValue.timeValueMinutes(1L)); String scrollId = null; SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); scrollId = response.getScrollId(); // 后续使用 SearchScrollRequest 继续拉取 ``` --- ### 五、异常处理 ```java try { SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); } catch (IOException e) { throw new RuntimeException("Elasticsearch 查询失败", e); } catch (Exception e) { System.err.println("查询异常: " + e.getMessage()); } ``` 常见异常包括网络中断、索引不存在、查询语法错误等。 --- ### 六、注意事项 | 项目 | 说明 | |------|------| | 性能优化 | 避免 deep pagination,尽量使用 `search_after` 或 `scroll` | | 字段类型 | keyword 用于精确匹配,text 用于全文检索,注意区分 | | JSON 解析 | 响应中的 `_source` 是 Map 或 String,需根据情况反序列化为对象 | | 线程安全 | `SearchRequest` 实例不是线程安全的,每次查询应新建 | | 版本兼容性 | 使用与 ES 服务端一致的客户端版本,避免解析失败 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值