当前位置: 首页 > 面试题库 >

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

东郭弘
2023-03-14
问题内容

我有一个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.*,并且必须是a path_match而不是plain 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"
            }
        }
    }
}
'


 类似资料:
  • 问题内容: 让我们说我有这样的查询: 通过在各处手动更改字符串,我使用不同的表多次运行此查询。我尝试声明以下内容: 但这似乎不起作用,因为它引发了一个错误,提示我必须先声明为表变量,然后才能使用它。我如何对表名进行模板化,如果可以的话,Intellisense仍然可以使用吗? 问题答案: 您可以将其包装在EXEC语句中,如下所示: 但是不,在这种情况下,智能感知将无法正常工作。 如果您事先知道输出

  • 问题内容: 我正在使用一个字段,我希望在用户以其他颜色键入时设置字段的样式。例如,假设的样式声明为,而我想将其中的 一部分 更改为。有什么办法可行吗? 如果没有(我怀疑),那么关于如何在保持语义标记的同时如何模拟这种效果的任何创意? 问题答案: 您的猜想是正确的:样式仅适用于整个输入。 由于样式只能应用于整个元素,因此解决方案将要求每种所需颜色至少包含一个元素。 考虑相对于用户进行更改的点的输入字

  • 在C中,如果值不能为NULL,则通常引用传递而不是指针。 假设我有一个具有以下签名的函数,该签名通常与字符串文字一起使用。 我想知道如何更改函数,使其接受引用(并且具有不接受NULL的优势)? > 另一个选项是

  • 因为在protobuf中,在某些场景中定义一个灵活的结构很麻烦。 例如: 事实上,我不希望服务的客户端同时传递a和other。然而,在protobuf中,我们不能将这两个字段放在其中一个,因为另一个是列表字段。因此,声明了上述消息后,当我们只传递a\u other字段时,客户端无法判断a字段实际上是0还是服务器没有传递。 所以我想知道是否为定义一个字符串字段,例如: 并且服务器端和客户端都同意将字

  • 如何让我的Request estBody接受可能包含也可能不包含对象字段的模型? 这是我正在调用的Restcontrollerendpoint 这是@RequestBody正在接受的模型 我希望能够发送一个JSON,可以包含所有对象字段,或者一些。 我的JSON身体看起来像这样... 或者这个等等 或任何其他可能的组合。

  • 问题内容: 有什么方法可以使用静态字段。如果没有,还有其他方法可以做到这一点吗? 问题答案: 没有。你不能在Spring中自动连线或手动连线静态字段。为此,你必须编写自己的逻辑。