一、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條數據,十分耗性能