摘要:实现 ES 结果最大匹配数修改、筛选并嵌套聚类,比较多种模式检索的差异。
结果最大匹配数修改 官方文档说明
默认情况下,elasticsearch 搜索请求将准确地计算总点击数,最多 10,000 个文档。如果与查询匹配的总点击数大于此值,则响应将指示返回的值是一个下限,例如"gte"
:
不修改track_total_hits
的结果:
1 2 3 4 5 6 7 8 9 10 GET /kibana_sample_data_logs/_search -------- "hits" : { "total" : { "value" : 10000 , "relation" : "gte" } }
修改track_total_hits
后的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 GET /kibana_sample_data_logs/_search { "track_total_hits" : true } -------- "hits" : { "total" : { "value" : 14074 , "relation" : "eq" }}
此外设置index.max_result_window
上限:
1 2 3 4 PUT _all/_settings { "index.max_result_window" :"200000" }
筛选并嵌套聚类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 GET /kibana_sample_data_flights/_search?size=0 { "query" : { "bool" : { "must" : [ { "query_string" : { "default_field" : "DestCountry" , "query" : "AU OR CN OR US" } } ] } },"aggs" : { "按照国家聚类" : { "terms" : { "field" : "DestCountry" , "size" : 10 },"aggs" : { "按照城市聚类" : { "terms" : { "field" : "DestCityName" , "size" : 100 } } } } } }
查询结果(部分):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 { "key" : "CN" , "doc_count" : 1096 , "按照城市聚类" : { "doc_count_error_upper_bound" : 0 , "sum_other_doc_count" : 0 , "buckets" : [ { "key" : "Xi'an" , "doc_count" : 526 }, { "key" : "Shanghai" , "doc_count" : 479 }, { "key" : "Guangzhou" , "doc_count" : 48 }, { "key" : "Chengdu" , "doc_count" : 29 }, { "key" : "Beijing" , "doc_count" : 14 } ] } }
几种检索模式的特性 检索全部文档 1 GET /kibana_sample_data_ecommerce/_search?size=100 &_source=category
查询结果(总数):
1 2 3 4 "total" : { "value" : 4675 , "relation" : "eq" }
match
模糊匹配,需要指定字段名,但是输入会进行分词,比如”hello world”会进行拆分为 hello 和 world,然后匹配,如果字段中包含 hello 或者 world,或者都包含的结果都会被查询出来,也就是说 match 是一个部分匹配的模糊查询。查询条件相对来说比较宽松。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 GET /kibana_sample_data_ecommerce/_search?size=4000 &_source=category { "query" : { "bool" : { "must" : [ { "match" : { "category" : "Men's Clothing" } } ] } } }
查询结果(多于实际数量):
1 2 3 4 "total" : { "value" : 4213 , "relation" : "eq" }
term
这种查询和 match 在有些时候是等价的,比如我们查询单个的词 hello,那么会和 match 查询结果一样,但是如果查询”hello world”,结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有”hello world”的字样,而不是查询字段中包含”hello world”的字样,elasticsearch 会对字段内容进行分词,”hello world”会被分成 hello 和 world,不存在”hello world”,因此这里的查询结果会为空。这也是 term 查询和 match 的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 GET /kibana_sample_data_ecommerce/_search?size=100 &_source=category { "query" : { "bool" : { "must" : [ { "term" : { "category" : { "value" : "Men's Clothing" } } } ] } } }
查询结果(查不到):
1 2 3 4 "total" : { "value" : 0 , "relation" : "eq" }
match_phrase
会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以”hello world”为例,要求结果中必须包含 hello 和 world,而且还要求他们是连着的,顺序也是固定的,hello that word 不满足,world hello 也不满足条件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 GET /kibana_sample_data_ecommerce/_search?size=4000 &_source=category { "query" : { "bool" : { "must" : [ { "match_phrase" : { "category" : "Men's Clothing" } } ] } } }
查询结果(等于实际数量):
1 2 3 4 "total" : { "value" : 2024 , "relation" : "eq" }
query_string
和 match 类似,但是 match 需要指定字段名,query_string 是在所有字段中搜索,范围更广泛。
对检索的关键词不加双引号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 GET /kibana_sample_data_ecommerce/_search?size=4000 &_source=category { "query" : { "bool" : { "must" : [ { "query_string" : { "default_field" : "category" , "query" : "Men's Clothing" } } ] } } }
查询结果(多于实际数量):
1 2 3 4 5 "total" : { "value" : 4213 , "relation" : "eq" }
对检索的结果加上转义后的双引号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 GET /kibana_sample_data_ecommerce/_search?size=4000 &_source=category { "query" : { "bool" : { "must" : [ { "query_string" : { "default_field" : "category" , "query" : "\"Men's Clothing\"" } } ] } } }
查询结果(等于实际数量):
1 2 3 4 "total" : { "value" : 2024 , "relation" : "eq" }