在 Elasticsearch 中搜索 "keyword" 内的完整子串

Search for complete substring within "keyword" in Elasticsearch

我有一个包含 5 亿个文档的索引。每个文档本质上都是一个 "keyword" / 字母和数字串(没有空格或标点符号)。这些字符串平均有 10 个字母,长度在 3 到 40 个字符之间。

我希望能够快速找到关键字字段包含某个子字符串的文档。

我读到 "wildcard" 搜索 (*abc*) 速度慢且不可缩放(前缀通配符)。

我现在专注于 n-gram。理想情况下,我认为我应该将 "min" 和 "max" 设置为 3 和 40。但是如果我在查询中将两者都设置为 3 并将 minimum_should_match 设置为 100%,我可以获得很好的结果(无需为大小为 4 - 40 的 ngram 添加大量额外存储空间)。缺点似乎是我得到了一些不需要的结果,例如搜索 "dabc" 也会匹配 "abcd".

我的问题是,如何以最好的方式(性能和存储)解决我的目标。

我是在重新发明轮子吗?我应该只使用 ngram min: 3 和 max: 40 吗?

您可以尝试使用几种不同的分析策略为字符串编制索引,然后使用 ngrams 过滤掉绝对不属于您要查找的内容的文档,然后对剩余的文档使用通配符。你的 ngram 过滤器会 return 一些误报,但这没关系,因为你的通配符过滤器会解决这个问题。您在这里权衡 space 与性能。较小的 ngram 意味着更多的误报(但使用的 space 更少)并且通配符过滤器的工作量更大。

我建议先在这里尝试一些方法,然后再在这里对性能和大小得出任何结论。

除了通配符,您还可以尝试正则表达式查询。这可能 运行 比通配符查询便宜一点,您可以将它与 ngrams 过滤器方法结合使用。