• ElasticSearch join连接查询


    ElasticSearch join连接查询

    特别说明:文章所有内容基于ElasticSerch 5.5.3版本

    ElasticSerch 的连接查询有两种方式实现

    • nested
    • parent和child关联查询

    nested

    • 存储结构
      nested的方式和其他字段一样,在同一个type里面存储,以数组的方式存储在
      type里,格式如下:

      PUT index_test/type_info/1000
      {
      “userId”: 1000,
      “mobile”: “13301020202”,
      “nick”: “梅西”,
      “vipType”: 1,
      “vipPoints”: 1200,
      “regTime”: “2018-06-18 12:00:31”,
      “order”: [
      {
      “status”: 1,
      “payMethod”: 2,
      “amount”: 100,
      “productCount”: 3
      },
      {
      “status”: 2,
      “payMethod”: 2,
      “amount”: 230,
      “productCount”: 1
      }
      ]
      }

    order 则为 nested

    • API查询方式
      直接用.连接对象的属性,如要要查找订单中状态=2的用户,直接使用order.status

      GET index_test/type_info/_search
      {
      “query”: {
      “term”: {
      “order.status”: 2
      }
      }
      }

    parent / child 关联的方式

    • 存储结构
      parent / child 的存储结果跟nested不一样,是存储在不同的type里,通过parent来关联父子type关系

      PUT index_test
      {
      "mappings": {
      "type_info": {
        "properties": {
          "userId": {
            "type": "integer"
          },
          "mobile": {
            "type": "keyword"
          },
          "nick": {
            "type": "keyword"
          },
          "vipType": {
            "type": "integer"
          },
          "vipPoints": {
            "type": "integer"
          },
          "regTime": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss"
          }
        }
      },
      "type_order": {
        "_parent": {
          "type": "type_info"
        },
        "properties": {
          "amount": {
            "type": "scaled_float",
            "scaling_factor": 100
          },
          "payMethod": {
            "type": "integer"
          },
          "status": {
            "type": "integer"
          },
          "productCount": {
            "type": "integer"
          }
        }
      }
      }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48

      通过 _parent 来指定父type

    • 造点数据
      添加几条用户数据,和普通的type一样,没有任何区别

      PUT index_test/type_info/1000
      {
      "userId": 1000,
      "mobile": "13301020202",
      "nick": "梅西",
      "vipType": 1,
      "vipPoints": 1200,
      "regTime": "2018-06-18 12:00:31"
      }
      
      PUT index_test/type_info/1001
      {
      "userId": 1001,
      "mobile": "151232223",
      "nick": "C罗",
      "vipType": 1,
      "vipPoints": 300,
      "regTime": "2018-05-18 12:00:00"
      }
      
      PUT index_test/type_info/1002
      {
      "userId": 1002,
      "mobile": "181829282",
      "nick": "内马尔",
      "vipType": 2,
      "vipPoints": 1300,
      "regTime": "2018-09-09 12:00:00"
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29

      添加几条订单数据,通过parent来指定type_info

      PUT index_test/type_order/100?parent=1000
      {
      "userId": 1000,
      "amount": 300,
      "payMethod": 2,
      "status": 3,
      "productCount": 2
      }
      
      PUT index_test/type_order/101?parent=1000
      {
      "userId": 1000,
      "amount": 250,
      "payMethod": 1,
      "status": 2,
      "productCount": 1
      }
      
      PUT index_test/type_order/102?parent=1001
      {
      "userId": 1001,
      "amount": 56,
      "payMethod": 1,
      "status": 2,
      "productCount": 1
      }
      
      PUT index_test/type_order/103?parent=1002
      {
      "userId": 1002,
      "amount": 78,
      "payMethod": 2,
      "status": 1,
      "productCount": 2
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
    • API查询方式

      • 通过子type查询父type,返回父type信息
        查询下单金额大于60的用户,通过 has_child 查询,返回用户信息

        GET index_test/type_info/_search
        {
        “query”: {
        “has_child”: {
        “type”: “type_order”,
        “query”: {
        “range”: {
        “amount”: {
        “gte”: 60
        }
        }
        }
        }
        }
        }

      • 通过父type查子type,返回子type信息
        查询vip等级为1的用户下的订单,通过 has_parent 查询,返回订单信息

      GET index_test/type_order/_search
      {
      “query”: {
      “has_parent”: {
      “parent_type”: “type_info”,
      “query”: {
      “term”: {
      “vipType”: {
      “value”: 1
      }
      }
      }
      }
      }
      }

    nested 和 parent-child的区别以及使用场景

    • 主要区别:
      由于存储结构的不同,nested和parent-child的方式有不同的应用场景
      nested 所有实体存储在同一个文档,parent-child模式,子type和父type存储在不同的文档里。
      所以查询效率上nested要高于parent-child,但是更新的时候nested模式下,es会删除整个文档再创建,而parent-child只会删除你更新的文档在重新创建,不影响其他文档。所以更新效率上parent-child要高于nested。

    • 使用场景:
      nested:在少量子文档,并且不会经常改变的情况下使用。
      比如:订单里面的产品,一个订单不可能会有成千上万个不同的产品,一般不会很多,并且一旦下单后,下单的产品是不可更新的。
      parent-child:在大量文档,并且会经常发生改变的情况下使用。
      比如:用户的浏览记录,浏览记录会很大,并且会频繁更新

  • 相关阅读:
    python http.server 的测试和常见问题解决方法
    联发科最先完成WiFi 7演示,速度是WiFi 6的2.4倍
    可验证随机函数(Verifiable Random Function, VRF)
    matlab图像的运算有点运算、代数运算、逻辑运算和几何运算
    mybatis-plus学习笔记
    【无标题】
    spring boot 自定义druid数据源,如何注入配置
    解决pip 安装 pyhash错误
    MapReduce和Spark读取HBase快照表
    面试官:你是怎样进行react组件代码复用的
  • 原文地址:https://blog.csdn.net/Bejpse/article/details/126358889