【问题标题】:Search for complete substring within "keyword" in Elasticsearch在 Elasticsearch 中的“关键字”中搜索完整的子字符串
【发布时间】:2018-07-30 10:27:35
【问题描述】:

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

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

我读到“通配符”搜索 (*abc*) 很慢且不可扩展(前缀通配符)。

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

我的问题是,如何以最佳方式(性能和存储)实现我的目标。

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

【问题讨论】:

    标签: elasticsearch substring wildcard n-gram


    【解决方案1】:

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

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

    您也可以尝试使用正则表达式查询来代替通配符。这可能比通配符查询便宜一些,您可以将其与 ngrams 过滤器方法结合使用。

    【讨论】:

    • 我喜欢这种方法,但是当我在查询中添加通配符部分时,性能就像只使用通配符一样慢:{“查询”:{“布尔”:{“过滤器”:[ { "match": { "name": { "query": "abcdefg" } } }, { "wildcard": { "name": "*abcdefg*" } } ] } } } ngram 部分需要 75 毫秒,在添加通配符时会跳转到 3000...
    • 最终使用 3grams (3:3) 然后在 python 中过滤。因为我无法在 Elastic 中获得良好的通配符性能,并且 ngram 扫描的结果只有 500 次左右。
    猜你喜欢
    • 2021-07-09
    • 2021-12-23
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多