天天看點

Join 資料類型—Elastic Stack 實戰手冊

Join 資料類型—Elastic Stack 實戰手冊
https://developer.aliyun.com/topic/download?id=1295 · 更多精彩内容,請下載下傳閱讀全本《Elastic Stack實戰手冊》 https://developer.aliyun.com/topic/download?id=1295 https://developer.aliyun.com/topic/es100 · 加入創作人行列,一起交流碰撞,參與技術圈年度盛事吧 https://developer.aliyun.com/topic/es100

創作人:李增勝

Join 類型是一種特殊的資料類型,類似父子結構,一個子文檔隻能有一個父文檔,一個父文檔可以有多個子文檔。

使用場景

Join 可以實作父子文檔的關系存儲,在什麼情況下使用 Join 類型呢?假設我們存在這種場景,售賣的商品有評價資訊,商品資訊不會經常發生變更,但是評論資訊就更新的比較頻繁了,此時就可以使用 Join 資料類型來處理此種業務, 一對多關系存在多個文檔中,父子文檔更新性能高,可獨立更新,互不影響。

在實際使用場景中,推薦使用 Data denormalization 來解決過多關聯查詢問題,字面解讀就是”非規範化存儲”,通過備援存儲多字段來達到過多關聯的查詢問題,避免使用 Join 資料類型,雖然帶來了關聯的友善性,但是會帶來額外的查詢開銷影響搜尋性能。

此外,Kibana 對 Join 以及 Nested 的支援也比較少

#定義索引,my_goods_sale 為售賣的商品資訊,my_goods_comment 為商品的評價資訊
PUT my_goods_hot_sale
{
  "mappings": {
    "properties": {
      "my_id": {
        "type": "keyword"
      },
      "my_join_field": { 
        "type": "join",
        "relations": {
          "my_goods_sale": "my_goods_comment" 
        }
      }
    }
  }
}

#添加商品售賣 ID 為1的資訊
PUT my_goods_hot_sale/_doc/1?refresh
{
  "my_id": "1",
  "text": "This is a my_goods_sale",
  "my_join_field": {
    "name": "my_goods_sale" 
  }
}

#添加商品售賣 ID 為2的資訊
PUT my_goods_hot_sale/_doc/2?refresh
{
  "my_id": "2",
  "text": "This is another my_goods_sale",
  "my_join_field": {
    "name": "my_goods_sale"
  }
}

#添加商品售賣 ID 為3,父商品為1,注意父子文檔一定要在一個 shard 上
PUT my_goods_hot_sale/_doc/3?routing=1&refresh
{
  "my_id": "3",
  "text": "This is an comment",
  "my_join_field": {
    "name": "my_goods_comment", 
    "parent": "1" 
  }
}

#添加商品售賣 ID 為4,父商品為1
PUT my_goods_hot_sale/_doc/4?routing=1&refresh
{
  "my_id": "4",
  "text": "This is another comment",
  "my_join_field": {
    "name": "my_goods_comment",
    "parent": "1"
  }
}           

根據父文檔查詢子文檔

GET my_goods_hot_sale/_search
{
  "query": {
    "has_parent": {
      "parent_type": "my_goods_sale",
      "query": {
        "match": {
          "text": "my_goods_sale"
        }
      }
    }
  }
}           

根據子文檔查詢父文檔

GET my_goods_hot_sale/_search
{
  "query": {
    "has_child": {
      "type": "my_goods_comment",
      "query": {
        "match_all": {}
      }
    }
  }
}