2

我正在尝试使用 python 从文件中提取 JSON 数组并将其输入到 ElasticSearch 中。数组如下所示:

{"name": [["string1", 1, "string2"],["string3", 2, "string4"], ... (variable length) ... ["string n-1", 3, "string n"]]}

ElasticSearch 在尝试索引数组时抛出 TransportError(400, mapper_parsing_exception, failed to parse)。我发现,每当我尝试向它提供包含字符串和整数的字符串时,ElasticSearch 有时会抛出相同的错误。因此,例如,以下内容有时会崩溃,有时会成功:

import json
from elasticsearch import Elasticsearch

es = Elasticsearch()

test = json.loads('{"test": ["a", 1, "b"]}')
print test
es.index(index, body=test)

这段代码是我可以在不破坏程序的情况下安全地注释掉的所有内容。我将 JSON 放入程序中,而不是从文件中读取它。我输入的实际字符串很长(否则我只会发布它们)并且总是会使程序崩溃。将 JSON 更改为 "test": ["a"] 将使其工作。如果上次崩溃,当前设置会崩溃,或者如果上次成功,则可以正常工作。到底是怎么回事?某种映射设置会解决这个问题吗?我还没有弄清楚如何设置具有可变数组长度的地图。我更喜欢利用无模式输入,但我会采取任何有效的方法。

4

1 回答 1

5

您可能会遇到与映射的类型冲突。由于您已经表达了保持“无模式”的愿望,我假设您没有明确地为您的索引提供映射。这很好用,只要认识到您索引的第一个文档将确定您的索引的架构。之后您索引的每个文档都具有相同的字段(按名称),这些字段必须符合与第一个文档相同的类型。

Elasticsearch 对值数组没有问题。事实上,在底层,它将所有值都视为数组(具有一个或多个条目)。稍微令人担忧的是您选择的示例数组,它混合了字符串和数字类型。由于数组中的每个值都映射到名为“test”的字段,并且该字段可能只有一种类型,因此如果 ES 处理的第一个文档的第一个值是数字,它可能会将该字段分配为一种long类型。然后,包含不能很好地解析为数字的字符串的未来文档将在 Elasticsearch 中导致异常。

查看有关动态映射的文档

无模式可能会很好,但在您的场景中,通过显式声明索引上至少为文档中的某些字段的映射,您可能会取得更大的成功。如果您打算索引充满混合数据类型的数组,最好将该字段声明为string类型。

于 2016-02-27T17:50:02.313 回答