第三章 Elasticsearch Query DSL -- 查詢
摘要
Elasticsearch 提供了基於JSON的完整查詢DSL(Domain Specific Language)來定義查詢。將查詢DSL視爲查詢的ASL()。它由兩種子句組成:
- 基本查詢條件(Leaf query clauses):
filed
字段滿足某一特定的值。包括:match
,term
,range
等 - 複合查詢條件(Compound query clauses):由基本查詢條件組合而成,並用邏輯方式組合多個查詢:
bool
;或是更改查詢條件的行爲:constant_score
- Elasticsearch默認允許昂貴的查詢:這種查詢會耗費大量的系統資源,響應速度比較慢。可以在配置中禁止這類查詢:
search.allow_expensive_queries=false
默認爲true
查詢子句的行爲會有所不同,具體取決於它們是在查詢上下文中使用或是在過濾上下文中使用
查詢和過濾的上下文(context)
在查詢上下文中使用查詢子句以應對可能影響匹配文檔得分(即文檔匹配程度)的條件,並在過濾器上下文中使用所有其他查詢子句。
相關性得分
默認情況下,Elasticsearch 按相關性得分對搜索結果進行排序,該得分衡量每個文檔與查詢條件的匹配程度。相關性得分是一個正浮點數_score
,會在搜索結果中mate
字段中返回。得分越高,相關度越高。雖然每種查詢類型都會不同的計算相關性分數,但分數的計算還會取決於查詢子句是在查詢上下文中還是在過濾上下文中運行。
查詢上下文
在查詢上下文中,查詢子句用於表示:某一文檔與該查詢子句的匹配程度如何。除了確定文檔是否匹配之外,查詢子句還計算_score
元字段中的相關性的分。在查詢請求中,傳遞query
的參數。
過濾上下文
在過濾上下文中,查詢子句表示:某一文檔是否匹配過濾子句。答案很簡單,只有是或否,不計算相關性得分。過濾主要用於過濾結構化數據。
Elasticsearch 會緩存常用的過濾器,用於提高性能。在查詢請求中傳遞filter
參數。
示例(下面這些查詢參數,後續會詳述)
query
,指定查詢條件bool
,組建符合查詢must
,隸屬於bool
,必須滿足match
,包含:address這個字段中,包含Street這個單詞filter'
,篩選條件term
,精確等於:age=32
range
,區間查詢:balance>=1000
查詢請求
curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": { "match": { "address": "Street"}},
"filter": [
{ "term": { "age": 32 }},
{ "range": { "balance": { "gte": 1000 }}}
]
}
}
}
'
運行結果
{
"took" : 69,
"timed_out" : false,
"_shards" : {
"total" : 16,
"successful" : 16,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 22,
"relation" : "eq"
},
"max_score" : 0.95395315,
"hits" : [
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "140",
"_score" : 0.95395315,
"_source" : {
"account_number" : 140,
"balance" : 26696,
"firstname" : "Cotton",
"lastname" : "Christensen",
"age" : 32,
"gender" : "M",
"address" : "878 Schermerhorn Street",
"employer" : "Prowaste",
"email" : "[email protected]",
"city" : "Mayfair",
"state" : "LA"
}
}
]
}
}
全文查詢
全文查詢使您可以搜索已分析的文本字段。使用索引期間應用於字段的同一份喜氣來處理查詢字符串
intervals 查詢
全文查詢,可以對匹配項的順序和臨近度進行細粒度控制。
根據匹配項的順序和接近程度返回文檔。intervals查詢使用匹配規則,這些規則是由一小組定義構成的。然後將這些規則,作用於指定的字段fiels
。這些定義產生的最小間隔序列跨越了文本主題中的各個術語。這些間隔可以由上級進一步組合和過濾。
intervals的頂級參數
你想要匹配的字段,必填項。此參數的值是一個規則對象,用於根據匹配項、順序、和接近度來匹配文檔
match 規則參數
match
規則,匹配文本;
query
,必填項。您希望在提供的<field>
中找到的文本max_gaps
,選填項。如果query
填寫是個詞組,會進行分詞。這個參數是限制,分詞後各個詞在文檔中的間隔。除此之外的術語不視爲匹配項,默認爲-1(表示匹配項沒有寬度限制)。如果爲0,則這些術語必須相鄰出現。ordered
,匹配項在文檔中的順序;如果“ordered”: true
,則文檔中的詞組順序必須和匹配項中的順序保持一致。就拿示例來說,如果指定"query": "Street 916", “ordered”: true
,則搜索結果爲空。analyzer
:分析器,用於分析query
,默認爲和文檔中的field
保持一致filter
:過濾器use_field
:如果指定,則會匹配該字段而不是<field>
。就拿示例來說,如果指定"use_field": "state",則會匹配字段state
而不是address
。
對比結果,仔細品味各個指令的含義
請求
POST /_search?pretty
{
"query": {
"intervals" : {
"address" : {
"match" : {
"query": "Street 916",
// 如果"max_gaps":0,則查詢結果爲空;若大於1,則存在值
"max_gaps":10
}
}
}
}
}
結果
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 18,
"successful" : 18,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.3333333,
"hits" : [
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "812",
"_score" : 0.3333333,
"_source" : {
"account_number" : 812,
"balance" : 42593,
"firstname" : "Graves",
"lastname" : "Newman",
"age" : 32,
"gender" : "F",
"address" : "916 Joralemon Street",
"employer" : "Ecrater",
"email" : "[email protected]",
"city" : "Crown",
"state" : "PA"
}
}
]
}
}
aff_of 規則參數
組合規則參數,文檔必須滿足所有匹配規則
intervals
必填項。要組合的匹配規則,所有規則都必須在文檔中產生匹配項,以匹配整個源匹配。max_gaps
(可選,整數)匹配項之間的最大位置數。規則所產生的間隔比此間隔更遠,則不視爲匹配。默認爲-1。如果未指定或設置爲-1,則匹配項沒有寬度限制。如果設置爲0,則這些術語必須彼此相鄰出現。ordered
可選項,如果"ordered":true
,則規則產生間隔應按指定順序出現。默認爲false
filter
可選項,過濾項
any_of 規則參數
intervals
必填項。要組合的匹配規則,文檔只需要滿足其中一個條件即可filter
可選項,過濾項
可以將all_of 替換爲 any_of 體會一下這個規則的含義
請求
POST /_search?pretty
{
"query": {
"intervals" : {
"address" : {
"all_of" : {
"intervals" : [
{ "match" : {
"query" : "the",
"ordered" : true,
"max_gaps" : 0 } },
{ "match" : {
"query" : "The intervals",
"ordered" : true,
"max_gaps" : 0 } }
]
}
}
}
}
}
返回
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 18,
"successful" : 18,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5,
"hits" : [
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "1001",
"_score" : 0.5,
"_source" : {
"account_number" : 164,
"balance" : 9101,
"firstname" : "Cummings",
"lastname" : "Little",
"age" : 26,
"gender" : "F",
"address" : "The intervals query uses matching rules, constructed from a small set of definitions. These rules are then applied to terms from a specified field.The definitions produce sequences of minimal intervals that span terms in a body of text. These intervals can be further combined and filtered by parent sources.",
"employer" : "Comtrak",
"email" : "[email protected]",
"city" : "Chaparrito",
"state" : "WI"
}
}
]
}
}
prefix 規則參數
匹配指定字符集的開頭,index_prefixes參數啓用術語前綴索引,以加快前綴搜索。prefix
除非另行指定analyzer
,否則使用此字段中的搜索分析器將標準化。
prefix
,必填項。您希望<field>
以prefix
開頭。但好像是開頭包含prefix
,自己在實踐中體會,測試。analyzer
:分析器,用於分析query
,默認爲和文檔中的field
保持一致use_field
:如果指定,則會匹配該字段而不是<field>
。就拿示例來說,如果指定"use_field": "state",則會匹配字段state
而不是address
。
wildcard 規則參數
**通配符模式匹配文檔。pattern除非analyzer另行指定,否則使用此字段中的搜索分析器將標準化 **
pattern
,必填項。通配符模式,用於查找匹配項。這個參數支持兩個通配符,?
它與任意單個字符匹配;*
可以匹配一個或多個字符,包括一個空字符。analyzer
:分析器,用於分析query
,默認爲和文檔中的field
保持一致use_field
:如果指定,則會匹配該字段而不是<field>
。就拿示例來說,如果指定"use_field": "state",則會匹配字段state
而不是address
。
避免使用*
或?
開頭,這會增加查找匹配項所迭代的次數,並降低搜索性能
filter 間隔查詢的filter參數
filter規則,是基於一個query組合一個間隔查詢