【问题标题】:Elasticsearch default mappingElasticsearch 默认映射
【发布时间】:2015-05-19 16:58:35
【问题描述】:

我目前的理解-

  1. Elasticsearch 在第一次接收 JSON 数据集时创建映射索引。
  2. 此映射无法更改,但可以重新映射数据集。

问题-

忘记重新映射。有什么方法可以告诉 ES 默认行为 作为-

"Consider everything that is not a date to be of string type"?

另外,如果我这样做,我会损失很多吗?

更新-

我添加了文件-config/mappings/_default/mapping.json,内容如下-

{
    "dynamic_templates": [
        {
            "template_1": {
                "match": "*",
                "match_mapping_type": "int",
                "mapping": {
                    "type": "string"
                }
            },
            "template_2": {
                "match": "*",
                "match_mapping_type": "long",
                "mapping": {
                    "type": "string"
                }
            }
        }
    ]
}

我还尝试将以下内容放在-config/default_mapping.json

{
    "_default_" : {
        "match": "*",
        "match_mapping_type": "int",
        "mapping": {
                "type": "string"
        }
    }
}

我的“动机”是消除在 intlong 类型更改为 string 时出现的错误。此映射 all intlong 值是否会在将来创建的所有索引中映射为 string?我需要在_all 中嵌套这个dynamic_templates 键吗?

更新二-

添加这个映射文件会导致 elasticsearch 崩溃-

[2014-02-04 10:48:34,396][DEBUG][action.admin.indices.create] [Her] [logstash-2014.02.04] failed to create
org.elasticsearch.index.mapper.MapperParsingException: mapping [mapping.json]
    at org.elasticsearch.cluster.metadata.MetaDataCreateIndexService$2.execute(MetaDataCreateIndexService.java:312)
    at org.elasticsearch.cluster.service.InternalClusterService$UpdateTask.run(InternalClusterService.java:298)
    at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:135)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:701)
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map
    at org.elasticsearch.index.mapper.DocumentMapperParser.extractMapping(DocumentMapperParser.java:268)
    at org.elasticsearch.index.mapper.DocumentMapperParser.parse(DocumentMapperParser.java:155)
    at org.elasticsearch.index.mapper.MapperService.parse(MapperService.java:314)
    at org.elasticsearch.index.mapper.MapperService.merge(MapperService.java:193)
    at org.elasticsearch.cluster.metadata.MetaDataCreateIndexService$2.execute(MetaDataCreateIndexService.java:309)
    ... 5 more
2014-02-04 10:48:34 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2014-02-04 10:48:33 +0000 error_class="Net::HTTPServerException" error="400 \"Bad Request\"" instance=17509700

【问题讨论】:

    标签: mapping elasticsearch


    【解决方案1】:

    当您从头开始,因此没有映射时,您依赖默认值。每次发送文档时,尚未映射的字段会根据其 json 类型(和日期约定)自动映射。也就是说,如果您将第一个文档中的字段作为数字发送,并且该字段在您的第二个文档中变为字符串,则第二个文档的索引操作将返回错误。

    有管理映射的api,这并不意味着您必须声明所有字段。您可以只指定您希望与默认行为不同的行为。您可以在creating an index 时指定映射,如果索引已经存在,则使用put mapping api,或者甚至将它们包含在index templates 中,用于尚未创建的索引。

    可以更改映射,但只能应用向后兼容的更改。您始终可以添加新字段,但不能更改现有字段的类型或分析器。在这种情况下,您可以尝试使用 multi-fields 使更改向后兼容,否则您需要根据更新的映射重新索引。

    至于您的最后一个问题,如果您将所有内容都作为字符串进行索引,您将失去通常可以使用数字执行的操作,例如范围查询。这是否可行取决于您的数据以及您需要如何处理这些数据。

    【讨论】:

    • 如果您将第一个文档中的字段作为数字发送,并且该字段在第二个文档中变为字符串,则第二个文档的索引操作将返回错误。 有什么办法解决这个问题?我不介意 everything 是否被映射为字符串。没有任何标志说-Don't map, string everything.? :)
    • 当然可以,你的问题是它是否有意义,我的回答假设你知道这是可能的 :) Dynamic templates 是答案,以避免指定所有字段,但只是一个模式和要应用的映射。
    • @javanna- 那么像this 这样的东西会确保我所有的intlong 值都映射到string,全面吗?你能验证一下吗?
    • 我建议不要使用配置文件,当你像 elasticsearch 提供的那样出色的 api 时。只需将您的动态模板添加到您的映射中。使用_default_ 类型是有意义的,您只需删除match_mapping_type 以便使用单个模板将所有内容映射为字符串。至于您的错误,您提交的文件格式错误。
    猜你喜欢
    • 2014-11-27
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多