本篇繼續介紹 Query DSL 的 term-lvel queries
range query找出terms在指定的range的documents
[情境] 找出 field age 的field value 介於 10(包含) 和 20(包含) 之間的documents
Example Request
GET /_search
{
"query": {
"range": { (1)
"age": { (2)
"gte": 10, (3)
"lte": 20 (4)
}
}
}
}
(1): range query
(2): <field>,必填,欲搜尋的 field
(3): gte,大於等於
(4): lte,小於等於
當然,有大於等於,也有 "大於",使用 gt,同理,"小於" 使用 lt
range query with text and keyword fields
實際上,range query是可以用在 field type為 text 和 keyword 的fields,
不過是屬於 expensive queries (成本比較高),所以一般而言執行會比較慢。
而有參數可以限制 expensive queries, search.allow_expensive_queries 預設為 true,
當設定為 false 時,就無法執行 expensive queries,也就會包含無法使用 range query 來搜尋 field data type 為 text 和 keyword 的fields。
range query with date fields
如果 <field> 的 field data type為 date,則可以使用 date math(https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math) 搭配 gt, gte, lt, lte
[情境] 找出 field timestamp 的field value 介於 今天 和 昨天 之間的documents
Example Request
GET /_search
{
"query": {
"range": {
"timestamp": {
"gte": "now-1d/d", (1)
"lt": "now/d" (2)
}
}
}
}
(1): 現在 減 1天,並無條件捨去至最近的天
(2): 現在,並無條件捨去至最近的天
這邊稍微說明一下 date math,
可使用日期來當錨點(anchor),如 now 或者是 formatted date,而如果使用 formatted date,其後面須加上 ||,然後在 anchor date 後面可選擇性加上 數學式,
例如:
+1h: 加上1小時-1d: 減1天/d: 無條件捨去至最近的天regex query透過 regular expression 找出有匹配的terms,然後回傳其documents
而 regex query 支援的operators可參閱 Regular expression syntax ,是使用 Apache Lucene's 的 regular expression 引擎
[情境] 找出field user.id 是 k 開頭,y 結尾的documents
Example Request
GET /_search
{
"query": {
"regexp": { (1)
"user.id": { (2)
"value": "k.*y", (3)
"flags": "ALL" (4)
}
}
}
}
(1): 即 regex query
(2): <field>,必填,欲搜尋的 field
(3): value,必填,填入 regular expression
(4): flags,選填,預設為 ALL,此參數用來設定 regular expression引擎 可使用的operators
上述request的 regex為 "k.*y",其中 .* operators 代表的是可以匹配任何字元,包括沒有字元也算,所以可以匹配的terms可以是 ky, kay, kelly 等等
[Note]regex query也是屬於 expensive queries
term query搜尋出指定field含 exact term 的documents
在蠻多篇章應該都有提到此 query,這邊再完整介紹一次
[Note]
避免使用 term query 在 text field 上,因為 text field在建立索引時,會經過 analyzer分析而改變原本的值,所以會讓精確匹配是很困難的
此範例使用 Elastic Stack第七重 匯入的範例資料,所以想用一樣的測資可先照那一重做批次匯入
[情境] 找出 field firstname 為 "Nanette" 的 帳戶擁有者資訊(document)
Request
GET /bank/_search
{
"query": {
"term": { (1)
"firstname.keyword": { (2)
"value": "Nanette" (3)
}
}
}
}
(1): 即 term query
(2): <field>,必填,欲搜尋的field,記得使用非 text field,此處使用 "firstname.keyword" 的 field date type為 keyword,而 "firstname" 是 text field data type,所以不能使用 "firstname" ,否則會不如預期(以此為例,用 "firstname" 會匹配不到任何documents)
(3): value,必填,欲搜尋的值
Response
上述Request也可以簡寫成
GET /bank/_search
{
"query": {
"term": {
"firstname.keyword": "Nanette"
}
}
}
[Note]
如欲搜尋 text fields,可以透過 match query,在儲存至此field前會經過analyzer分析後轉換成tokens才會被建立索引,而用 match query 提供的 query string(search term)也一樣會經過analyzer分析,此兩個analyzer是可以指定成不一樣的analyzer,在未設定時,皆使用預設的 standard analyzer ,透過分析後的 tokens 來做匹配搜尋,而不是用 exact term(精確的值)
而 term query "不會"分析 search term, term query 直接拿提供的term找出完整符合的term,這也意味著用 term query 搜尋 text fields 可能回傳 poor(較少) 或 沒有匹配的documents
terms query搜尋出指定field含 一個或多個 exact term 的documents,
其實和 term query一樣,只是差在可以搜尋多個值
[情境] 找出 field firstname 為 "Nanette" 或 "Mcgee" 的 帳戶擁有者資訊(document)
Request
GET /bank/_search
{
"query": {
"terms": { (1)
"firstname.keyword": ["Nanette", "Mcgee"] (2)
}
}
}
(1): 即 terms query
(2): 放置多個 search term至array value
Response
小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正
Term-level queries
regular expression