iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
1
Elastic Stack on Cloud

Elastic Stack武學練功坊系列 第 23

Elastic Stack第二十三重

  • 分享至 

  • xImage
  •  

Query DSL Part IV (查詢語法)

本篇介紹 Query DSL的 其他 query
我會著重在我使用過或是覺得比較特別的 query,沒有介紹到的不代表不重要


Join queries

要在分散式系統像是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): pathnested query 必填參數,填入欲搜尋的nested object的路徑
(4): 注意這邊要使用 "driver.vehicle"
(5): query 也是 nested query 必填參數,即填入 query clause

Match all

Match All Query
最簡單的query,用來匹配所有documents,其中每一個document的 _score1.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": {}
  }
}

Specialized queries(專用的query)

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為 datedate_nanos field type,則此value也必須是date,不過date還可以使用 Date Math,例如: now-1h ,而如果(1)的field value是 geo_point field,則此value只能是 geopoint
(3): pivot為必填,datedate_nanos field type的單位必須是 time unitgeo_point field type的單位必須是 distance unit,如果document與 origin 的距離等於此參數的值,則相關分數就可以得到 boost 值的一半 (boost預設值為1.0)

補充一下: boost 參數和上述三個參數為同一層,如未設定則使用預設值1.0

如下為 distance_feature query 計算document相關分數的公式
relevance score = boost * pivot / (pivot + distance)


小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正


Reference

Joining queries
Nested query
Specialized queries


上一篇
Elastic Stack第二十二重
下一篇
Elastic Stack第二十四重
系列文
Elastic Stack武學練功坊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言