elasticsearch的rest搜索--- 查询
目录: 一、 针对这次装B 的解释
四、 查询
四、 查询
1. 查询的官网的文档
2. 查询的rest格式
3. 介绍用过的查询方式
一般的查询
http://blog.csdn.net/dm_vincent/article/details/41820537
查询出的数据字段的解释
- took —— Elasticsearch执行这个搜索的耗时,以毫秒为单位- timed_out —— 指明这个搜索是否超时
- _shards —— 指出多少个分片被搜索了,同时也指出了成功/失败的被搜索的shards的数量
- hits —— 搜索结果
- hits.total —— 能够匹配我们查询标准的文档的总数目
- hits.hits —— 真正的搜索结果数据(默认只显示前10个文档)- _score和max_score —— 现在先忽略这些字段
(1) match匹配
1 "query":{ 2 "match":{ 3 "UserName":"BWH-PC" 4 } 5 }
match是匹配一个key对应的value,value可以是多个,但是必须是这个字段下的,查找多个字段的是不行.
1 { 2 "query": { 3 "match": { 4 "text": "quick fox" 5 } 6 } 7 }
相当于
1 { 2 "query": { 3 "bool": { 4 "should": [ 5 { 6 "term": { 7 "text": "quick" 8 } 9 }, 10 { 11 "term": { 12 "text": "fox" 13 } 14 } 15 ] 16 } 17 } 18 }
(2) multi_match 匹配
1 { 2 "query": { 3 "multi_match": { 4 "query": "bbc0641345dd8224ce81bbc79218a16f", 5 "operator": "or", 6 "fields": [ 7 "*.machine" 8 ] 9 } 10 } 11 }
注意:如果没有machine这个字段,就会报错,需要在fields后面添加一个""
fields中可以添加*做模糊----fields": ["f*.name"]【查询的是f开头的】
"operator":"or" 指的是对query中的多个值查询方式
其中的type的配置报错,需要进一步学习
(3) bool查询
1 { 2 "bool": { 3 "must": { 4 "match": { 5 "title": "how to make millions" 6 } 7 }, 8 "must_not": { 9 "match": { 10 "tag": "spam" 11 } 12 }, 13 "should": [ 14 { 15 "match": { 16 "tag": "starred" 17 } 18 }, 19 { 20 "range": { 21 "date": { 22 "gte": "2014-01-01" 23 } 24 } 25 } 26 ] 27 } 28 }
must:所有分句都必须匹配,与 AND 相同。
must_not:所有分句都必须不匹配,与 NOT 相同。
should:至少有一个分句匹配,与 OR 相同。
(4) term查询
(a) 在term查询中,字段是field.name1,那么term不能查,以为"."必须是域
"term":{"f1.name":"a1"}-----那么意思是查找的是f1的field下面的name
但是数据中有"f1.name":"a1" ,那么term是查找不到这个, 所以数据中的key不能有"."
(b) 在term中查询时候,查询的字段的值不能有大写,但是可以有空格 ---- 对数据中有大写,那么查询用小写,也会匹配到那个值的
1 "term": { 2 "CapabilityDescriptions": "aa" 3 }
(5)不计算存在的次数,判断存在就1分,当然可以指定分数
1 { 2 "query": { 3 "bool": { 4 "should": [ 5 { 6 "constant_score": { 7 "query": { 8 "match": { 9 "description": "wifi" 10 } 11 } 12 } 13 }, 14 { 15 "constant_score": { 16 "query": { 17 "match": { 18 "description": "garden" 19 } 20 } 21 } 22 }, 23 { 24 "constant_score": { 25 "boost": { 26 "query": { 27 "match": { 28 "description": "pool" 29 } 30 } 31 } 32 } 33 } 34 ] 35 } 36 } 37 }
(6) exists 过滤器 相当于is not null
missing相当于is null【没查到的是null】
(7) 过滤查询---了解到这种过滤会使得查询效率高,而不是单纯的查询完以后的过滤
当执行 filtered 查询时,filter 会比 query 早执行。结果字节集会被传给 query 来跳过已经被排除的文档。这种过滤器提升性能的方式,查询更少的文档意味着更快的速度。
(a)query带match filter带term 【term是精确匹配单个字段 , terms中可以写多个的term】
1 { 2 "query": { 3 "filtered": { 4 "query": { 5 "match": { 6 "email": "business opportunity" 7 } 8 }, 9 "filter": { 10 "term": { 11 "folder": "inbox" 12 } 13 } 14 } 15 } 16 }
(b)query没有,默认是查询match_all , fliter中带bool 【bool中再使用match或者match_all,需要用query包】
1 { 2 "query": { 3 "filtered": { 4 "filter": { 5 "bool": { 6 "must": { 7 "term": { 8 "folder": "inbox" 9 } 10 }, 11 "must_not": { 12 "query": { 13 "match": { 14 "email": "urgent business proposal" 15 } 16 } 17 } 18 } 19 } 20 } 21 } 22 }
(c) tie_breaker ,在标题的网址中去查,是最佳字段的调优,是将匹配度乘以这个值
tie_breaker的取值范围是0到1之间的浮点数,取0时即为仅使用最佳匹配子句(译注:和不使用tie_breaker参数的dis_max查询效果相同),取1则会将所有匹配的子句一视同仁。
它的确切值需要根据你的数据和查询进行调整,但是一个合理的值会靠近0,(比如,0.1 -0.4),来确保不会压倒dis_max查询具有的最佳匹配性质。
(d)range 过滤器,让你可以根据范围过滤:range过滤器也可以用于日期字段
1 "range": { 2 "price": { 3 "gt": 20, 4 "lt": 40 5 } 6 }
1 { 2 "query": { 3 "filtered": { 4 "filter": { 5 "range": { 6 "price": { 7 "gte": 20, 8 "lt": 40 9 } 10 } 11 } 12 } 13 } 14 }
1 { 2 "range": { 3 "timestamp": { 4 "gt": "2014-01-0100: 00: 00", 5 "lt": "2014-01-0700: 00: 00" 6 } 7 } 8 }
到所有最近一个小时的文档:
1 { 2 "range": { 3 "timestamp": { 4 "gt": "now-1h" 5 } 6 } 7 }
(e) 区别于 filtered ,post_filter查询就是先查询,后过滤, 效率没有前面的高
后置过滤--post_filter元素是一个顶层元素,只会对搜索结果进行过滤。警告:性能考量只有当你需要对搜索结果和聚合使用不同的过滤方式时才考虑使用post_filter。有时一些用户会直接在常规搜索中使用post_filter。不要这样做!post_filter会在查询之后才会被执行,因此会失去过滤在性能上帮助(比如缓存)。post_filter应该只和聚合一起使用,并且仅当你使用了不同的过滤条件时。
----下面的例子是可以过滤field的,multi_match必须使用query包,
match只能过滤没有被“包”的,必须multi_match是过滤被"包"的,
query_string中的是全文搜索,是可以查到所有的数据
eg:查询machine是bbc0641345dd8224ce81bbc79218a16f,不管是否被字段包,都需要过滤出来
1 { 2 "query": { 3 "query_string": { 4 "query": "*" 5 } 6 }, 7 "post_filter": { 8 "bool": { 9 "should": { 10 "query": { 11 "bool": { 12 "should": [ 13 { 14 "match": { 15 "machine": "bbc0641345dd8224ce81bbc79218a16f" 16 } 17 }, 18 { 19 "match": { 20 "machine": "bbc0641345dd8224ce81bbc79218a16f" 21 } 22 } 23 ] 24 } 25 } 26 } 27 } 28 } 29 }
当然,在里面的每一个should中,可以去做很多变形,但是should多个子类时,必须用[]
1 { 2 "query": { 3 "query_string": { 4 "query": "*" 5 } 6 }, 7 "post_filter": { 8 "bool": { 9 "should": [ 10 { 11 "query": { 12 "bool": { 13 "must": [ 14 { 15 "multi_match": { 16 "query": "bbc0641345dd8224ce81bbc79218a16f", 17 "operator": "or", 18 "fields": [ 19 "*.machine", 20 "" 21 ] 22 } 23 }, 24 { 25 "multi_match": { 26 "query": "10.10.185.99", 27 "operator": "or", 28 "fields": [ 29 "*.IPAddress", 30 "" 31 ] 32 } 33 } 34 ] 35 } 36 } 37 }, 38 { 39 "query": { 40 "bool": { 41 "must": [ 42 { 43 "match": { 44 "machine": "bbc0641345dd8224ce81bbc79218a16f" 45 } 46 }, 47 { 48 "match": { 49 "IPAddress": "10.10.11.11" 50 } 51 } 52 ] 53 } 54 } 55 } 56 ] 57 } 58 } 59 }
(f) 这是查询中最让人恶心的:查询到结果以后,进行过滤(或者过滤以后进行查询)----其实这种复杂的,直接在query中查,最后在_score中过滤,0.1以下的就是不匹配(同事不让,原因不明,我感觉这很好用)
在一般的过滤中,比如"first":"a1" 那么只能过滤到第二个,不被name包的
但是有时候,对于field没创建好的情况下,需要"包","不包"的都匹配上,就需要使用multi_match和match的联用
在过滤中可以用match或者multi_match,query_string放的方式用query包
eg:查询 last = a2的,不管包还是不包的都要查询出来
1 { 2 "query": { 3 "filtered": { 4 "query": { 5 "query_string": { 6 "query": "*" 7 } 8 }, 9 "filter": { 10 "bool": { 11 "should": { 12 "query": { 13 "bool": { 14 "should": [ 15 { 16 "multi_match": { 17 "query": "a2", 18 "operator": "or", 19 "fields": [ 20 "*.last" 21 ] 22 } 23 }, 24 { 25 "match": { 26 "last": "a2" 27 } 28 } 29 ] 30 } 31 } 32 } 33 } 34 } 35 } 36 } 37 }
8. 询条件添加以后,进行数量的检索_search?search_type=count