ES查詢語法
一、Searchtimeout
1、設定:預設沒有timeout,如果設定了timeout,那麼會執行timeout機制。
2、Timeout機制:假設使用者查詢結果有1W條資料,但是需要10″才能查詢完畢
使用者設定了1″的timeout
那麼不管當前一共查詢到了多少資料,都會在1″後ES講停止查詢,並返回當前資料。
3、用法:GET /_search?timeout=1s/ms/m
二、Query DSL
1、match_all:匹配所有
GET /product/_search { "query":{ "match_all": {} } }
2、match:name中包含“nfc”
GET /product/_search { "query": { "match": { "name": "nfc" } } }
3、sort:按照價格倒序排序
GET /product/_search { "query": { "multi_match": { "query": "nfc", "fields": ["name","desc"] } }, "sort": [ { "price": "desc" } ] }
4、multi_match:根據多個欄位查詢一個關鍵詞,name和desc中包含“nfc”的doc
GET /product/_search { "query": { "multi_match": { "query": "nfc", "fields": ["name","desc"] } }, "sort": [ { "price": "desc" } ] }
5、_source 元資料:想要查詢多個欄位,例子中為只查詢“name”和“price”欄位。
GET /product/_search { "query":{ "match": { "name": "nfc" } }, "_source": ["name","price"] }
6、分頁(deep-paging):查詢第一頁(每頁兩條資料)
GET /product/_search { "query":{ "match_all": {} }, "sort": [ { "price": "asc" } ], "from": 0, "size": 2 }
三、Full-text queries
1、query-term:不會被分詞
(name:nfc phone)中nfc phone不會被分詞,但是doc會被分詞,所以在es中查詢時結果為0
GET /product/_search { "query": { "term": { "name": "nfc phone" } } }
GET /product/_search { "query": { "terms": { "name":["nfc","phone"] } } }
2、match和term的區別:
GET /product/_search { "query": { "term": { "name": "nfc phone" 這裡因為沒有分詞,所以查詢沒有結果 } } }
3、全文檢索
GET /product/_search { "query": { "match": { "name": "xiaomi nfc zhineng phone" } } } #驗證分詞 GET /_analyze { "analyzer": "standard", "text":"xiaomi nfc zhineng phone" }
四、短語搜尋
GET /product/_search { "query": { "match_phrase": { "name": "nfc phone" } } }
五、查詢和過濾
1、bool
可以組合多個查詢條件,bool查詢也是採用more_matches_is_better的機制,因此滿足must和should子句的文件將會合並起來計算分值。
①must:必須滿足
子句(查詢)必須出現在匹配的文件中,並將有助於得分。
②filter:過濾器,不計算相關度分數
子句(查詢)必須出現在匹配的文件中。但是不像must查詢的分數將被忽略。
Filter子句在filter上下文中執行,這意味著計分被忽略,並且子句被考慮用於快取。
③should:可能滿足 or
子句(查詢)應出現在匹配的文件中。
④must_not:必須不滿足 不計算相關度分數
子句(查詢)不得出現在匹配的文件中。子句在過濾器上下文中執行,這意味著計分被忽略
並且子句被視為用於快取。由於忽略計分,0因此將返回所有文件的分數。
⑤minimum_should_match:should配合使用,滿足幾個should條件
⑥range:lt大於,gt小於
#首先篩選name包含“xiaomi phone”並且價格大於1999的資料(不排序),
#然後搜尋name包含“xiaomi”and desc 包含“shouji”
GET /product/_search { "query": { "bool":{ "must": [ {"match": { "name": "xiaomi"}}, {"match": {"desc": "shouji"}} ], "filter": [ {"match_phrase":{"name":"xiaomi phone"}}, {"range": { "price": { "gt": 1999 } }} ] } } }
2、bool多條件
name包含xiaomi 不包含erji 描述裡包不包含nfc都可以,價錢要大於等於4999
GET /product/_search { "query": { "bool":{ #name中必須不能包含“erji” "must": [ {"match": { "name": "xiaomi"}} ], #name中必須包含“xiaomi” "must_not": [ {"match": { "name": "erji"}} ], #should中至少滿足0個條件,參見下面的minimum_should_match的解釋 "should": [ {"match": { "desc": "nfc" }} ], #篩選價格大於4999的doc "filter": [ {"range": { "price": { "gt": 4999 } }} ] } } }
3、巢狀查詢
minimum_should_match:引數指定should返回的文件必須匹配的子句的數量或百分比。如果bool查詢包含至少一個should子句,而沒有must或 filter子句,則預設值為1。否則,預設值為0
GET /product/_search { "query": { "bool": { "filter": { "bool": { "should": [ { "range": {"price": {"gt": 1999}}}, { "range": {"price": {"gt": 3999}}} ], "must": [ { "match": {"name": "nfc"}} ] } } } } }
4、組合查詢
搜尋一臺xiaomi nfc phone或者一臺滿足 是一臺手機 並且 價格小於等於2999
GET /product/_search { "query": { "constant_score": { "filter": { "bool":{ "should":[ {"match_phrase":{"name":"xiaomi nfc phone"}}, { "bool":{ "must":[ {"term":{"name":"phone"}}, {"range":{"price":{"lte":"2999"}}} ] } } ] } } } } }
5、高亮
GET /product/_search { "query" : { "match_phrase" : { "name" : "nfc phone" } }, "highlight":{ "fields":{ "name":{} } } }
六、Deep paging問題
使用場景:當你的資料超過1W時,不要使用,返回不要超過1000個
解決辦法:儘量避免深查詢,使用Scroll search
如上圖所示:
使用者要查詢5001~5050條資料。一個叢集有5個PShard分片構成完整資料,每個PShard中有1W資料
這時ES會在每個分片中將前5050條資料取出,這時一共會取出25250條資料,十分耗效能