elasticsearch 6.x 處理一對多關系使用場景


思考:一個用戶有多篇博客,如何查詢博客作者姓名中帶“旺”字、博客標題中帶“運”的10篇博客列表

elasticsearch關聯模型;

一: 應用層做聯接
2個索引
博客作者、博客發布
先從博客作者中查詢出符合姓名中帶“旺”字的作者ID,
然后根據這些ID、博客標題中帶“運”字這兩個條件查詢出來博客列表

優點: 數據很規范清晰,作者一個索引,博客一個索引
缺點: 如果查詢出來的作者ID很多的情況造成效率很低(如果有10萬作者的話,每一次分頁都需要先查作者,再拿作者ID為條件)

二:非規范化的數據
同一個索引中,博客作者和博客發布表整合成一個文檔
冗余、冗余、冗余

優點:不需要做聯接
缺點:由於作者博客為一對多關系,每次修改了作者姓名,都需要更新所有的索引文檔數據,每次都需要批量改


三:嵌套對象
博客作者和博客發布存在於一個文檔(nested)
索引映射中,所有的博客作為數組嵌套的類型存在

優點:不需聯接
缺點:只能返回符合條件的整個文檔,不能部分返回嵌套文檔中的數據(nested查詢職能返回最頂層的文檔)

四:父-子關系文檔
博客作者和博客發布存在於一個文檔(join)
映射時將其中一個字段作為連接字段,供作關聯關系

優點:能返回想要的數據
缺點:性能差一點

 

有了這樣的粗略認知之后,實現開始提到的使用場景,選擇第四種方案{父-子關系文檔}, 並在做了一個簡單類似的實驗

 

// 1、創建索引及映射關系

put bnb_home

{
  "mappings": {
    "home_search": {
      "properties": {
        "shop_room": {
          "type": "join",
          "relations": {
            "shop": "room"
          }
        }
      }
    }
  }
}

 

// 2、添加父文檔(酒店信息)

PUT bnb_home/home_search/1?refresh

{
  "data": {"shopId":1, "shopName": "我是客棧鍋手", "description": "我是一條測試數據"},
  "shop_room": {
    "name": "shop" 
  }
}

 

// 3、添加子文檔(酒店房間信息)***划重點:URL中的routing必須是parent ID 的值

***

PUT bnb_home/home_search/2?routing=1&refresh

{
  "data": {"shopId":1, "roomId":1, "roomName": "我是一條小蟲子", "description": "可愛清新風格"},
  "shop_room": {
    "name": "room",
    "parent": "1" 
  }
}

 

// 4、再添加子文檔(酒店房間信息)

PUT bnb_home/home_search/3?routing=1&refresh

{
  "data": {"shopId":1, "roomId":2, "roomName": "我是第二間房子", "description": "第二件仿佛回到開始"},
  "shop_room": {
    "name": "room",
    "parent": "1" 
  }
}

 

// 5、查詢酒店(查詢店鋪名稱中帶”你好“,房間名稱帶有“小蟲”的{店鋪})

POST bnb_home/_search

{
    "query": {
      "bool":{
        "must":[
          {"match":{"data.shopName":"客棧"}},
          {
              "has_child" : {
                  "type" : "room",
                  "query" : {
                    "bool":{
                      "must":[
                        {"match":{"data.roomName":"小蟲子"}}
                      ]
                    }
                  }
              }
          }
        ]
      }
    }
}

 

// 6、查詢酒店房間(查詢店鋪名稱中帶”你好“,房間名稱帶有“小蟲”的{房間})

POST bnb_home/_search

{
    "query": {
      "bool":{
        "must":[
          {"match":{"data.roomName":"小蟲"}},
          {
              "has_parent" : {
                  "parent_type" : "shop",
                  "query" : {
                    "bool":{
                      "must":[
                          {"match":{"data.shopName":"客棧"}}
                      ]
                    }
                  }
              }
          }
        ]
      }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM