Elasticsearch教程(25) 详解mapping之nested

1 前言

在工作开发中, 我们常遇到2张表示1对多的关系,这样的父子结构, 如果用MySQL存的话,子表设一个字段parentId存储父表的id,这样就可以用join关联查询.
那么ES作为NoSQL,它有更便捷的存储方式来保存父子结构:

  • 第一种:join字段类型,子文档包含父文档ID,可用has_parent和has_child来查询
  • 第二种:nested字段类型,子文档就存在父文档某个字段内部,适合子文档数量较少的情况

在上一篇Elasticsearch笔记(二十六) 详解mapping之object中介绍了object存储对象数组的缺陷, 如果要存对象数组, 并且对数组中每一个对象进行单独查询, 用nested类型比较合适.
但是nested类型适合子文档数量较少情况,有es有如下默认设置

  • 一个文档最多有50个nested类型的字段
  • 一个文档所有nested类型的字段存储文档最大数量是10000条

如果用elasticsearch存树形结构,可以参考Elasticsearch笔记(十三) ES 存储树形结构 整合Spring Data Elasticsearch

更多nested详解参考知名大佬博客干货 | Elasticsearch Nested类型深入详解

2 创建nested字段的mapping

创建一个文档,存储班级, student里存储该班级的学生信息

PUT /pigg_test_nested

PUT /pigg_test_nested/_mapping/
{
    
    
    "properties":{
    
    
        "class":{
    
    
            "type":"keyword"
        },
        "student":{
    
    
            "type":"nested",
            "properties":{
    
    
                "name":{
    
    
                    "type":"keyword"
                },
                "sex":{
    
    
                    "type":"keyword"
                },
                "age": {
    
    
                    "type":"integer"
                }
            }
        }
    }
}

3 插入测试数据

PUT pigg_test_nested/_doc/1
{
    
    
    "class":"高三(1)班",
    "student":[
        {
    
    
            "name":"亚瑟王",
            "sex":"男",
            "age":18
        },
        {
    
    
            "name":"程咬金",
            "sex":"男",
            "age":18
        },
        {
    
    
            "name":"扁鹊",
            "sex":"男",
            "age":20
        },
        {
    
    
            "name":"安其拉",
            "sex":"女",
            "age":18
        }
    ]
}

PUT pigg_test_nested/_doc/2
{
    
    
    "class":"高三(2)班",
    "student":[
        {
    
    
            "name":"老夫子",
            "sex":"男",
            "age":20
        },
        {
    
    
            "name":"凯爹",
            "sex":"男",
            "age":19
        },
        {
    
    
            "name":"小乔",
            "sex":"女",
            "age":16
        },
        {
    
    
            "name":"大乔",
            "sex":"女",
            "age":18
        }
    ]
}

4 nested查询

GET /pigg_test_nested/_search
{
    
    
  "query": {
    
    
    "nested": {
    
    
      "path": "student",
      "query": {
    
    
        "bool": {
    
    
          "must": [
            {
    
    
              "term": {
    
    
                "student.age": {
    
    
                  "value": "18"
                }
              }
            },
            {
    
    
              "term": {
    
    
                "student.sex": {
    
    
                  "value": "女"
                }
              }
            }
          ]
        }
      }
    }
  }
}

返回如下:

{
    
    
        "_index" : "pigg_test_nested",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.5447271,
        "_source" : {
    
    
          "class" : "高三(1)班",
          "student" : [
            {
    
    
              "name" : "亚瑟王",
              "sex" : "男",
              "age" : 18
            },
            {
    
    
              "name" : "程咬金",
              "sex" : "男",
              "age" : 18
            },
            {
    
    
              "name" : "扁鹊",
              "sex" : "男",
              "age" : 20
            },
            {
    
    
              "name" : "安其拉",
              "sex" : "女",
              "age" : 18
            }
          ]
        }
      }

如果查询女的亚瑟王,则返回没有数据,这个和object类型是有区别的,

GET /pigg_test_nested/_search
{
    
    
  "query": {
    
    
    "nested": {
    
    
      "path": "student",
      "query": {
    
    
        "bool": {
    
    
          "must": [
            {
    
    
              "term": {
    
    
                "student.name": {
    
    
                  "value": "亚瑟王"
                }
              }
            },
            {
    
    
              "term": {
    
    
                "student.sex": {
    
    
                  "value": "女"
                }
              }
            }
          ]
        }
      }
    }
  }
}

5 nested聚合分析

统计每个班级各自的性别数量

GET pigg_test_nested/_search
{
    
    
  "aggs": {
    
    
    "group_by_class": {
    
    
      "terms": {
    
    
        "field": "class",
        "size": 10
      },
      "aggs": {
    
    
        "count_by_sex": {
    
    
          "nested": {
    
    
            "path": "student"
          },
          "aggs": {
    
    
            "group_by_sex": {
    
    
              "terms": {
    
    
                "field": "student.sex",
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}

返回如下:

"aggregations" : {
    
    
    "group_by_class" : {
    
    
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
    
    
          "key" : "高三(1)班",
          "doc_count" : 1,
          "count_by_sex" : {
    
    
            "doc_count" : 4,
            "group_by_sex" : {
    
    
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
    
    
                  "key" : "男",
                  "doc_count" : 3
                },
                {
    
    
                  "key" : "女",
                  "doc_count" : 1
                }
              ]
            }
          }
        },
        {
    
    
          "key" : "高三(2)班",
          "doc_count" : 1,
          "count_by_sex" : {
    
    
            "doc_count" : 4,
            "group_by_sex" : {
    
    
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
    
    
                  "key" : "女",
                  "doc_count" : 2
                },
                {
    
    
                  "key" : "男",
                  "doc_count" : 2
                }
              ]
            }
          }
        }
      ]
    }
  }

猜你喜欢

转载自blog.csdn.net/winterking3/article/details/108513261