elasticsearch简介
elasticsearch一直以来受大众青睐,特别适用于大数据量、高频繁查询的业务逻辑。大家都知道ES的数据是以文档的形式保存的,在保存数据的时候ES的分词系统会将我们的数据通过倒排索引进行处理,以便于我们后续高效的查询。

多个实体对象关联
在实际业务过程中我们的各个实体对象都相互关联,那么在ES的世界里我们如何处理这些关联关系呢?ES中一般有普通文档、嵌套文档、父子文档,这些文档都能满足父子对象的关系。但是,普通一对多文档有子对象边界值问题,嵌套文档修改父文档必须修改整个文档,父子文档则可以任意修改文档且不影响其他关系文档。今天我们就来看看ES的父子文档。

什么是父子文档
父子文档就是将父文档和子文档关联起来,就如同关系数据库里面 join 一样。父子文档都绑定在同一个索引上,但是分属于两个独立的文档。

优势与劣势
优点:
1、父子文档相互独立
2、修改父文档索引不影响子文档;增删改任意的子文档,父文档和其他子文档不受影响
3、子文档可以从属于多个父文档

缺点:
1、索引结构复杂,封装操作脚本难度较大
2、为保证父子文档被分配到同一个分片,新增子文档必须添加和父文档一致的路由

小试牛刀
比如我们产品下有多个渠道
1、定义如下父子文档索引:
这里用到了 joinFiled 自定义字段进行过滤,此字段我们创建索引时可以自由声明,当前里面的父子文档标识( “product”: “channel”)也是自由声明。

PUT product

PUT product/_mapping
{
  "properties":{
    "name": {
      "type":"keyword"
    },
    "productId": {
      "type":"integer"
    },
    "joinFiled":{
      "type":"join",
      "relations":{
        "product": "channel"
      }
    }
  }
}

2、查看索引结构

GET product

es agg nested 父文档数 es子文档查询_es agg nested 父文档数

3、新增父文档数据

#新增父文档
PUT product/_doc/11001
{
  "name":"产品1",
  "productId":11001,
  "joinFiled":{
    "name": "product"
  }
}

4、新增子文档,注意路由取父文档id保证父子文档在同片。

#新增子文档
PUT product/_doc/12001?routing=11001
{
  "name":"渠道1",
  "joinFiled":{
    "name": "channel",
    "parent": 11001
  }
}

“parent”: 11001 >> 将渠道子文档与产品父文档关联起来。
实际业务中一般子文档保存有父文档的id,那么这个父id就是关联的关键。

5、查询文档数量确定父子文档是否独立

#查询文档数据
GET product/_search
{
  
}

es agg nested 父文档数 es子文档查询_elasticsearch_02

6、根据父文档查询子文档,

#根据子父档查询子文档
GET product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "joinFiled": {
              "value": "channel"
            }
          }
        },{
          "has_parent": {
            "parent_type": "product",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "name": {
                        "value": "产品1"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

es agg nested 父文档数 es子文档查询_数据_03

7、根据子文档查询父文档

#根据子文档查询父文档
GET product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "joinFiled": {
              "value": "product"
            }
          }
        },{
          "has_child": {
            "type": "channel",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "name": {
                        "value": "渠道1"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

es agg nested 父文档数 es子文档查询_es agg nested 父文档数_04

父子文档是将两个独立的文档关联起来,操作父子文档关系不会影响其他文档。父子文档关联是在创建索引时进行申明,他们同属于同一个索引却不是同一个文档。