透传对象字段类型

编辑

透传对象扩展了对象的功能,允许在不包含透传对象名称作为前缀的情况下访问其子字段。例如:

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "attributes": {
                "type": "passthrough",
                "priority": 10,
                "properties": {
                    "id": {
                        "type": "keyword"
                    }
                }
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "attributes": {
            "id": "foo",
            "zone": 10
        }
    },
)
print(resp1)

resp2 = client.search(
    index="my-index-000001",
    query={
        "bool": {
            "must": [
                {
                    "match": {
                        "id": "foo"
                    }
                },
                {
                    "match": {
                        "zone": 10
                    }
                }
            ]
        }
    },
)
print(resp2)

resp3 = client.search(
    index="my-index-000001",
    query={
        "bool": {
            "must": [
                {
                    "match": {
                        "attributes.id": "foo"
                    }
                },
                {
                    "match": {
                        "attributes.zone": 10
                    }
                }
            ]
        }
    },
)
print(resp3)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      attributes: {
        type: "passthrough",
        priority: 10,
        properties: {
          id: {
            type: "keyword",
          },
        },
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    attributes: {
      id: "foo",
      zone: 10,
    },
  },
});
console.log(response1);

const response2 = await client.search({
  index: "my-index-000001",
  query: {
    bool: {
      must: [
        {
          match: {
            id: "foo",
          },
        },
        {
          match: {
            zone: 10,
          },
        },
      ],
    },
  },
});
console.log(response2);

const response3 = await client.search({
  index: "my-index-000001",
  query: {
    bool: {
      must: [
        {
          match: {
            "attributes.id": "foo",
          },
        },
        {
          match: {
            "attributes.zone": 10,
          },
        },
      ],
    },
  },
});
console.log(response3);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "attributes": {
        "type": "passthrough", 
        "priority": 10,
        "properties": {
          "id": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "attributes" : {  
    "id": "foo",
    "zone": 10
  }
}

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "id": "foo" }},  
        { "match": { "zone": 10 }}
      ]
    }
  }
}

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "attributes.id": "foo" }}, 
        { "match": { "attributes.zone": 10 }}
      ]
    }
  }
}

一个对象被定义为透传对象。其优先级(必需)用于冲突解决。

对象内容像往常一样被索引,包括动态映射。

子字段可以在查询中被引用,就像它们被定义在根级别一样。

子字段也可以通过包含对象名称作为前缀来引用。

冲突解决

编辑

在不同的作用域中定义的字段可能会出现冲突的名称,例如:

  1. 一个透传对象被定义在与透传对象子字段之一同名的字段旁边,例如:

    resp = client.index(
        index="my-index-000001",
        id="1",
        document={
            "attributes": {
                "id": "foo"
            },
            "id": "bar"
        },
    )
    print(resp)
    const response = await client.index({
      index: "my-index-000001",
      id: 1,
      document: {
        attributes: {
          id: "foo",
        },
        id: "bar",
      },
    });
    console.log(response);
    PUT my-index-000001/_doc/1
    {
      "attributes" : {
        "id": "foo"
      },
      "id": "bar"
    }

    在这种情况下,对 id 的引用指向根级别的字段,而字段 attributes.id 只能使用完整路径访问。

  2. 两个(或多个)透传对象在同一对象内定义,并且包含相同名称的字段,例如:

    resp = client.indices.create(
        index="my-index-000002",
        mappings={
            "properties": {
                "attributes": {
                    "type": "passthrough",
                    "priority": 10,
                    "properties": {
                        "id": {
                            "type": "keyword"
                        }
                    }
                },
                "resource.attributes": {
                    "type": "passthrough",
                    "priority": 20,
                    "properties": {
                        "id": {
                            "type": "keyword"
                        }
                    }
                }
            }
        },
    )
    print(resp)
    const response = await client.indices.create({
      index: "my-index-000002",
      mappings: {
        properties: {
          attributes: {
            type: "passthrough",
            priority: 10,
            properties: {
              id: {
                type: "keyword",
              },
            },
          },
          "resource.attributes": {
            type: "passthrough",
            priority: 20,
            properties: {
              id: {
                type: "keyword",
              },
            },
          },
        },
      },
    });
    console.log(response);
    PUT my-index-000002
    {
      "mappings": {
        "properties": {
          "attributes": {
            "type": "passthrough",
            "priority": 10,
            "properties": {
              "id": {
                "type": "keyword"
              }
            }
          },
          "resource.attributes": {
            "type": "passthrough",
            "priority": 20,
            "properties": {
              "id": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }

    在这种情况下,参数 priority 用于冲突解决,较高的值具有优先权。在上面的示例中,resource.attributes 的优先级高于 attributes,因此对 id 的引用指向 resource.attributes 中的字段。attributes.id 仍然可以使用其完整路径访问。

将子字段定义为时间序列维度

编辑

可以将透传字段配置为 时间序列维度 的容器。在这种情况下,所有子字段都会在底层使用相同的参数进行注释,并且它们也会被包含在路由路径tsid 计算中,从而简化了 TSDS 的设置。

resp = client.indices.put_index_template(
    name="my-metrics",
    index_patterns=[
        "metrics-mymetrics-*"
    ],
    priority=200,
    data_stream={},
    template={
        "settings": {
            "index.mode": "time_series"
        },
        "mappings": {
            "properties": {
                "attributes": {
                    "type": "passthrough",
                    "priority": 10,
                    "time_series_dimension": True,
                    "properties": {
                        "host.name": {
                            "type": "keyword"
                        }
                    }
                },
                "cpu": {
                    "type": "integer",
                    "time_series_metric": "counter"
                }
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="metrics-mymetrics-test",
    document={
        "@timestamp": "2020-01-01T00:00:00.000Z",
        "attributes": {
            "host.name": "foo",
            "zone": "bar"
        },
        "cpu": 10
    },
)
print(resp1)
const response = await client.indices.putIndexTemplate({
  name: "my-metrics",
  index_patterns: ["metrics-mymetrics-*"],
  priority: 200,
  data_stream: {},
  template: {
    settings: {
      "index.mode": "time_series",
    },
    mappings: {
      properties: {
        attributes: {
          type: "passthrough",
          priority: 10,
          time_series_dimension: true,
          properties: {
            "host.name": {
              type: "keyword",
            },
          },
        },
        cpu: {
          type: "integer",
          time_series_metric: "counter",
        },
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "metrics-mymetrics-test",
  document: {
    "@timestamp": "2020-01-01T00:00:00.000Z",
    attributes: {
      "host.name": "foo",
      zone: "bar",
    },
    cpu: 10,
  },
});
console.log(response1);
PUT _index_template/my-metrics
{
  "index_patterns": ["metrics-mymetrics-*"],
  "priority": 200,
  "data_stream": { },
  "template": {
    "settings": {
      "index.mode": "time_series"
    },
    "mappings": {
      "properties": {
        "attributes": {
          "type": "passthrough",
          "priority": 10,
          "time_series_dimension": true,
          "properties": {
            "host.name": {
              "type": "keyword"
            }
          }
        },
        "cpu": {
          "type": "integer",
          "time_series_metric": "counter"
        }
      }
    }
  }
}

POST metrics-mymetrics-test/_doc
{
  "@timestamp": "2020-01-01T00:00:00.000Z",
  "attributes" : {
    "host.name": "foo",
    "zone": "bar"
  },
  "cpu": 10
}

在上面的示例中,attributes 被定义为维度容器。其子字段 host.name (静态) 和 zone (动态) 被包含在路由路径和 tsid 中,并且可以在查询中引用,而无需 attributes. 前缀。

子字段自动扁平化

编辑

透传字段默认情况下会对子字段应用自动扁平化,以减少动态映射冲突。因此,不允许在透传字段中定义子对象。

passthrough 字段的参数

编辑

passthrough 字段接受以下参数:

priority

(必需)用于解决透传字段之间的命名冲突。值最高的字段获胜。接受非负整数值。

time_series_dimension

是否将子字段视为时间序列维度。接受 false (默认) 或 true

dynamic

是否应将新的 properties 动态添加到现有对象。接受 true (默认)、runtimefalsestrict

enabled

是否应该解析并索引为对象字段给定的 JSON 值(true,默认)或完全忽略(false)。

properties

对象中的字段,可以是任何数据类型,包括 object。可以将新属性添加到现有对象。

如果您需要索引对象数组而不是单个对象,请先阅读嵌套