本篇介紹 Query DSL的 其他 query
我會著重在我使用過或是覺得比較特別的 query,沒有介紹到的不代表不重要
要在分散式系統像是es使用 完整的SQL join功能是很expensive(付出很大的代價),
不過es有提供兩種形式的 join
來實現水平擴展
has_child
and has_parent
queries
透過 join
field type可以在單一index內建立fields間的關係,
利用 has_child
query 會匹配出含有指定的child的 parent documents,
反之 has_parent
query 會匹配出含有指定的parent的 child documents
nested
query
之前在介紹
nested
field type的時候,有稍微提到過此 query
欲搜尋 nested
field type的fields,可使用 nested
query,
此 field 在新增 array of objects後,可以針對每一個object用此 query來搜尋,
其中每一個object可以視為一個獨立的document,如果object匹配到了,query就會回傳他的root parent document
Multi-level nested query(多層的nested query)
簡單來說,為了要讓array of objects中的每一個object彼此是獨立的,就會定義 nested
field type,而如果資料是可能含有多層object,也就會有在 nested
field下再定義 nested
field type,也因此搜尋的時候就會搭配使用 multi-level nested query
如下範例
index mapping
PUT /drivers
{
"mappings": {
"properties": {
"driver": { (1)
"type": "nested",
"properties": {
"last_name": {
"type": "text"
},
"vehicle": { (2)
"type": "nested",
"properties": {
"make": {
"type": "text"
},
"model": {
"type": "text"
}
}
}
}
}
}
}
}
(1): 第一層 array of objects driver
,定義 nested
field type
(2): 第二層 array of objects driver.vehicle
,也定義 nested
field type
那搭配此mapping的 multi-level nested query怎麼使用呢?
GET /drivers/_search
{
"query": {
"nested": { (1)
"path": "driver", (3)
"query": {
"nested": { (2)
"path": "driver.vehicle", (4)
"query": { (5)
"bool": {
"must": [
{ "match": { "driver.vehicle.make": "Powell Motors" } },
{ "match": { "driver.vehicle.model": "Canyonero" } }
]
}
}
}
}
}
}
}
(1): 第一層 nested query
(2): 第二層 nested query
(3): path
為 nested query 必填參數,填入欲搜尋的nested object的路徑
(4): 注意這邊要使用 "driver.vehicle"
(5): query
也是 nested query 必填參數,即填入 query clause
Match All Query
最簡單的query,用來匹配所有documents,其中每一個document的 _score
為 1.0
Example Request
GET /_search
{
"query": {
"match_all": {}
}
}
如果想調整分數(_score
),可使用 boost
參數
Example Request
GET /_search
{
"query": {
"match_all": {"boost": 1.2}
}
}
Match None Query
和上述相反,不會匹配到任何documents
Example Request
GET /_search
{
"query": {
"match_none": {}
}
}
distance_feature
query
根據設定的 origin
(原點) date(日期)或point(點),越靠近提高(boost)越多分數,
也就是說,透過此query可以讓更靠近特定日期或地點的documents有更高的權重
限制是只能用在 date
, date_nanos
, geo_point
field type的 fields
如下範例
index mapping
PUT /items
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"production_date": {
"type": "date"
},
"location": {
"type": "geo_point"
}
}
}
}
針對日期的 distance_feature
query
GET /items/_search
{
"query": {
"bool": {
"must": {
"match": {
"name": "chocolate"
}
},
"should": {
"distance_feature": {
"field": "production_date",(1)
"origin": "now" (2)
"pivot": "7d", (3)
}
}
}
}
}
(1): field
為必填,填入欲搜尋的field
(2): origin
為必填,point或date的起點,如果 (1)的field value為 date
或 date_nanos
field type,則此value也必須是date,不過date還可以使用 Date Math,例如: now-1h
,而如果(1)的field value是 geo_point
field,則此value只能是 geopoint
(3): pivot
為必填,date
或 date_nanos
field type的單位必須是 time unit, geo_point
field type的單位必須是 distance unit,如果document與 origin
的距離等於此參數的值,則相關分數就可以得到 boost
值的一半 (boost
預設值為1.0
)
補充一下: boost
參數和上述三個參數為同一層,如未設定則使用預設值1.0
如下為 distance_feature
query 計算document相關分數的公式relevance score = boost * pivot / (pivot + distance)
小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正
Joining queries
Nested query
Specialized queries