subobjects编辑

在索引文档或更新映射时,Elasticsearch 接受名称中包含点的字段,这些字段将扩展为其对应的对象结构。例如,字段 metrics.time.max 被映射为一个 max 叶字段,其父对象为 time,属于其父对象 metrics

所描述的默认行为对于大多数场景来说是合理的,但在某些情况下会导致问题,例如,当字段 metrics.time 也保存一个值时,这在索引指标数据时很常见。包含 metrics.time.maxmetrics.time 值的文档会被拒绝,因为 time 需要是一个叶字段来保存值,同时也是一个对象来保存 max 子字段。

subobjects 设置只能应用于顶级映射定义和 object 字段,它禁用了对象保存更多子对象的功能,并使得存储字段名称中包含点并共享公共前缀的文档成为可能。从上面的例子来看,如果对象容器 metricssubobjects 设置为 false,它可以直接保存 timetime.max 的值,而不需要任何中间对象,因为字段名称中的点被保留了。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "metrics": {
        "type":  "object",
        "subobjects": false, 
        "properties": {
          "time": { "type": "long" },
          "time.min": { "type": "long" },
          "time.max": { "type": "long" }
        }
      }
    }
  }
}

PUT my-index-000001/_doc/metric_1
{
  "metrics.time" : 100, 
  "metrics.time.min" : 10,
  "metrics.time.max" : 900
}

PUT my-index-000001/_doc/metric_2
{
  "metrics" : {
    "time" : 100, 
    "time.min" : 10,
    "time.max" : 900
  }
}

GET my-index-000001/_mapping
{
  "my-index-000001" : {
    "mappings" : {
      "properties" : {
        "metrics" : {
          "subobjects" : false,
          "properties" : {
            "time" : {
              "type" : "long"
            },
            "time.min" : { 
              "type" : "long"
            },
            "time.max" : {
              "type" : "long"
            }
          }
        }
      }
    }
  }
}

metrics 字段不能包含其他对象。

包含扁平路径的示例文档

包含一个对象(配置为不包含子对象)及其叶节点子字段的示例文档

字段名称中的点被保留的结果映射

整个映射也可以配置为不支持子对象,在这种情况下,文档只能包含叶节点子字段

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      subobjects: false
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 'metric_1',
  body: {
    time: '100ms',
    'time.min' => '10ms',
    'time.max' => '900ms'
  }
)
puts response
PUT my-index-000001
{
  "mappings": {
    "subobjects": false 
  }
}

PUT my-index-000001/_doc/metric_1
{
  "time" : "100ms", 
  "time.min" : "10ms",
  "time.max" : "900ms"
}

整个映射被配置为不支持对象。

文档不支持对象

现有字段和顶级映射定义的 subobjects 设置不能更新。

自动扁平化对象映射编辑

通常建议使用带点的字段名称(如第一个示例所示)定义配置了 subobjects: false 的对象的属性。但是,也可以在映射中将这些属性定义为子对象。在这种情况下,映射将在存储之前自动扁平化。这使得重用现有映射变得更容易,而无需重写它们。

请注意,当在配置了 subobjects: false 的对象下定义的对象映射上设置了某些 映射参数 时,自动扁平化将不起作用。

  • enabled 映射参数不能为 false
  • dynamic 映射参数不能与父级的隐式或显式值相矛盾。例如,当在映射的根目录中将 dynamic 设置为 false 时,将 dynamic 设置为 true 的对象映射器将无法自动扁平化。
  • subobjects 映射参数不能显式设置为 true
PUT my-index-000002
{
  "mappings": {
    "properties": {
      "metrics": {
        "subobjects": false,
        "properties": {
          "time": {
            "type": "object", 
            "properties": {
              "min": { "type": "long" }, 
              "max": { "type": "long" }
            }
          }
        }
      }
    }
  }
}
GET my-index-000002/_mapping
{
  "my-index-000002" : {
    "mappings" : {
      "properties" : {
        "metrics" : {
          "subobjects" : false,
          "properties" : {
            "time.min" : { 
              "type" : "long"
            },
            "time.max" : {
              "type" : "long"
            }
          }
        }
      }
    }
  }
}

指标对象可以包含将自动扁平化的其他对象映射。此级别的对象映射不能设置某些映射参数,如上所述。

此字段将在存储映射之前自动扁平化为 "time.min"

可以通过查看索引映射来检查自动扁平化的 "time.min" 字段。