【发布时间】:2016-04-06 00:36:31
【问题描述】:
我需要在弹性搜索中支持对动态(非预定义)标签的查询。假设我有一个博客文档并希望支持对不同列集的查询,即 tagTypeA=valueX & tagTypeB=ValueY 并且这些 tagTypeX 列事先不知道。这些标签中的每一个都只有一个值。用户会将这些附加数据作为 Map String::String 传递给我的 API(没有严格的模型/结构)。我还需要支持对这些标签列的聚合查询。
我正在考虑支持此功能的三种方法。
- 声明每个文档最多只能支持 N 种动态标签(比如 10 个),并创建内部列,例如 Tag1、Tag2 ... Tag10。现在有一个配置来维护 TagTypeA=Tag1、TagTypeB=Tag2 等的映射。在代码中,迭代输入键值对并使用键到列名的映射动态生成 ES 搜索查询。
优点:易于实施
缺点:维护映射的开销。每次加入新类型的文档/客户端/必须为现有客户端添加新字段时,都必须对此进行修改。
- 在 ES 中使用字符串数组创建一个未分析的字段。存储数据时,以key+"Delimiter"+value的串联格式存储。因此,如果输入映射有 TagTypeA=Good & TagTypeB=High,那么这将在 ES 中存储为 ["TagTypeA-Good","TagTypeB-High"]。当用户查询时,构造回联系的字符串并搜索它们。
优点:无需更改代码即可加入新客户端/添加或更新新字段
缺点:首先,它听起来不干净。密钥不应该有分隔符。稍后更改映射非常繁琐,因为我们必须更改所有现有字符串值的值。
- 不要定义任何模式,让标签的 json 键值对传递给弹性搜索 PUT 调用。对于尚未存在的任何新键,弹性搜索将自动将其添加到具有默认类型推断的索引中(使用动态模板控制,并限制所有字段名称应以特定前缀开头)。
优点:无需配置或手动连接输入。无需任何手动操作即可透明地处理任何添加的列。
缺点:我相信这会有一些缺点。但是想不出具体的东西。请建议?我能想到的一个缺点是,由于字段名称被忽略,任何一个滥用的客户端都可能膨胀索引,这可能会由于大量字段而导致整个集群崩溃,除非我们有一个手动注册和批准的工作流程这些字段存储在单独的数据库中。还有什么缺点吗?
我个人正在考虑与选项 #3 保持一致。
任何人都可以分享您对上述三种方法的看法,以及是否有更好的方法来解决这个问题。
谢谢, 哈里什
【问题讨论】:
标签: search elasticsearch