在 Elasticsearch 中完全禁用动态映射

Disable dynamic mapping completely in Elasticsearch

我有一个索引模板,我正在从中创建索引

PUT /_index_template/example_template
{
   "index_patterns": [
        "example*"
    ],
    "priority": 1,
    "template": {
        "aliases": {
            "example":{}
        },
    "mappings": {
"dynamic":strict,
      "_source":
      {"enabled": false},
      "properties": {
       "SomeID":
        { "type": "keyword", "index" : true,"store":true,"ignore_above":5},
       "firstName":
        { "type": "text", "index" : true,"store":true},
        "lastName":
        { "type": "text", "index" : false},
        "PersonInfo": {
        "type": "object",
"dynamic":"true",
        "properties": {
          "FirstName": {
            "type": "keyword",
            "index": true,
            "store": false
          }
        }
        }
      }
    },
    "settings": {
    "index": {
      "number_of_shards": 1,  
      "number_of_replicas": 3
    }
  }
  }
}

正如在模板映射中,您可以看到我将动态设置为 Strict,这样就无法将新字段添加到映射中, 而在内部对象 PersonInfo 上,我可以将 dynamic 设置为 true,它优先并允许插入新的字段映射。

PUT example10022021/_doc/1
{
   "SomeID":"1234",
   "firstName":"Nishikant",
   "PersonInfo.service_data":"random"
}

这里 service_data 被添加到映射中,因为 dynamic 是真实的

"PersonInfo" : {
          "dynamic" : "true",
          "properties" : {
            "FirstName" : {
              "type" : "keyword"
            },
            "service_data" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }

有没有办法完全禁用动态映射?比如全局指定?

谢谢!

@Val 回答后我采取的步骤:

PUT /_index_template/example_template
{
   "index_patterns": [
        "example*"
    ],
    "priority": 1,
    "template": {
        "aliases": {
            "order":{}
        },
    "mappings": {
      "dynamic": "strict",
      "dynamic_templates": [
        {
          "objects": {
            "match_mapping_type": "object",
            "mapping": {
              "dynamic": "strict"
            }
          }
        }
      ],
      "_source":
      {"enabled": false},
      "properties": {
       "BillToID":
        { "type": "keyword", "index" : true,"store":true,"ignore_above":5},
       "firstName":
        { "type": "text", "index" : true,"store":true},
        "lastName":
        { "type": "text", "index" : false},
        "PersonInfo": {
        "type": "object",
        "dynamic":true,
        "properties": {
          "FirstName": {
            "type": "keyword",
            "index": true,
            "store": false
          }
        }
        }
      }
    },
    "settings": {
    "index": {
      "number_of_shards": 1,  
      "number_of_replicas": 3
    }
  }
  }
}

然后我创建一个索引

PUT example10022021

然后插入文档

POST example10022021/_doc/1
{
   "BillToID":"1234",
   "firstName":"Nishikant",
   "PersonInfo.service_data":"random"
}

这将导致 200OK,现在如果您再次检查映射

GET example10022021

在 o/p 中你可以看到添加了动态字段映射(我不想要这种行为),

"PersonInfo" : {
          "dynamic" : "true",
          "properties" : {
            "FirstName" : {
              "type" : "keyword"
            },
            "service_data" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        }

您可以做的是创建另一个适用于所有索引的索引模板,即使用 * 名称模式:

PUT /_index_template/common_template
{
   "index_patterns": [
        "*"
    ],
    "priority": 0,
    "template": {
       "mappings": {
         "dynamic": "strict",
         ...

如果您还想限制内部对象内部动态字段的创建,您可以利用 dynamic templates,如下所示:

PUT /_index_template/common_template
{
  "index_patterns": [
    "*"
  ],
  "priority": 1000,
  "template": {
    "settings": {},
    "mappings": {
      "dynamic": "strict",
      "dynamic_templates": [
        {
          "objects": {
            "match_mapping_type": "object",
            "mapping": {
              "dynamic": "strict"
            }
          }
        }
      ],
      "properties": {
        "test": {
          "type": "object",
          "properties": {
            "inner": {
              "type": "integer"
            }
          }
        }
      }
    }
  }
}

使用上述索引模板,您可以创建这样的文档:

POST test/_doc/
{
  "test": {
    "inner": 1
  }
}

但不像这个:

POST test/_doc/
{
  "test": {
    "inner": 1,
    "inner2": 2        <--- this will not be allowed
  }
}