Elasticsearch数据类型--object

概念介绍 

  • es中的object类型可理解为field包含field即field的分层结构。
  • 例如下面的index,在第一个层次包含了[region,manager]字段,manager内部又包含了[age,name],name本身又是一个object,包含了[first,last]。
    • 这里需要注意的是,name使用了dynamic、enabled、properties、type属性。
    • 其中,dyanmic表示此object是否可动态添加字段,当然也可以给当前索引整体设置dyanmic的值;
    • enabled表示是否此object可被索引,以作为后续检索使用;
    • properties定义了内部下一层的fields;
    • 这里需要关注的是type,type定义了此字段的数据类型,为object。manager没有使用type,是因为在这种情况下,object是默认值。
  • 如果是field的分层结构及上面的manager不必显示的指明类型为object,但是如果类型指明为其他类型,则报错
  • 这里要注意,manager作为外层的object,它的enabled属性不能设置为false,否则对于其内部的name  object,即使其enabled设置为true,也不能被query检索到。

#manager没有显示的指明类型为object

PUT test_object
{"mappings": {
  "properties": {
    "region":{
      "type": "keyword"
    },
    "manager":{
      "dynamic":true,
      "enabled":true,
      "properties": {
        "age":{
          "type":"integer"
        },
        "name":{
          "dynamic":false,
          "enabled":true,
          "type":"object",
          "properties":{
            "first":{
              "type":"keyword"
            },
            "last":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}} 

  •  es的底层是lucene,lucene是不识别object对象的,因此,在内部,object对象数据,是按照分层平展开来的

 {
  region,
  manager.age,
  manager.name.first,
  manager,name,last
}

  •  这样带来一个问题:作为一个整体存在的object,不能被作为整体单独检索

 POST test_object/_doc
{
  "region" : "region1",
  "manager" : [ 
    {
      "age":23,
      "name":[
        {
          "first" : "John",
          "last" :  "Smith"
        }
      ]
    },
    {
      "age":23,
      "name":[
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
  ]
}

//结构

{
  "region":"region1"
  "manager.age":[23,23]
  "manager.name.first":["John","Alice"]
  "manager.name.last":["Smith","White"]
}

  • 如果我们要检索一个document,它需要满足这样的条件:first name = Alice ,并且last name = Smith:

//结构

{
  "region":"region1"
  "manager.age":[23,23]
  "manager.name.first":["John","Alice"]
  "manager.name.last":["Smith","White"]
}

GET test_object/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "manager.name.first": "Alice" }},
        { "match": { "manager.name.last":  "Smith" }}
      ]
    }
  }
}

  • 从我们上面的数据来看,Alice与White为一个name object,John与Smith为一个name object。正常的话,是不能检索出来的,但是上面这个query却查询出了结果。原因就在于,在es(lucene)内部,这个数据是按照类似上述的方式展开存储的

 解决这个问题,就需要用到nested数据类型

 dyanmic作用介绍

  • manager的dyanmic设为true
  • name的设为true

PUT test_object
{"mappings": {
  "properties": {
    "region":{
      "type": "keyword"
    },
    "manager":{
      "dynamic":true,
      "enabled":true,
      "properties": {
        "age":{
          "type":"integer"
        },
        "name":{
          "dynamic":true,
          "enabled":true,
          "type":"object",
          "properties":{
            "first":{
              "type":"keyword"
            },
            "last":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}}

//新增mapping中不存在的字段

POST test_object/_doc/1
{
  "region" : "region1",
  "manager" : [ 
    {
      "age":23,
      "name":[
        {
          "first" : "John",
          "last" :  "Smith",
          "test_name":"test_name"
        }
      ],
      "test_manager":"test_manager"
    },
    {
      "age":23,
      "name":[
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
  ]
}

//查看mapping文件,为新添加的字段设置了mapping映射(一般情况下不建议开启)

{
  "test_object" : {
    "mappings" : {
      "properties" : {
        "manager" : {
          "dynamic" : "true",
          "properties" : {
            "age" : {
              "type" : "integer"
            },
            "name" : {
              "dynamic" : "true",
              "properties" : {
                "first" : {
                  "type" : "keyword"
                },
                "last" : {
                  "type" : "keyword"
                },
                "test_name" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                }
              }
            },
            "test_manager" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        },
        "region" : {
          "type" : "keyword"
        }
      }
    }
  }
}

//manager和name的dyanmic设为strict

PUT test_object
{"mappings": {
  "properties": {
    "region":{
      "type": "keyword"
    },
    "manager":{
      "dynamic":"strict",
      "enabled":true,
      "properties": {
        "age":{
          "type":"integer"
        },
        "name":{
          "dynamic":"strict",
          "enabled":true,
          "type":"object",
          "properties":{
            "first":{
              "type":"keyword"
            },
            "last":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}}

//再次添加上述文档,错误提示

{
  "error" : {
    "root_cause" : [
      {
        "type" : "strict_dynamic_mapping_exception",
        "reason" : "mapping set to strict, dynamic introduction of [test_name] within [manager.name] is not allowed"
      }
    ],
    "type" : "strict_dynamic_mapping_exception",
    "reason" : "mapping set to strict, dynamic introduction of [test_name] within [manager.name] is not allowed"
  },
  "status" : 400
}

//也可以整体设置

PUT /test_object/_mapping
{
  "dynamic":"strict"
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值