【问题标题】:Disable dynamic mapping creation for only specific indexes on elasticsearch?仅针对弹性搜索上的特定索引禁用动态映射创建?
【发布时间】:2016-01-20 16:59:00
【问题描述】:

我正在尝试仅为特定索引禁用动态映射创建,而不是全部禁用。出于某种原因,我不能将 default 映射与“动态”:“假”。 所以,这里留下了两个选项,我可以看到:

  1. 在文件 elasticsearch.yml 中指定属性 'index.mapper.dynamic'
  2. 'index.mapper.dynamic' 放在索引创建时,如此处所述https://www.elastic.co/guide/en/kibana/current/setup.html#kibana-dynamic-mapping

第一个选项只能接受值:true、false 和 strict。所以没有办法指定特定索引的子集(就像我们通过带有属性 'action.auto_create_index' https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-creation 的模式所做的那样)。

第二个选项不起作用。 我已经创建了索引

POST http://localhost:9200/test_idx/
{
    "settings" : {
        "mapper" : {
            "dynamic" : false
        }
    },
    "mappings" : {
        "test_type" : {
            "properties" : {
                "field1" : {
                    "type" : "string"
                }
            }
        }
    }
}

然后检查索引设置:

GET http://localhost:9200/test_idx/_settings    
{
    "test_idx" : {
        "settings" : {
            "index" : {
                "mapper" : {
                    "dynamic" : "false"
                },
                "creation_date" : "1445440252221",
                "number_of_shards" : "1",
                "number_of_replicas" : "0",
                "version" : {
                    "created" : "1050299"
                },
                "uuid" : "5QSYSYoORNqCXtdYn51XfA"
            }
        }
    }
}

和映射:

GET http://localhost:9200/test_idx/_mapping
{
    "test_idx" : {
        "mappings" : {
            "test_type" : {
                "properties" : {
                    "field1" : {
                        "type" : "string"
                    }
                }
            }
        }
    }
}

到目前为止一切顺利,让我们用未声明的字段索引文档:

POST http://localhost:9200/test_idx/test_type/1
{
    "field1" : "it's ok, field must be in mapping and in source",
    "somefield" : "but this field must be in source only, not in mapping"
}

然后我再次检查了映射:

GET http://localhost:9200/test_idx/_mapping
{
    "test_idx" : {
        "mappings" : {
            "test_type" : {
                "properties" : {
                    "field1" : {
                        "type" : "string"
                    },
                    "somefield" : {
                        "type" : "string"
                    }
                }
            }
        }
    }
}

如您所见,无论索引设置如何,映射都会扩展“动态”:false。 我还尝试完全按照文档中的描述创建索引

PUT http://localhost:9200/test_idx
{
    "index.mapper.dynamic": false
}

但行为相同。

也许我错过了什么?

提前非常感谢!

【问题讨论】:

  • 抱歉,忘记版本了,我正在使用 elastic 1.5.2。
  • 查看答案的最后一条评论,实际上是答案
  • "settings.mapper.dynamic": false 禁用自动类型创建

标签: elasticsearch


【解决方案1】:

您快到了:需要将值设置为strict。 而正确的用法如下:

PUT /test_idx
{
  "mappings": {
    "test_type": {
      "dynamic":"strict",
      "properties": {
        "field1": {
          "type": "string"
        }
      }
    }
  }
}

再进一步,如果您想禁止创建新类型,而不仅仅是该索引中的字段,请使用:

PUT /test_idx
{
  "mappings": {
    "_default_": {
      "dynamic": "strict"
    },
    "test_type": {
      "properties": {
        "field1": {
          "type": "string"
        }
      }
    }
  }
}

没有_default_模板:

PUT /test_idx
{
  "settings": {
    "index.mapper.dynamic": false
  },
  "mappings": {
    "test_type": {
      "dynamic": "strict",
      "properties": {
        "field1": {
          "type": "string"
        }
      }
    }
  }
}

【讨论】:

  • 感谢您的回答。不幸的是,我必须禁用整个索引(索引级别)的动态映射创建。在您的示例中,它仅针对类型“test_type”被禁用。而且我不能为此使用'default'映射(正如我在开始时所说的那样)
  • 需要使用_default_ 映射来禁用字段/类型的索引级创建。
  • 不幸的是我不能把_default_映射。我试图了解如何在不放置任何映射的情况下禁用动态映射创建(从 API 的角度来看,通过放置其他映射来禁用动态映射有点棘手,恕我直言)
  • 是的,有办法。请参阅我上次尝试使用 settings"dynamic": "strict" 进行单一类型的映射。
  • 不,有两个单独的设置。索引级别一和映射级别一。这来自文档:可以通过将 index.mapper.dynamic 设置为 false 来完全禁用未映射类型的映射的动态创建。通过将类型的动态属性设置为严格,可以完全禁用类型中字段的动态创建。 索引级别设置用于创建新映射(用于新类型)。类型级别 1 用于该特定类型中的字段。 index.mapper.dynamic 不会继承到新类型,因为类型级别设置不同。
【解决方案2】:

你必须知道,下面这部分只是意味着 ES 不能动态创建类型。

"mapper" : {
        "dynamic" : false
    }

你应该像这样配置 ES:

PUT http://localhost:9200/test_idx/_mapping/test_type
{
  "dynamic":"strict"
}

那么你不能索引其他没有映射的字段,并得到如下错误:

mapping set to strict, dynamic introduction of [hatae] within [data] is not allowed

如果你想存储数据,但是字段不能被索引,你可以这样设置:

PUT http://localhost:9200/test_idx/_mapping/test_type
{
  "dynamic":false
}

希望这些可以帮助有同样问题的人:)。

【讨论】:

    【解决方案3】:

    答案在文档中 (7x.):https://www.elastic.co/guide/en/elasticsearch/reference/7.x/dynamic.html

    动态设置控制是否可以添加新字段 动态与否。它接受三种设置:

    新检测到的字段将添加到映射中。 (默认)

    新检测到的字段将被忽略。这些字段不会被索引,所以 将不可搜索,但仍会出现在 _source 字段中 返回点击量。这些字段不会添加到映射中,新 字段必须显式添加。

    严格

    如果检测到新字段,则抛出异常并且文档被 被拒绝。新字段必须显式添加到映射中。

    PUT my_index
    {
      "mappings": {
        "dynamic": "strict", 
        "properties": {
          "user": { 
            "properties": {
              "name": {
                "type": "text"
              },
              "social_networks": { 
                "dynamic": true,
                "properties": {}
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 所以这只有在创建索引时才有可能?
    • 好吧,据我所知,您可以这样做作为更新:不仅在创建期间,而且在创建之后。
    【解决方案4】:

    你不能再在 ES 7 中禁用动态映射,如果你有完全非结构化的数据,你可以做的是完全禁用索引的映射,如下所示:

    curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'
    {
      "mappings": {
        "enabled": false 
      }
    }
    '
    

    如果你使用 python,你可以这样做:

    from elasticsearch import Elasticsearch
    
    # Connect to the elastic cluster
    es=Elasticsearch([{'host':'localhost','port':9200}])
    
    request_body = {
            "mappings": {
                     "enabled": False
        }
    }
    es.indices.create(index = 'my_index', body = request_body)
    

    【讨论】:

    • 我不知道您使用的是哪个版本,但它似乎在 7.x(至少 7.6.0)中运行良好。
    • 我使用的是 7.4 版本,我不得不完全禁用映射,因为每个对象都有不同的结构
    • 我对此投了反对票,因为答案不准确,可能会误导其他人。正如 avetisk 的回答,这在 7.x 中仍然是可能的(我已经测试了 7.7.0)并且文档仍然显示它是受支持的。唯一改变的是类型的删除,所以选项现在直接在“映射”下。
    【解决方案5】:

    对于 ES 7,如果要更新现有索引:

    PUT customers/_mapping
    {
      "dynamic": "strict"
    }
    

    【讨论】:

      【解决方案6】:

      首先,请注意值 falsestrict,它们的工作方式不同。

      使用 "dynamic": "false" 并使用映射未涵盖的字段创建文档,这些字段将被忽略(因此它们不会被存储)并且不会在您获取文档时显示在 _source 中。

      其中值 strict 将不允许您创建文档,而是会引发异常

      内部对象从其父对象或映射类型继承动态设置。在以下示例中,在类型级别禁用了动态映射,因此不会动态添加新的顶级字段。

      不过,user.social_networks 对象启用动态映射,因此您可以向该内部对象添加字段。

      https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic.html

      PUT my-index-000001
      {
        "mappings": {
          "dynamic": false, 
          "properties": {
            "user": { 
              "properties": {
                "name": {
                  "type": "text"
                },
                "social_networks": {
                  "dynamic": true, 
                  "properties": {}
                }
              }
            }
          }
        }
      }
      

      如果您使用的是 node.js 客户端

          await this.client.indices.putMapping({
            index: ElasticIndex.UserDataFactory,
            body: {
              dynamic: 'strict',
              properties: {
                ...this.schema,
              },
            },
          });
      

      【讨论】:

        猜你喜欢
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        • 2020-06-28
        • 1970-01-01
        • 2016-06-20
        相关资源
        最近更新 更多