标签:lap after 命令 eal 嵌套 regular prim mamicode sea
preference查询选择副本分片的倾向性(即在一个复制组中选择副本的分片值。默认情况下,es以未指定的顺序从可用的碎片副本中进行选择,副本之间的路由将在集群章节更加详细的介绍 。可以通过该字段指定分片倾向与选择哪个副本。preference可选值:
是否解释各分数是如何计算的。
1GET /_search
2{
3 "explain": true,
4 "query" : {
5 "term" : { "user" : "kimchy" }
6 }
7}
如果设置为true,则返回每个命中文档的当前版本号。
1GET /_search
2{
3 "version": true,
4 "query" : {
5 "term" : { "user" : "kimchy" }
6 }
7}
当搜索多个索引时,允许为每个索引配置不同的boost级别。当来自一个索引的点击率比来自另一个索引的点击率更重要时,该属性则非常方便。
使用示例如下:
1GET /_search
2{
3 "indices_boost" : [
4 { "alias1" : 1.4 },
5 { "index*" : 1.3 }
6 ]
7}
指定返回文档的最小评分,如果文档的评分低于该值,则不返回。
1GET /_search
2{
3 "min_score": 0.5,
4 "query" : {
5 "term" : { "user" : "kimchy" }
6 }
7}
每个过滤器和查询都可以在其顶级定义中接受_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,表明该文档匹配的是哪个查询条件。
用于定义内部嵌套层的返回规则,其inner hits支持如下选项:
允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。有点类似于聚合分组,其效果类似于按字段进行分组,默认命中的文档列表第一层由该字段的第一条信息,也可以通过允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。例如下面的查询为每个用户检索最佳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。
Elasticsearch支持的第三种分页获取方式,该方法不支持跳转页面。
es支持的分页方式目前已知:
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 }
更多文章请关注微信公众号:
广告:作者新书《RocketMQ技术内幕》已上市
《RocketMQ技术内幕》已出版上市,目前可在主流购物平台(京东、天猫等)购买,本书从源码角度深度分析了RocketMQ NameServer、消息发送、消息存储、消息消费、消息过滤、主从同步HA、事务消息;在实战篇重点介绍了RocketMQ运维管理界面与当前支持的39个运维命令;并在附录部分罗列了RocketMQ几乎所有的配置参数。本书得到了RocketMQ创始人、阿里巴巴Messaging开源技术负责人、Linux OpenMessaging 主席的高度认可并作序推荐。目前是国内第一本成体系剖析RocketMQ的书籍。
Elasticsearch Search API之(Request Body Search 查询主体
标签:lap after 命令 eal 嵌套 regular prim mamicode sea
原文地址:https://blog.51cto.com/15023237/2559368