Elasticsearch Search API之(Request Body Search 查询主体)-下篇

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch Search API之(Request Body Search 查询主体)-下篇

image.png

查询选择副本分片的倾向性(即在一个复制组中选择副本的分片值。默认情况下,es以未指定的顺序从可用的碎片副本中进行选择,副本之间的路由将在集群章节更加详细的介绍 。可以通过该字段指定分片倾向与选择哪个副本。preference可选值:


  • _primary
    只在节点上执行,在6.1.0版本后废弃,将在7.x版本移除。

  • _primary_first
    优先在主节点上执行。在6.1.0版本后废弃,将在7.x版本移除。

  • _replica
    操作只在副本分片上执行,如果有多个副本,其顺序随机。在6.1.0版本后废弃,将在7.x版本移除。

  • _replica_first
    优先在副本分片上执行,如果有多个副本,其顺序随机。在6.1.0版本后废弃,将在7.x版本移除。

  • _only_local
    操作将只在分配给本地节点的分片上执行。_only_local选项保证只在本地节点上使用碎片副本,这对于故障排除有时很有用。所有其他选项不能完全保证在搜索中使用任何特定的碎片副本,而且在索引更改时,这可能意味着如果在处于不同刷新状态的不同碎片副本上执行重复搜索,则可能产生不同的结果。

  • _local
    优先在本地分片上执行。

  • _prefer_nodes:abc,xyz
    优先在指定节点ID的分片上执行,示例中的节点ID为abc、xyz。

  • _shards:2,3
    将操作限制到指定的分片上执行。(这里是2和3)这个首选项可以与其他首选项组合,但必须首先出现_-shards:2,3|_local。

  • _only_nodes:abc,xyz,…
    根据节点ID进行限制。

  • Custom (string) value
    自定义字符串,其路由为 hashcod-e(该值)%赋值组内节点数。例如在web应用中通常以sessionId为倾向值。

image.png

是否解释各分数是如何计算的。

1GET /_search
2{
3    "explain": true,
4    "query" : {
5        "term" : { "user" : "kimchy" }
6    }
7}

image.png

如果设置为true,则返回每个命中文档的当前版本号。

1GET /_search
2{
3    "version": true,
4    "query" : {
5        "term" : { "user" : "kimchy" }
6    }
7}

image.png

当搜索多个索引时,允许为每个索引配置不同的boost级别。当来自一个索引的点击率比来自另一个索引的点击率更重要时,该属性则非常方便。

使用示例如下:

1GET /_search
2{
3    "indices_boost" : [
4        { "alias1" : 1.4 },
5        { "index*" : 1.3 }
6    ]
7}

image.png

指定返回文档的最小评分,如果文档的评分低于该值,则不返回。

1GET /_search
2{
3    "min_score": 0.5,
4    "query" : {
5        "term" : { "user" : "kimchy" }
6    }
7}

image.png

每个过滤器和查询都可以在其顶级定义中接受_name。搜索响应中每个匹配文档中会增加matched_queries结构体,记录该文档匹配的查询名称。查询和筛选器的标记只对bool查询有意义。


java示例如下:

1public static void testNamesQuery() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            SearchRequest searchRequest = new SearchRequest();
 5            searchRequest.indices("esdemo");
 6            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 7            sourceBuilder.query(
 8                    QueryBuilders.boolQuery()
 9                        .should(QueryBuilders.termQuery("context", "fox").queryName("q1"))
10                        .should(QueryBuilders.termQuery("context", "brown").queryName("q2"))
11                    );
12            searchRequest.source(sourceBuilder);
13            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
14            System.out.println(result);
15        } catch (Throwable e) {
16            e.printStackTrace();
17        } finally {
18            EsClient.close(client);
19        }
20    }

返回结果如下:

 1{
10    "hits":{
19                "_source":{
20                    "context":"My quick brown as fox eats rabbits on a regular basis.",
21                    "title":"Keeping pets healthy"
22                },
23                "matched_queries":[
24                    "q1",
25                    "q2"
26                ]
27            }
41        ]
42    }
43}

正如上面所说,每个匹配文档中都包含matched_queries,表明该文档匹配的是哪个查询条件。

image.png

用于定义内部嵌套层的返回规则,其inner hits支持如下选项:


  • from 用于内部匹配的分页。
  • size 用于内部匹配的分页,size。
  • sort 排序策略。
  • name 为内部嵌套层定义的名称。
    该部分示例将在下节重点阐述。

image.png

允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。有点类似于聚合分组,其效果类似于按字段进行分组,默认命中的文档列表第一层由该字段的第一条信息,也可以通过允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。例如下面的查询为每个用户检索最佳twee-t,并按喜欢的数量对它们进行排序。

下面首先通过示例进行展示field colla-psing的使用。


1)首先查询发的推特内容中包含elast-icsearch的推文:

1GET /twitter/_search
 2{
 3    "query": {
 4        "match": {
 5            "message": "elasticsearch"
 6        }
 7    },
 8    "collapse" : {
 9        "field" : "user" 
10    },
11    "sort": ["likes"]
12}

返回结果:

1{
13        "hits":[
14            {
15                "_index":"mapping_field_collapsing_twitter",
16                "_type":"_doc",
17                "_id":"OYnecmcB-IBeb8B-bF2X",
18                "_score":null,
19                "_source":{
20                    "message":"to be a elasticsearch",
21                    "user":"user2",
22                    "likes":3
23                },
24                "sort":[
25                    3
26                ]
27            },
84        ]
85    }
86}

首先上述会列出所有用户的推特,如果只想每个用户只显示一条推文,并且点赞率最高,或者每个用户只显示2条推文呢?这个时候,按字段折叠就闪亮登场了。java demo如下:

1public static void search_field_collapsing() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            SearchRequest searchRequest = new SearchRequest();
 5            searchRequest.indices("mapping_field_collapsing_twitter");
 6            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 7            sourceBuilder.query(
 8                    QueryBuilders.matchQuery("message","elasticsearch")
 9            );
10            sourceBuilder.sort("likes", SortOrder.DESC);
11            CollapseBuilder collapseBuilder = new CollapseBuilder("user");
12            sourceBuilder.collapse(collapseBuilder);
13            searchRequest.source(sourceBuilder);
14            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
15            System.out.println(result);
16        } catch (Throwable e) {
17            e.printStackTrace();
18        } finally {
19            EsClient.close(client);
20        }
21    }

其结果如下:

 1{
10    "hits":{
11  
13        "hits":[
14            {
15                "_index":"mapping_field_collapsing_twitter",
16                "_type":"_doc",
17                "_id":"OYnecmcB-IBeb8B-bF2X",
18                "_score":null,
19                "_source":{
20                    "message":"to be a elasticsearch",
21                    "user":"user2",
22                    "likes":3
23                },
24                "fields":{
25                    "user":[
26                        "user2"
27                    ]
28                },
29                "sort":[
30                    3
31                ]
32            },
33            {
34                "_index":"mapping_field_collapsing_twitter",
35                "_type":"_doc",
36                "_id":"OInecmcB-IBeb8B-bF2G",
37                "_score":null,
38                "_source":{
39                    "message":"elasticsearch is very high",
40                    "user":"user1",
41                    "likes":3
42                },
43                "fields":{
44                    "user":[
45                        "user1"
46                    ]
47                },
48                "sort":[
49                    3
50                ]
51            }
52        ]
53    }
54}

上面的示例只返回了每个用户的第一条数据,如果需要每个用户返回2条数据呢?可以通过inner_hit来设置。

1public static void search_field_collapsing() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            SearchRequest searchRequest = new SearchRequest();
 5            searchRequest.indices("mapping_field_collapsing_twitter");
 6            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 7            sourceBuilder.query(
 8                    QueryBuilders.matchQuery("message","elasticsearch")
 9            );
10            sourceBuilder.sort("likes", SortOrder.DESC);
11            CollapseBuilder collapseBuilder = new CollapseBuilder("user");
12
13            InnerHitBuilder collapseHitBuilder = new InnerHitBuilder("collapse_inner_hit");
14            collapseHitBuilder.setSize(2);
15            collapseBuilder.setInnerHits(collapseHitBuilder);
16            sourceBuilder.collapse(collapseBuilder);
17
18            searchRequest.source(sourceBuilder);
19            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
20            System.out.println(result);
21        } catch (Throwable e) {
22            e.printStackTrace();
23        } finally {
24            EsClient.close(client);
25        }
26    }

返回结果如下:

1{
  2    "took":42,
  3    "timed_out":false,
  4    "_shards":{
  5        "total":5,
  6        "successful":5,
  7        "skipped":0,
  8        "failed":0
  9    },
 10    "hits":{
 11        "total":5,
 12        "max_score":null,
 13        "hits":[
 14            {
 15                "_index":"mapping_field_collapsing_twitter",
 16                "_type":"_doc",
 17                "_id":"OYnecmcB-IBeb8B-bF2X",
 18                "_score":null,
 19                "_source":{
 20                    "message":"to be a elasticsearch",
 21                    "user":"user2",
 22                    "likes":3
 23                },
 24                "fields":{
 25                    "user":[
 26                        "user2"
 27                    ]
 28                },
 29                "sort":[
 30                    3
 31                ],
 32                "inner_hits":{
 33                    "collapse_inner_hit":{
 34                        "hits":{
 35                            "total":2,
 36                            "max_score":0.19363807,
 37                            "hits":[
 38                                {
 39                                    "_index":"mapping_field_collapsing_twitter",
 40                                    "_type":"_doc",
 41                                    "_id":"OonecmcB-IBeb8B-bF2q",
 42                                    "_score":0.19363807,
 43                                    "_source":{
 44                                        "message":"to be elasticsearch",
 45                                        "user":"user2",
 46                                        "likes":3
 47                                    }
 48                                },
 49                                {
 50                                    "_index":"mapping_field_collapsing_twitter",
 51                                    "_type":"_doc",
 52                                    "_id":"OYnecmcB-IBeb8B-bF2X",
 53                                    "_score":0.17225473,
 54                                    "_source":{
 55                                        "message":"to be a elasticsearch",
 56                                        "user":"user2",
 57                                        "likes":3
 58                                    }
 59                                }
 60                            ]
 61                        }
 62                    }
 63                }
 64            },
 65            {
 66                "_index":"mapping_field_collapsing_twitter",
 67                "_type":"_doc",
 68                "_id":"OInecmcB-IBeb8B-bF2G",
 69                "_score":null,
 70                "_source":{
 71                    "message":"elasticsearch is very high",
 72                    "user":"user1",
 73                    "likes":3
 74                },
 75                "fields":{
 76                    "user":[
 77                        "user1"
 78                    ]
 79                },
 80                "sort":[
 81                    3
 82                ],
 83                "inner_hits":{
 84                    "collapse_inner_hit":{
 85                        "hits":{
 86                            "total":3,
 87                            "max_score":0.2876821,
 88                            "hits":[
 89                                {
 90                                    "_index":"mapping_field_collapsing_twitter",
 91                                    "_type":"_doc",
 92                                    "_id":"O4njcmcB-IBeb8B-Rl2H",
 93                                    "_score":0.2876821,
 94                                    "_source":{
 95                                        "message":"elasticsearch is high db",
 96                                        "user":"user1",
 97                                        "likes":1
 98                                    }
 99                                },
100                                {
101                                    "_index":"mapping_field_collapsing_twitter",
102                                    "_type":"_doc",
103                                    "_id":"N4necmcB-IBeb8B-bF0n",
104                                    "_score":0.2876821,
105                                    "_source":{
106                                        "message":"very likes elasticsearch",
107                                        "user":"user1",
108                                        "likes":1
109                                    }
110                                }
111                            ]
112                        }
113                    }
114                }
115            }
116        ]
117    }
118}

此时,返回结果是两级,第一级,还是每个用户第一条消息,然后再内部中嵌套inner_hits。

image.png

Elasticsearch支持的第三种分页获取方式,该方法不支持跳转页面。


es支持的分页方式目前已知:


  1. 通过from和size,当时当达到深度分页时,成本变的非常高昂,故es提供了索引参数:index.max_result_window来控制(from + size)的最大值,默认为10000,超过该值后将报错。
  2. 通过scroll滚动API,该方式类似于快照的工作方式,不具备实时性,并且滚动上下文的存储需要耗费一定的性能。
    本节将介绍第3种分页方式,search after,基于上一页查询的结果进行下一页数据的查询。基本思想是选择一组排序字段,能做到全局唯一。es的排序查询响应结果中会返回sort数组,包含本排序字段的最大值,下一页查询将该组字段当成查询条件,es在此数据的基础下返回下一批合适的数据。


java示例如下:

 1public static void search_search_after() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            SearchRequest searchRequest = new SearchRequest();
 5            searchRequest.indices("mapping_search_after");
 6            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 7            sourceBuilder.query(
 8                    QueryBuilders.termQuery("user","user2")
 9            );
10            sourceBuilder.size(1);
11            sourceBuilder.sort("id", SortOrder.ASC);
12            searchRequest.source(sourceBuilder);
13            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
14            System.out.println(result);
15            if(hasHit(result)) { // 如果本次匹配到数据
16                // 省略处理数据逻辑
17                // 继续下一批查询
18                // result.getHits().
19                int length = result.getHits().getHits().length;
20                SearchHit aLastHit = result.getHits().getHits()[length - 1];
21                //开始下一轮查询
22                sourceBuilder.searchAfter(aLastHit.getSortValues());
23                result = client.search(searchRequest, RequestOptions.DEFAULT);
24                System.out.println(result);
25            }
26        } catch (Throwable e) {
27            e.printStackTrace();
28        } finally {
29            EsClient.close(client);
30        }
31    }
32    private static boolean hasHit(SearchResponse result) {
33        return !( result.getHits() == null ||
34                result.getHits().getHits() == null ||
35                result.getHits().getHits().length < 1 );
36    }


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
13天前
|
安全 API 持续交付
要利用阿里云控制API查询您的阿里云资源
【2月更文挑战第33天】要利用阿里云控制API查询您的阿里云资源
40 3
|
13天前
|
缓存 API 定位技术
使用Python调用百度地图API实现地址查询
使用Python调用百度地图API实现地址查询
145 0
|
13天前
|
存储 自然语言处理 搜索推荐
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
28 0
|
13天前
|
存储 数据可视化 数据建模
阿里云大佬叮嘱我务必要科普这个 Elasticsearch API
阿里云大佬叮嘱我务必要科普这个 Elasticsearch API
25 0
|
13天前
|
存储 缓存 运维
DataWorks操作报错合集之DataWorks根据api,调用查询文件列表接口报错如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
13天前
|
缓存 前端开发 JavaScript
【专栏】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角
【4月更文挑战第27天】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角。它提供强类型系统、灵活查询和实时更新,改善数据获取效率和开发体验。掌握GraphQL涉及学习基础概念、搭建开发环境和实践应用。结合前端框架,利用缓存和批量请求优化性能,与后端协作设计高效API。尽管有挑战,但GraphQL为前端开发开辟新道路,引领未来趋势。一起探索GraphQL,解锁前端无限可能!
|
13天前
|
API 数据库
工作流JBPM操作API启动实例&查询任务
工作流JBPM操作API启动实例&查询任务
18 0
|
13天前
|
存储 监控 大数据
【Elasticsearch专栏 15】深入探索:Elasticsearch使用API删除旧数据
本文探讨了如何使用Elasticsearch API管理并删除旧数据。Elasticsearch提供RESTful API,支持按条件批量删除。删除策略可基于时间、文档数量或索引。通过`DELETE BY QUERY` API,可以根据时间戳范围删除数据,如删除早于30天的记录。为处理大量数据,建议分批次进行,使用`scroll`和`size`参数控制。监控删除进度可使用任务ID。合理运用这些方法能有效优化存储,适应不同业务需求。
33 0
|
13天前
|
Java Maven 开发工具
【ElasticSearch 】IK 分词器安装
【ElasticSearch 】IK 分词器安装
28 1
|
13天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用

热门文章

最新文章