Elastic Search内部对象、内嵌文档、父子文档

内部对象(扁平式)


所有的信息都在一个文档中,比较高效.但是也有扁平式带来的问题,我们来试试!

//新建一个索引先,class_number是班级,student_info是学生信息,模拟一个一对多的场景
PUT flat_type
{
  "mappings": {
    "properties": {
      "class_number": {
        "type":"keyword"
      },
      "student_info":{
        "properties":{
          "student_name":{
            "type":"keyword"
          },
          "student_age":{
            "type":"keyword"
          }
        }
      }
    }
  }
}
//插入一条数据,小明(xiaoming) 红红(honghong)
POST flat_type/_doc/1
{
  "class_number": "1-1",
  "student_info": [
    {
      "student_name": "xiaoming",
      "student_age":11
    },
    {
      "student_name": "honghong",
      "student_age":10
    }
  ]
}
//查询的条件是复合条件,必须要有student_info.student_age匹配到11,student_info.student_name匹配到红红
GET flat_type/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "student_info.student_age": 11
        }},
        {"match": {
          "student_info.student_name": "honghong"
        }}
      ]
    }
  }
}

//结果集
{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.723315,
    "hits" : [
      {
        "_index" : "flat_type",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.723315,
        "_source" : {
          "class_number" : "1-1",
          "student_info" : [
            {
              "student_name" : "xiaoming",
              "student_age" : 11
            },
            {
              "student_name" : "honghong",
              "student_age" : 10
            }
          ]
        }
      }
    ]
  }
}

可以看到以上实验,他查询出了这个结果!并不是我们想要的结果!

小明应该是age11,红红应该是age10.

因为json格式的文档被处理成了扁平式的键值对的结构

student_info.student_name:["xiaoming","honghong"]
student_age.age:[11,10]

如果你的数据对于这种层级关系不敏感,可以选用这种方式

内嵌文档

我们还是用班级和学生信息当做例子来看看
内嵌文档nested的功能

//新建一个含有nested类型的索引
PUT nested_document
{
  "mappings": {
    "properties": {
      "class_number": {
        "type":"keyword"
      },
      "student_info":{
          "type": "nested"
      }
    }
  }
}
//新建文档1,班级1-1,小明(xiaoming)11岁,红红(honghong)10岁
POST nested_document/_doc/1
{
  "class_number": "1-1",
  "student_info": [
    {
      "student_name": "xiaoming",
      "student_age":11
    },
    {
      "student_name": "honghong",
      "student_age":10
    }
  ]
}
//新建文档2,班级1-2,小明12岁,红红13岁
POST nested_document/_doc/2
{
  "class_number": "1-2",
  "student_info": [
    {
      "student_name": "xiaoming",
      "student_age":12
    },
    {
      "student_name": "honghong",
      "student_age":13
    }
  ]
}
//查询会稍有变化,会多加一个nested层级
按照上面介绍的内部对象
我们的条件红红11岁是可以查出来的(因为扁平化文档对象了)
我们试试nested会不会有一样的情况
GET nested_document/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "class_number": "1-1"
          }
        },
        {
          "nested": {
            "path": "student_info",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "student_info.student_age": "11"
                    }
                  },
                  {
                    "match": {
                      "student_info.student_name": "xiaohong"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

//结果集,很显然是没有
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
//我们再来修改成对的数据查询试试
红红其实是10岁
GET nested_document/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "class_number": "1-1"
          }
        },
        {
          "nested": {
            "path": "student_info",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "student_info.student_age": "10"
                    }
                  },
                  {
                    "match": {
                      "student_info.student_name": "honghong"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

//结果集,是查出来了
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.3862944,
    "hits" : [
      {
        "_index" : "nested_document",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 2.3862944,
        "_source" : {
          "class_number" : "1-1",
          "student_info" : [
            {
              "student_name" : "xiaoming",
              "student_age" : 11
            },
            {
              "student_name" : "honghong",
              "student_age" : 10
            }
          ]
        }
      }
    ]
  }
}

nested其实在文档底层也是将nested内部的文档拆成了多份

我们可以查看一下文档的数量

GET _cat/indices/nested_document?v

//结果集
health status index           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   nested_document rBXvWV06R-ujhkz0ZCLQXg   1   1          6            0     17.8kb          8.9kb

文档数量是6,并不是2,我们再使用count看看

GET nested_document/_count
//结果集
{
  "count" : 2,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  }
}

可以看到,文档数量是2

所以真实的文档数量其实是6,es内部其实是做过join的处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值