Elasticsearch教程(24) 详解mapping之object


elasticsearch支持某个字段存储一个JSON对象, 这个字段类型就是object.

1 举例: 传统数据库存对象数据

假设有一个人员信息如下:

{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

如果我们要按照普通方式:建一个字段存一个值,那么会做如下处理

字段
regionUS
managerAge30
managerFirstNameJohn
managerLastNameSmith
  • 如果我们是用MySQL创建表记录数据,的确得这么做,一个字段存一个值.
  • 但是它的缺点是字段扁平化后, 无法直观的表现原来数据的层级关系: age和name是属于manager的, first和last是属于name的.

2 ES存对象数据

ES中,一条数据都是一个JSON格式的文档,JSON格式本身就包含嵌套的层级关系.

2.1 创建mapping

PUT pigg_test_object
{
  "mappings": {
    "properties": {
      "region": {
        "type": "keyword"
      },
      "manager": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "name": {
            "properties": {
              "first": {
                "type": "keyword"
              },
              "last": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }
  }
}

上面的mapping可以看出mapping字段层级关系和数据层级关系一致

  • 一层有2个字段: region和manager
  • manager包含2个字段: age和name
  • name包含2个字段: first和last

2.2 插入数据

PUT pigg_test_object/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

在es内部,这些值其实是类似如下格式存储的

{
  "region":             "US",
  "manager.age":        30,
  "manager.name.first": "John",
  "manager.name.last":  "Smith"
}

2.3 查询object对象数据

查询嵌套的子字段时,得输入字段的全名,如manager.name.first

GET /pigg_test_object/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "region": {
              "value": "US"
            }
          }
        },
        {
          "term": {
            "manager.age": {
              "value": "30"
            }
          }
        },
        {
          "term": {
            "manager.name.first": {
              "value": "John"
            }
          }
        }
      ]
    }
  }
}

3 注意点: object类型不要存对象数组

3.1 存入对象数组

PUT pigg_test_object/_doc/1
{
    "region":"US",
    "manager":[
        {
            "age":30,
            "name":{
                "first":"John",
                "last":"Smith"
            }
        },
        {
            "age":40,
            "name":{
                "first":"Geen",
                "last":"Hank"
            }
        }
    ]
}

3.2 验证错误的查询结果

按照正常理解,下面的语句是不应该查询出来结果的

GET /pigg_test_object/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "manager.age": {
              "value": "30"
            }
          }
        },
        {
          "term": {
            "manager.name.first": {
              "value": "Geen"
            }
          }
        }
      ]
    }
  }
}

返回如下:

{
        "_index" : "pigg_test_object",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.3616575,
        "_source" : {
          "region" : "US",
          "manager" : [
            {
              "age" : 30,
              "name" : {
                "first" : "John",
                "last" : "Smith"
              }
            },
            {
              "age" : 40,
              "name" : {
                "first" : "Geen",
                "last" : "Hank"
              }
            }
          ]
        }
      }

之所以能够查询到数据是因为在es内部,数据会如下存储

{
  "region":             "US",
  "manager.age":        [30, 40],
  "manager.name.first": ["John", "Geen"],
  "manager.name.last":  ["Smith", "Hank"]
}
  • 一个object字段只能存入一个JSON对象, 不适合存对象数组
  • 如果想要一个字段存一个对象数组,可以使用nested字段类型
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为啥总是用户昵称已存在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值