
創作人:李增勝
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": {}
}
}
}
}