我使用Elasticsearch来存储从我的系统之外的多个源发送的数据,也就是说,我不控制传入的数据--我只是接收json文档并存储它。我没有在中间使用过滤器的logstash,只有ES和Kibana。每个数据源都发送自己的数据类型,并且它们都存储在同一个索引中但是由于我无法控制发送给我的数据,因此可以接收字段具有相同名称和不同结构的不同类型的文档。
例如,假设我有type 1和type 2,字段为FLD,在这两种情况下都是对象,但该对象的结构不同。具体地说,FLD.name在type 1中是字符串字段,而在type 2中是对象。在这种情况下,当type 1数据到达时,它被成功存储,但当type 2数据到达时,它被拒绝:
无法在索引myindex、类型[type 2]上放置Map
异常错误:[FLD]的Map器与其他类型中的现有Map冲突[无法将非对象Map[FLD.name]与对象Map[FLD.name]合并]
ES文档明确声明,不同Map类型中同一索引中具有相同名称的字段在内部Map到同一字段,并且必须具有相同的Map(请参阅此处)。
我的问题是在这种情况下我能做些什么?我更喜欢将所有类型保存在同一个索引中。有没有可能为字段名添加一个每种类型唯一的后缀或类似的东西?还有其他解决方案吗?我是一个Elasticsearch新手,所以可能我错过了一些简单的东西...提前感谢。
2条答案
按热度按时间apeeds0o1#
如果在索引之前不进行预处理,就无法对任意JSON进行索引--即使Dynamic templates也不够灵活。
您可以将嵌套对象扁平化为键-值对,并使用Nested datatype、Multi-fields和
ignore_malformed
来索引任意JSON(即使存在类型冲突),如here所述。不幸的是,如果您试图将字符串与kv_pairs.value.long
匹配,Elasticsearch仍然会在查询时抛出异常,因此您必须根据值的格式选择适当的字段。qlzsbp2j2#
我认为这不是最佳实践,但您可以将字段内容存储为
String
,并在检索信息后手动进行反序列化。所以,想象一下这样一个类:
它可以接收
String
的List
或任何其他Object
的List,仅举个例子因此,您可以将Person序列化为
String
并保存它,而不是序列化为String
并将内容保存在另一个类上,例如:并保存
dtoContent
:RequestDto
将是一个具有String
字段的简单类:我不是ElasticSearch的Maven,但是通过验证,你可能会失去很多ElasticSearch的特性。