• -------------------------------------------------------------
  • ====================================

elasticsearch 6.x 处理一对多关系使用场景

elasticsearch dewbay 6年前 (2019-04-12) 2213次浏览 已收录 0个评论 扫描二维码

思考:一个用户有多篇博客,如何查询博客作者姓名中带“旺”字、博客标题中带“运”的 10 篇博客列表

elasticsearch关联模型;

一: 应用层做联接
2 个索引
博客作者、博客发布
先从博客作者中查询出符合姓名中带“旺”字的作者 ID,
然后根据这些 ID、博客标题中带“运”字这两个条件查询出来博客列表

优点: 数据很规范清晰,作者一个索引,博客一个索引
缺点: 如果查询出来的作者 ID 很多的情况造成效率很低(如果有 10 万作者的话,每一次分页都需要先查作者,再拿作者 ID 为条件)

二:非规范化的数据
同一个索引中,博客作者和博客发布表整合成一个文档
冗余、冗余、冗余

优点:不需要做联接
缺点:由于作者博客为一对多关系,每次修改了作者姓名,都需要更新所有的索引文档数据,每次都需要批量改


三:嵌套对象
博客作者和博客发布存在于一个文档(nested)
索引映射中,所有的博客作为数组嵌套的类型存在

优点:不需联接
缺点:只能返回符合条件的整个文档,不能部分返回嵌套文档中的数据(nested 查询职能返回最顶层的文档)

四:父-子关系文档
博客作者和博客发布存在于一个文档(join)
映射时将其中一个字段作为连接字段,供作关联关系

优点:能返回想要的数据
缺点:性能差一点

有了这样的粗略认知之后,实现开始提到的使用场景,选择第四种方案{父-子关系文档}, 并在做了一个简单类似的实验

// 1、创建索引及映射关系

elasticsearch 6.x 处理一对多关系使用场景
put bnb_home

{
  "mappings": {
    "home_search": {
      "properties": {
        "shop_room": {
          "type": "join",
          "relations": {
            "shop": "room"
          }
        }
      }
    }
  }
}
elasticsearch 6.x 处理一对多关系使用场景

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

elasticsearch 6.x 处理一对多关系使用场景
PUT bnb_home/home_search/1?refresh

{
  "data": {"shopId":1, "shopName": "我是客栈锅手", "description": "我是一条测试数据"},
  "shop_room": {
    "name": "shop" 
  }
}
elasticsearch 6.x 处理一对多关系使用场景

// 3、添加子文档(酒店房间信息)***划重点:URL 中的 routing 必须是 parent ID 的值

***

elasticsearch 6.x 处理一对多关系使用场景
PUT bnb_home/home_search/2?routing=1&refresh

{
  "data": {"shopId":1, "roomId":1, "roomName": "我是一条小虫子", "description": "可爱清新风格"},
  "shop_room": {
    "name": "room",
    "parent": "1" 
  }
}
elasticsearch 6.x 处理一对多关系使用场景

// 4、再添加子文档(酒店房间信息)

elasticsearch 6.x 处理一对多关系使用场景
PUT bnb_home/home_search/3?routing=1&refresh

{
  "data": {"shopId":1, "roomId":2, "roomName": "我是第二间房子", "description": "第二件仿佛回到开始"},
  "shop_room": {
    "name": "room",
    "parent": "1" 
  }
}
elasticsearch 6.x 处理一对多关系使用场景

// 5、查询酒店(查询店铺名称中带”你好“,房间名称带有“小虫”的{店铺})

elasticsearch 6.x 处理一对多关系使用场景
POST bnb_home/_search

{
    "query": {
      "bool":{
        "must":[
          {"match":{"data.shopName":"客栈"}},
          {
              "has_child" : {
                  "type" : "room",
                  "query" : {
                    "bool":{
                      "must":[
                        {"match":{"data.roomName":"小虫子"}}
                      ]
                    }
                  }
              }
          }
        ]
      }
    }
}
elasticsearch 6.x 处理一对多关系使用场景

// 6、查询酒店房间(查询店铺名称中带”你好“,房间名称带有“小虫”的{房间})

elasticsearch 6.x 处理一对多关系使用场景
POST bnb_home/_search

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

露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:elasticsearch 6.x 处理一对多关系使用场景
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址