再次滚动查询
GET /_search/scroll { "scroll":"1m", "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAACNFlJmWHZLTkFhU0plbzlHX01LU2VzUXcAAAAAAAAAkRZSZlh2S05BYVNKZW85R19NS1Nlc1F3AAAAAAAAAI8WUmZYdktOQWFTSmVvOUdfTUtTZXNRdwAAAAAAAACQFlJmWHZLTkFhU0plbzlHX01LU2VzUXcAAAAAAAAAjhZSZlh2S05BYVNKZW85R19NS1Nlc1F3" } _search api 搜索api query string search_searchAPI + 将请求写在URI中
GET /bank/_search?q=*&sort=account_number:asc&pretty同样使用的是RestfulAPI, q=* ,表示匹配index=bank的下的所有doc,sort=account_number:asc表示告诉ES,结果按照account_number字段升序排序,pretty是告诉ES,返回一个漂亮的json格式的数据
上面的q还可以写成下面这样
GET /bank/_search?q=自定义field:期望的值 GET /bank/_search?q=+自定义field:期望的值 GET /bank/_search?q=-自定义field:期望的值响应:
{ "took" : 63, // 耗费的时间 "timed_out" : false, // 是否超时了 "_shards" : { // 分片信息 "total" : 5, // 总共5个分片,它的搜索请求会被打到5个分片上去,并且都成功了 "successful" : 5, // "skipped" : 0, // 跳过了0个 "failed" : 0 // 失败了0个 }, "hits" : { //命中的情况 "total" : 1000, // 命中率 1000个 "max_score" : null, // 相关性得分,越相关就越匹配 "hits" : [ { "_index" : "bank", // 索引 "_type" : "_doc", // type "_id" : "0", // id "sort": [0], "_score" : null, // 相关性得分 // _source里面存放的是数据 "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"} }, { "_index" : "bank", "_type" : "_doc", "_id" : "1", "sort": [1], "_score" : null, "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"} }, ... ] } }指定超时时间: GET /_search?timeout=10ms 在进行优化时,可以考虑使用timeout, 比如: 正常来说我们可以在10s内获取2000条数据,但是指定了timeout,发生超时后我们可以获取10ms中获取到的 100条数据
query dsl (domain specified language)下面我仅仅列出来了一点点, 更多的示例,参见官网 点击进入官网
_searchAPI +将请求写在请求体中
GET /bank/_search { "query": { "match_all": {} }, # 查询全部 "query": { "match": {"name":"changwu zhu"} }, # 全文检索,户将输入的字符串拆解开,去倒排索引中一一匹配, 哪怕匹配上了一个也会将结果返回 # 实际上,上面的操作会被ES转换成下面的格式 # # { # "bool":{ # "should":[ # {"term":{"title":"changwu"}}, # {"term":{"title":"zhu"}} # ] # } # } # "query": { "match": { # 手动控制全文检索的精度, "name":{ "query":"changwu zhu", "operator":"and", # and表示,只有同时出现changwu zhu 两个词的doc才会被命中 "minimum_should_match":"75%" # 去长尾,控制至少命中3/4才算是真正命中 } } }, # 全文检索,operator 表示 # 添加上operator 操作会被ES转换成下面的格式,将上面的should转换成must # # { # "bool":{ # "must":[ # {"term":{"title":"changwu"}}, # {"term":{"title":"zhu"}} # ] # } # } # # 添加上 minimum_should_match 操作会被ES转换成下面的格式 # # { # "bool":{ # "should":[ # {"term":{"title":"changwu"}}, # {"term":{"title":"zhu"}} # ], # "minimum_should_match":3 # } # } # "query": { "match": { #控制权重, "name":{ "query":"changwu zhu", "boost":3 # 将name字段的权重提升成3,默认情况下,所有字段的权重都是样的,都是1 } } }, "query": { # 这种用法不容忽略 "dis_max": { # 直接取下面多个query中得分最高的query当成最终得分 "queries":[ {"match":{"name":"changwu zhu"}}, {"match":{"content":"changwu"}} ] } }, # best field策略 "query": { # 基于 tie_breaker 优化dis_max # tie_breaker可以使dis_max考虑其他field的得分影响 "multi_match":{ "query":"用于去匹配的字段", "type":"most_fields",# 指定检索的策略most_fields "fields":["field1","field2","field3"] } }, # most field 策略, 优先返回命中更多关键词的doc, (忽略从哪个,从多少个field中命中的,只要命中就行) "query": { # 基于 tie_breaker 优化dis_max # tie_breaker可以使dis_max考虑其他field的得分影响 "dis_max": { # 直接取下面多个query中得分最高的query当成最终得分, 这也是best field策略 "queries":[ {"match":{"name":"changwu zhu"}}, {"match":{"content":"changwu"}} ], "tie_breaker":0.4 } }, "query": { "match_none": {} } "query": { "term": {"test_field":"指定值"} } # 精确匹配 "query": { "exits": {"field":"title"} } # title不为空(但是这时ES2.0中的用法,现在不再提供了) "query": { # 短语检索 # 顺序的保证是通过 term position来保证的 # 精准度很高,但是召回率低 "match_phrase": { # 只有address字段中包含了完整的 mill lane (相连,顺序也不能变) 时,这个doc才算命中 "address": "mill lane" } }, "query": { # 短语检索 "match_phrase": { "address": "mill lane", # 指定了slop就不再要求搜索term之间必须相邻,而是可以最多间隔slop距离 # 在指定了slop参数的情况下,离关键词越近,移动的次数越少, relevance score 越高 # match_phrase + slop 和 proximity match 近似匹配作用类似 # 平衡精准度和召回率 "slop":1 # 指定搜索文本中的几个term经过几次移动后可以匹配到一个doc } }, # 混合使用match和match_phrase 平衡精准度和召回率 "query": { "bool": { "must": { # 全文检索虽然可以匹配到大量的文档,但是它不能控制词条之间的距离 # 可能java elasticsearch在Adoc中距离很近,但是它却被ES排在结果集的后面 # 它的性能比match_phrase高10倍,比proximity高20倍 "match": { "address": "java elasticsearch" } }, "should": { # 借助match_phrase+slop可以感知term position的功能,为距离相近的doc贡献分数,让它们靠前排列 "match_phrase":{ "title":{ "query":"java elasticsearch", "slop":50 } } } }, # 重打分机制 "query": { "match":{ "title":{ "query":"java elasticsearch", "minimum_should_match":"50%" } }, "rescore":{ # 对全文检索的结果进行重新打分 "window_size":50, # 对全文检索的前50条进行重新打分 "query": { "rescore_query":{ # 关键字 "match_phrase":{ # match_phrase + slop 感知 term persition,贡献分数 "title":{ "query":"java elasticsearch", "slop":50 } } } } } # 前缀匹配, 相对于全文检索,前缀匹配是不会进行分词的,而且每次匹配都会扫描整个倒排索引,直到扫描完一遍才会停下来 # 不会计算相关性得分,前缀越短拼配到的越多,性能越不好 "query": { # 查询多个, 在下面指定的两个字段中检索含有 `this is a test`的doc "multi_match" : { "query": "this is a test", "fields": [ "subject", "message" ] } }, "query": { # 前缀搜索,搜索 user字段以ki开头的 doc "prefix" : { "user" : "ki" } }, "query": { # 前缀搜索 + 添加权重 "prefix" : { "user" : { "value" : "ki", "boost" : 2.0 } } }, # 通配符搜索 "query": { "wildcard" : { "user" : "ki*y" } }, "query": { "wildcard" : { "user" : { "value" : "ki*y", "boost" : 2.0 } } } # 正则搜索 "query": { "regexp":{ "name.first": "s.*y" } }, "query": {# 正则搜索 "regexp":{ "name.first":{ "value":"s.*y", "boost":1.2 } } }, # 搜索推荐, 类似于百度,当用户输入一个词条后,将其他符合条件的词条的选项推送出来 # 原理和match_pharse相似,但是唯一的区别就是会将最后一个term当作前缀去搜索 # 下例中: 使用quick brown进行match 使用f进行前缀搜索,使用slop调整term persition,贡献得分 "query": { "match_phrase_prefix" : {# 前缀匹配 "message" : { "query" : "quick brown f", "max_expansions" : 10, # 指定前缀最多匹配多少个term,超过这个数量就不在倒排索引中检索了,提升性能 "slop":10 } } }, # Function Score Query # 用户可以自定义一个function_secore 函数,然后将某个field的值和ES计算出来的分数进行运算 # 最终实现对自己指定的field进行分数的增强功能 "query": { "function_score": { "query": { "match_all": {} }, "boost": "5", "random_score": {}, "boost_mode":"multiply" } }, # Fuzzy Query 模糊查询会提供容错的处理 "query": { "fuzzy" : { "user" : { "value": "ki", "boost": 1.0, "fuzziness": 2, # 做大的纠错数量 "prefix_length": 0,# 不会被“模糊化”的初始字符数。这有助于减少必须检查的术语的数量。默认值为0。 "max_expansions": 100 # 模糊查询将扩展到的最大项数。默认值为50 transpositions:true # 是否支持模糊变换(ab→ba)。默认的是假的 } } } "query": { "bool": { # 布尔查询, 最终通过将它内置must,should等查询的得分加起来/should,must的总数, 得到最终的得分 "must": [ # 必须匹配到XXX, 并且会得出相关性得分 { "match": { "address": "mill" } }, # address中必须包含mill ], # 在满足must的基础上,should条件不满足也可以,但是如果也匹配上了,相关性得分会增加 # 如果没有must的话,should中的条件必须满足一个 "should": [ # 指定可以包含的值, should是可以影响相关性得分的 { "match": { "address": "lane" } } ], "must_not": [ # 一定不包含谁 { "match": { "address": "mill" } }, ], "filter": { # 对数据进行过滤 "range": { # 按照范围过滤 "balance": { # 指定过滤的字段 "gte": 20000, # 高于20000 "lte": 30000 # 低于30000 } } } } }在上面的组合查询中,每一个子查询都会计算一下他的相关性分数,然后由最外层的bool综合合并一个得分,但是 filter是不会计算分数的