• 【Elasticsearch教程12】Mapping字段类型之object



    首先给出结论:

    • 在一个字段存储一个JSON对象,可以选择object类型
    • 在一个字段存储多个JSON对象,可以选择nested类型

    一、传统数据库存object

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

    { 
      "region": "US",
      "manager": { 
        "age":     30,
        "name": { 
          "first": "John",
          "last":  "Smith"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    建表时会建一个字段存一个值,它的缺点是字段扁平化, 无法直观的表现层级关系

    字段
    regionUS
    manager_age30
    manager_firstnameJohn
    manager_lastnameSmith

    二、ES存object

    ES中,一个字段存的就是一个JSON,JSON格式本身就包含嵌套的层级关系。

    2.1 创建mapping

    • 一层有2个字段:regionmanager
    • manager包含2个字段: agename
    • name包含2个字段:firstlast
    PUT pigg_test_object
    {
      "mappings": {
        "properties": {
          "region": {
            "type": "keyword"
          },
          "manager": {
            "properties": {
              "age": {
                "type": "integer"
              },
              "name": {
                "properties": {
                  "first": {
                    "type": "keyword"
                  },
                  "last": {
                    "type": "keyword"
                  }
                }
              }
            }
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.2 插入数据

    PUT pigg_test_object/_doc/1
    { 
      "region": "US",
      "manager": { 
        "age":     30,
        "name": { 
          "first": "John",
          "last":  "Smith"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在ES内部,这些值其实是按如下格式存储的

    {
      "region":             "US",
      "manager.age":        30,
      "manager.name.first": "John",
      "manager.name.last":  "Smith"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3 查询object数据

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

    GET /pigg_test_object/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "manager.name.first": {
                  "value": "John"
                }
              }
            }
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    三、object不要存数组

    3.1 存入object数组

    • 30岁的John Smith
    • 40岁的Geen Hank
    PUT pigg_test_object/_doc/1
    {
        "region":"US",
        "manager":[
            {
                "age":30,
                "name":{
                    "first":"John",
                    "last":"Smith"
                }
            },
            {
                "age":40,
                "name":{
                    "first":"Geen",
                    "last":"Hank"
                }
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.2 验证错误的查询结果

    查询30岁的Geen按照正常理解,是不应该查询出来结果的,但是它能返回数据

    GET /pigg_test_object/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "manager.age": {
                  "value": "30"
                }
              }
            },
            {
              "term": {
                "manager.name.first": {
                  "value": "Geen"
                }
              }
            }
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这是因为在ES内部,数据会如下格式存储

    {
      "region":             "US",
      "manager.age":        [30, 40],
      "manager.name.first": ["John", "Geen"],
      "manager.name.last":  ["Smith", "Hank"]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这样的存储方式没有把2个人信息分开存储,而是混合在一起,所以有了文章开头的结论:

    • 在一个字段存储一个JSON对象,可以选择object类型
    • 在一个字段存储多个JSON对象,可以选择nested类型

    四、object的参数enabled

    • enabled参数只用于object类型,默认值是true(开启)
    • 为true时,ES会object里的所有字段进行索引操作, 这样就可以根据该字段检索文档
    • 为false时,ES不去解析object里的字段,不会索引每个字段
    • 当只需要返回该字段用于展示,而不需要索引某个字段时(例如session信息,我们很少用session作为查询条件),可设置enabled=false

    实验如下:

    PUT pigg_test_enabled
    {
      "mappings": {
        "properties": {
          "name": {"enabled": false}
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    插入多种格式的值

    PUT pigg_test_enabled/_doc/1
    {
      "name": "winter"
    }
    
    PUT pigg_test_enabled/_doc/2
    {
      "name": {
        "first_name": "wang",
        "last_name": "dong"
      }
    }
    
    GET pigg_test_enabled/_search
    
    返回发现: 不同的值都可以存入
     "hits" : [
          {
            "_index" : "pigg_test_enabled",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "winter"
            }
          },
          {
            "_index" : "pigg_test_enabled",
            "_type" : "_doc",
            "_id" : "2",
            "_score" : 1.0,
            "_source" : {
              "name" : {
                "first_name" : "wang",
                "last_name" : "dong"
              }
            }
          }
        ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    查看mapping

    GET pigg_test_enabled/_mapping
    
    返回如下: name类型是object, 并不会解析name在其下面添加first_name和last_name子字段
    {
      "pigg_test_enabled" : {
        "mappings" : {
          "properties" : {
            "name" : {
              "type" : "object",
              "enabled" : false
            }
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在enable=false的字段上检索文档, 是查询不到数据的

    GET pigg_test_enabled/_search
    {
      "query": {
        "term": {
          "name": {
            "value": "winter"
          }
        }
      }
    }
    
    返回没有数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    下一篇博客会详细讲解nested类型,如果本文对您有帮助,就给亚瑟王点个赞👍吧。

  • 相关阅读:
    unity shader用渲染纹理实现镜子效果
    Java:Java中的堆栈和堆内存
    easyExcel 简单使用 和遇到的坑
    微秒级 TCP 时间戳
    python机器人编程——差速机器人小车的控制,控制模型、轨迹跟踪,轨迹规划、自动泊车(上)
    数字信号处理-2-三角函数与谱
    python OS模块
    vue 项目 前端 模拟后端接口数据(vue2,vue3)
    WebRTC源码之摄像头视频数据采集源码分析
    易云维®智慧工厂数字化管理平台助推工业制造企业数字化转型新动能
  • 原文地址:https://blog.csdn.net/winterking3/article/details/126616092