Elasticsearch:有没有办法将对象字段的所有(可能是动态的)子字段声明为字符串?

2023-12-13

我有一个 doc_type ,其映射类似于这个非常简化的映射:

{
   "test":{
      "properties":{
         "name":{
            "type":"string"
         },
         "long_searchable_text":{
            "type":"string"
         },
         "clearances":{
            "type":"object"
         }
      }
   }
}

clearances应该是一个对象,具有一系列用于过滤目的的字母数字标识符。典型的文档将具有以下格式:

{
    "name": "Lord Macbeth",
    "long_searchable_text": "Life's but a walking shadow, a poor player, that..."
    "clearances": {
        "glamis": "aa2862jsgd",
        "cawdor": "3463463551"
    }
}

问题是,有时在索引过程中,对象字段内新字段的第一个索引内容clearances将完全是数字的,如上例所示。这会导致 Elasticsearch 推断该字段的类型为long。但这是一次意外。在另一个文档中,该字段可能是字母数字。当此字段中包含字母数字值的后一个文档到达时,我收到解析异常:

{"error":"MapperParsingException[failed to parse [clearances.cawdor]]; nested: NumberFormatException[For input string: \"af654hgss1\"]; ","status":400}% 

我尝试使用如下定义的动态模板来解决这个问题:

{
   "test":{
      "properties":{
         "name":{
            "type":"string"
         },
         "long_searchable_text":{
            "type":"string"
         },
         "clearances":{
            "type":"object"
         }
      }
   },
   "dynamic_templates":[
      {
         "source_template":{
            "match":"clearances.*",
            "mapping":{
               "type":"string",
               "index":"not_analyzed"
            }
         }
      }
   ]
}

但如果第一个索引文档有clearance.some_subfield值可以被解析为整数,它将被推断为整数,并且该子字段上具有字母数字值的所有后续文档将无法索引。

我可以列出映射中的所有当前子字段,但它们很多,我预计它们的数量将来会增长(触发映射更新以及需要完全重新索引......)。

有没有一种方法可以使这项工作正常进行,而无需每次添加新子字段时都进行完整的重新索引?


你快到了。

首先,您的动态映射路径必须位于clearances.*,并且它必须是一个path_match而不是一个普通的match.

这是一个可运行的示例:https://www.found.no/play/gist/df030f005da71827ca96

export ELASTICSEARCH_ENDPOINT="http://localhost:9200"

# Create indexes

curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{
    "settings": {},
    "mappings": {
        "test": {
            "dynamic_templates": [
                {
                    "clearances_as_string": {
                        "path_match": "clearances.*",
                        "mapping": {
                            "type": "string",
                            "index": "not_analyzed"
                        }
                    }
                }
            ]
        }
    }
}'


# Index documents
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"test"}}
{"clearances":{"glamis":1234,"cawdor":5678}}
{"index":{"_index":"play","_type":"test"}}
{"clearances":{"glamis":"aa2862jsgd","cawdor":"some string"}}
'

# Do searches

curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
    "facets": {
        "cawdor": {
            "terms": {
                "field": "clearances.cawdor"
            }
        }
    }
}
'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch:有没有办法将对象字段的所有(可能是动态的)子字段声明为字符串? 的相关文章

随机推荐