【发布时间】:2015-12-29 14:32:18
【问题描述】:
我使用 Elasticsearch 来存储从我的系统外部的多个来源发送的数据,即我不控制传入的数据 - 我只是接收 json 文档并存储它。我没有中间有过滤器的logstash,只有ES和Kibana。每个数据源都发送自己的数据类型,它们都存储在相同的索引(每个租户)中,但类型不同。但是,由于我无法控制发送给我的数据,因此可以接收具有相同名称和不同结构的字段的不同类型的文档。
例如,假设我有type1 和 type2 带有字段 FLD,在这两种情况下都是一个对象,但这个对象的结构不一样。具体来说,FLD.name 是 type1 中的字符串字段,但 type2 中的对象。在这种情况下,当type1数据到达时存储成功,但当type2数据到达时,它被拒绝:
未能在索引 [[myindex]] 上放置映射,类型 [type2]
java.lang.IllegalArgumentException:[FLD] 的映射器与其他类型中的现有映射冲突[无法将非对象映射 [FLD.name] 与对象映射 [FLD.name] 合并]
ES 文档明确声明,不同映射类型的同一索引中的同名字段在内部映射到同一个字段,并且必须具有相同的映射(see here)。
我的问题是在这种情况下我该怎么办?我更愿意将所有类型保留在同一个索引中。是否可以为字段名称或类似的东西添加每个类型的唯一后缀?还有其他解决方案吗?我是 Elasticsearch 的新手,所以也许我遗漏了一些简单的东西......在此先感谢。
【问题讨论】:
-
我真的怀疑是否有任何出路,除了使用不同的名称..因为这个功能是弹性在 2.0 中实现的,与他们的结束相比有很大的变化
-
如果我想使用不同的名称 - 我在技术上是如何做到的?是否有任何“过滤器”可以根据特定模式修改名称?由于字段是动态的,我无法在数据到达之前提前完成。我应该在他们的文档中寻找什么功能?我想到的另一个选择是重新设计数据的存储方式:使用当前类型作为索引(每个索引中的所有数据都将以相同的方式映射)并使租户 ID 成为以某种方式添加到文档中的字段之一。虽然它使索引更大,多租户支持更具挑战性。
-
不,没有过滤器可以根据任何模式修改字段的名称...我建议您重新考虑如何存储数据。将类型存储为索引也不推荐..
-
这个运气好吗?请分享你的所作所为。
-
最终通过在不同索引中保存不同类型来解决原始问题。不是好主意,但我们想不出更好的办法。请注意,我们有多个但数量有限的来源,因此索引的数量会合理增长。此外,我们添加了 pre-index-enricher 服务,该服务会在文档的实际索引之前干扰数据输入流。我们在那里添加了一些合成字段。但是,如果您的字段列表是已知列表(但不是类型),您可以使用它来重命名。这不是我们的情况(字段列表可能会改变),所以我们没有将它用于此目的。
标签: java elasticsearch