【问题标题】:Elasticsearch filter only if no matches to first filter仅当没有匹配到第一个过滤器时才过滤 Elasticsearch
【发布时间】:2015-06-07 13:06:56
【问题描述】:

我的用例是搜索有明确定义的邮政编码系统的英国地址,但我的用户仍可能在邮政编码中出错。我想使用一个过滤器,因为在大多数情况下,用户会得到正确的邮政编码,我不想让 Elasticsearch 工作得比它需要的更努力,但是我想避免从我的应用程序到 ES 的往返。

我正在使用文档中描述的edge n-gram 分析器,因此,以邮政编码ME4 4NR 为例,我将ME4 4NRME4 4NME4 4ME4 编入索引。我想先按ME4 4NR 过滤,如果没有匹配,则只扩大到ME4 4N

我可以在我的 ES 查询中实现这一点,还是需要在我的应用程序逻辑中实现这一点?任何建议将不胜感激。我可以在ME4shoulds 上使用带有must 的布尔过滤器,但我想知道是否有更好的方法?

【问题讨论】:

    标签: elasticsearch lucene


    【解决方案1】:

    我认为你在这里有点过于复杂了。这个 if-this-then-that-else-somethingelse 可以用 ES 来实现,但是可能的情况是有限的。例如 - this question - “else”部分是 must,其中的语句是 bool 过滤器,它首先使用 missing “条件”检查另一个 must。因此,为了应用“if-then-else”语句的另一部分,某些东西必须仍然正确。仅当“某个条件”为真或假时,就像在编程中一样,这并不是一个严格的问题。您需要采用这种 Elasticsearch 方式,而不是编程方式。

    您的解决方案 - 在 ME4 上使用 must 和在其他人上使用 shoulds - 不需要 imo。如果您将 analyzer 设置为边 n-gram,则在索引时使用相同的分析器,但在 搜索时时也使用相同的分析器。这意味着,根据所使用的查询/过滤器,您的输入文本将在执行搜索之前进行分析

    例如,如果您在搜索时使用match 查询,则分析您提供的输入文本。这意味着如果您输入 ME4 4N 作为搜索文本,首先 ES 将对输入文本进行 n-gram 边缘化并使用生成的标记来搜索倒排索引。因此,无需在您自己的代码中执行此操作,也无需在您的 ES 查询中提供多个 shoulds。

    我的建议是首先正确设置一组定义明确的要求。意思是,知道你想让你的搜索做什么:考虑应该放在倒排索引中的标记,并考虑用户输入的内容。确定您是否需要在索引时进行分析,还需要在搜索时。根据这一点,考虑在搜索时使用过滤器/查询的方法,这意味着哪些分析输入文本而哪些不分析(例如term 不会,而match 会)。 然后,测试您的方法并查看性能。 不要假设某些事情在 ES 上的工作量超过了应有的工作量,因为您可能错了。测试和比较结果,然后开始改进并提出其他想法。

    【讨论】:

    • 感谢您的建议 Andrei,非常感谢。我现在在提供的第一部分(例如 ME4)上有一个过滤器,这使 ES 在 7000 万条记录上的工作变得更加轻松,并保持搜索性能良好且结果合理,然后将完整的邮政编码作为常规匹配传递给分析器查询并让它做它的事情,到目前为止结果很好,再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    相关资源
    最近更新 更多