在 elasticSearch 中个绍,共有兩種查詢:1. url 搜索 2. DSL查詢語言
-
url 搜索
顧名思義死遭, url搜索的參數(shù)都通過url來傳遞钠署,方便來進行一般的數(shù)據(jù)查看,大概如下面這種形式的
GET twitter/_search?q=user:kimchy
-
Request Body 搜索
通過的 DSL(Domain Specific Language) 來定義查詢語言, 像下面這個
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }
這篇文章主要來說明 DSL 查詢的原理和語法题造。
DSL 搜索查詢
Elasticsearch提供了基于JSON的完整查詢DSL(Domain Specific Language[特定于域的語言])來定義查詢牵触。將查詢DSL視為查詢的AST(Abstract Syntax Tree[抽象語法樹]袜腥。
它由兩種子句組成:
-
子句查詢條件
子句查詢在特定字段中查找特定值福侈,例如match卢未,term或range查詢肪凛。這些查詢可以單獨使用。
-
復(fù)合查詢條件
復(fù)合查詢是把 子句查詢和 其他復(fù)合查詢組合起來辽社,實現(xiàn)復(fù)雜邏輯的查詢伟墙。例如bool和 dis_max 查詢
相同的查詢條件的結(jié)果依賴于他們的上下文環(huán)境,elasticSearch 的DSL 主要提供兩種上下文環(huán)境 : query[查詢上下文] 和 filter[過濾器上下文]滴铅。
filter 和 query 上下文
注意了戳葵, DLS關(guān)鍵是要搞清楚 filter 和 query 的差別
- 相關(guān)性得分 [relevance score]
默認(rèn)情況下, ElaticSearch通過相關(guān)性得分(查詢和文檔的匹配程度)來對結(jié)果排序汉匙。
相關(guān)性得分是一個正浮點數(shù)拱烁,在_search API 中以 _score 字段返回。_score 值越大盹兢,相關(guān)性越高邻梆。
每種字段以不同的方式計算_score, _score的計算也根據(jù)查詢條件運行于 filter 或者 query 而不同绎秒。
- 結(jié)構(gòu)化查詢
在 query 上下文中浦妄, 一個查詢條件主要解決的問題是: 條件和文檔的匹配程度有多高。除了解決匹配度的問題, 還會計算一個相關(guān)性程度剂娄,作為元數(shù)據(jù) _score 返回蠢涝。
- 結(jié)構(gòu)化過濾
在 filter 上下文中, 一個查詢條件主要解決的問題是: 條件和文檔是否匹配阅懦。通常結(jié)果是匹配和不匹配和二,這主要用于過濾結(jié)構(gòu)化數(shù)據(jù)。
一條過濾語句會詢問每個文檔的字段值是否包含著特定值:
- status 字段中是為 "published" ?
- created 的日期范圍是否在 2013 到 2014 ?
不論是把查詢條件傳遞給 bool下的 filter 或者 must 參數(shù)等耳胎, 還是在 聚合中的filter惯吕, filter都會起作用
- 性能差異
使用過濾語句得到的結(jié)果集 -- 一個簡單的文檔列表,快速匹配運算并存入內(nèi)存是十分方便的怕午, 每個文檔僅需要1個字節(jié)废登。這些緩存的過濾結(jié)果集與后續(xù)請求的結(jié)合使用是非常高效的。
查詢語句不僅要查找相匹配的文檔郁惜,還需要計算每個文檔的相關(guān)性堡距,所以一般來說查詢語句要比 過濾語句更耗時,并且查詢結(jié)果也不可緩存兆蕉。
幸虧有了倒排索引羽戒,一個只匹配少量文檔的簡單查詢語句在百萬級文檔中的查詢效率會與一條經(jīng)過緩存 的過濾語句旗鼓相當(dāng),甚至略占上風(fēng)虎韵。 但是一般情況下易稠,一條經(jīng)過緩存的過濾查詢要遠(yuǎn)勝一條查詢語句的執(zhí)行效率。
過濾語句的目的就是縮小匹配的文檔結(jié)果集劝术,所以需要仔細(xì)檢查過濾條件缩多。
- 什么情況下使用
原則上來說,使用查詢語句做全文本搜索或其他需要進行相關(guān)性評分的時候养晋,剩下的全部用過濾語句
Use query clauses in query context for conditions which should affect the score of matching documents (i.e. how well does the document match), and use all other query clauses in filter context.
復(fù)合查詢
-
bool
組合其他查詢的默認(rèn)查詢: 如must, should, must_not, or filter
must 和 should 會把score 合并起來衬吆, 越匹配越好
must_not 和 filter 則在filter 條件中執(zhí)行
-
booting query
增加正匹配查詢的匹配分?jǐn)?shù), 減少負(fù)匹配的查詢分?jǐn)?shù)绳泉。
-
constant_score query
包含另一個查詢的查詢逊抡, 但是所有文檔使用同一score, 在過濾器上下文執(zhí)行
全文搜索查詢
-
common terms query
大概可以理解為優(yōu)先級查詢零酪, 比如 not happy冒嫡, 會優(yōu)先查詢含有 happy的文檔
忽略或者從結(jié)構(gòu)中去過濾一些高頻率詞的查詢匹配,通常如 the四苇, a孝凌, not 等副詞,來提高搜索效率 月腋,這些詞通常單獨沒有意義蟀架,組合起來又不可缺少瓣赂, 例如 happy 和 not happy, common 首先搜索happy片拍,得到的結(jié)果中過濾 在對not happy 計算_score.
-
intervals query
intervals query 允許用戶精確控制查詢詞在文檔中出現(xiàn)的先后關(guān)系煌集,實現(xiàn)了對terms順序、terms之間的距離以及它們之間的包含關(guān)系的靈活控制
這個查詢匹配 my_text 中" my favorite food is cold porridge.", 但是不會匹配 "it's cold my favorite food is porridge."
POST _search
{
"query": {
"intervals" : {
"my_text" : {
"all_of" : {
"ordered" : true,
"intervals" : [
{
"match" : {
"query" : "my favorite food",
"max_gaps" : 0,
"ordered" : true
}
},
{
"any_of" : {
"intervals" : [
{ "match" : { "query" : "hot water" } },
{ "match" : { "query" : "cold porridge" } }
]
}
}
]
}
}
}
}
}
-
match
匹配文本捌省,數(shù)字苫纤,日期或布爾值等文檔,在執(zhí)行文本匹配之前纲缓,首先會 分析查詢詞匯卷拘。
match是full-text搜索的默認(rèn)查詢,包含模糊查詢祝高。match 的語法結(jié)構(gòu):
{
"query":{
"match": {
<field_name>: { // field_name 是match 的 top-level 參數(shù)
"query" : "" // 查詢內(nèi)容
"analyzer": "" // 分詞器
"operator" "OR[默認(rèn)], AND" //用于解釋 query中的bool邏輯
.....
}
}
}
}
-
match phrase query
短語查詢恭金, 查詢條件按照一個詞來處理
例如: "He is" 只能查詢到"He is a student", 而不能查詢到 "He said that is a monstor."
-match phrase prefix query
短語前綴查詢, 查詢文本的最后一項是單詞的前綴
```
GET /_search
{
"query": {
"match_phrase_prefix" : {
"message" : {
"query" : "quick brown f"
}
}
}
}
```
-
multi match query
match 的擴展褂策, 可以規(guī)定多個字符串匹配.
語法結(jié)構(gòu)和 match 稍有不同
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "best_fields",
"fields": [ "first_name", "last_name" ], // field 可以是很多個
"operator": "and"
}
}
}
term-level 查詢
查詢結(jié)構(gòu)化數(shù)據(jù)中的精確值, term-level 不對搜索文本進行分析颓屑, 它匹配精確的值斤寂。
exists
-
fuzzy
自動模糊查詢
ids
GET /_search
{
"query": {
"ids" : {
"values" : ["1", "4", "100"]
}
}
}
- preix
GET /_search
{
"query": {
"prefix": {
"user": {
"value": "ki"
}
}
}
}
- range
GET _search
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}
regexp
-
term
返回在特定字段中內(nèi)容完全相同的文檔。
可以term去找一個有精確值字段【價格揪惦,productID或用戶名】的文檔遍搞。
避免在類型為text字段上使用term, 要使用請使用 match器腋。 elasticSearch 會對text字段使用analysis, 這會導(dǎo)致term 搜索邊的困難
GET /_search { "query": { "term": { "user": { "value": "Kimchy", "boost": 1.0 } } } }
-
terms
terms的多字段形式
term_set
- wildcard