ES 筆記四十三:文件的父子關係

CrazyZard發表於2020-01-12
  • 物件和 Nested 物件的侷限性
    • 每次更新,需要重新索引整個物件(包括跟物件和巢狀物件)
  • ES 提供了類似關係型資料庫中Join 的實現。使用Join資料型別實現,可以通過Parent / Child 的關係,從而分離兩個物件
    • 父文件和子文件是兩個獨立的文件
    • 更新父文件無需重新索引整個子文件。子文件被新增,更改和刪除也不會影響到父文件和其他子文件。
  • 定義父子關係的幾個步驟
    • 設定索引的Mapping
    • 索引父文件
    • 索引子文件
    • 按需查詢文件

ES筆記四十二:文件的父子關係

DELETE my_blogs
# 設定 Parent/Child Mapping
PUT my_blogs
{
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "properties": {
      "blog_comments_relation": {
        "type": "join",
        "relations": {
          "blog": "comment"
        }
      },
      "content": {
        "type": "text"
      },
      "title": {
        "type": "keyword"
      }
    }
  }
}

ES筆記四十二:文件的父子關係

PUT my_blogs/_doc/blog1
{
  "title":"Learning Elasticsearch",
  "content":"learning ELK @ geektime",
  "blog_comments_relation":{
    "name":"blog"
  }
}

PUT my_blogs/_doc/blog2
{
  "title":"Learning Hadoop",
  "content":"learning Hadoop",
    "blog_comments_relation":{
    "name":"blog"
  }
}
  • 父文件和子文件必須存在相同的分片上
    • 確保查詢 join 的效能
  • 當指定文件時候,必須指定它的父文件ID
    • 使用route引數來保證,分配到相同的分片

ES筆記四十二:文件的父子關係

#索引子文件
PUT my_blogs/_doc/comment1?routing=blog1
{
  "comment":"I am learning ELK",
  "username":"Jack",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog1"
  }
}

PUT my_blogs/_doc/comment2?routing=blog2
{
  "comment":"I like Hadoop!!!!!",
  "username":"Jack",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}

PUT my_blogs/_doc/comment3?routing=blog2
{
  "comment":"Hello Hadoop",
  "username":"Bob",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}
  • 查詢所有文件
  • Parent Id 查詢
  • Has Child 查詢
  • Has Parent 查詢
    # 查詢所有文件
    POST my_blogs/_search
    {}
    #根據父文件ID檢視
    GET my_blogs/_doc/blog2
    # Parent Id 查詢
    POST my_blogs/_search
    {
    "query": {
    "parent_id": {
      "type": "comment",
      "id": "blog2"
    }
    }
    }
    # Has Child 查詢,返回父文件
    POST my_blogs/_search
    {
    "query": {
    "has_child": {
      "type": "comment",
      "query" : {
                "match": {
                    "username" : "Jack"
                }
            }
    }
    }
    }
    # Has Parent 查詢,返回相關的子文件
    POST my_blogs/_search
    {
    "query": {
    "has_parent": {
      "parent_type": "blog",
      "query" : {
                "match": {
                    "title" : "Learning Hadoop"
                }
            }
    }
    }
    }
  • 返回父文件
  • 通過對子文件進行查詢
    • 返回具體相關子文件的父文件
    • 父子文件在相同的分片上,因此Join 效率高

ES筆記四十二:文件的父子關係

  • 返回相關性的子文件
  • 通過對父文件進行查詢
    • 返回相關的子文件

ES筆記四十二:文件的父子關係

  • 返回所有相關子文件
  • 通過對付文件Id 進行查詢
    • 返回所有相關的子文件

ES筆記四十二:文件的父子關係

  • 需指定父文件 routing 引數

ES筆記四十二:文件的父子關係

#通過ID ,訪問子文件
GET my_blogs/_doc/comment2
#通過ID和routing ,訪問子文件
GET my_blogs/_doc/comment3?routing=blog2
  • 更新子文件不會影響到父文件

ES筆記四十二:文件的父子關係


#更新子文件
PUT my_blogs/_doc/comment3?routing=blog2
{
    "comment": "Hello Hadoop??",
    "blog_comments_relation": {
      "name": "comment",
      "parent": "blog2"
    }
}
Nested Object Parent / Child
優點 文件儲存在一起,讀取效能高 父子文件可以獨立更新
缺點 更新巢狀的子文件時,需要更新整個文件 需要額外的記憶體去維護關係。讀取效能相對差
適用場景 子文件偶爾更新,以查詢為主 子文件更新頻繁
本作品採用《CC 協議》,轉載必須註明作者和本文連結

快樂就是解決一個又一個的問題!

相關文章