zoukankan      html  css  js  c++  java
  • 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":"客栈"}}
                          ]
                        }
                      }
                  }
              }
            ]
          }
        }
    }
  • 相关阅读:
    一步步构建大型网站架构
    IIS访问设置
    如何删除windows中的服务
    IIS下对WebConfig加密后无法访问网站
    ConfigurationManager不认的问题
    ORA12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
    PostgreSQL中表和字符串大写的问题
    ASP.NET中注册客户端脚本的三种方式
    装箱(boxing)和拆箱(unboxing)
    windows开启防火墙后IIS下的网站外网无法访问
  • 原文地址:https://www.cnblogs.com/liugx/p/8482356.html
Copyright © 2011-2022 走看看