首页 > 解决方案 > Elasticsearch:如何找出一个值是否与列表中的任何值匹配?

问题描述

我刚开始学习 Elasticsearch。我的数据有公司名称及其网站,我有一个包含公司所有域别名的列表。我正在尝试编写一个查询,该查询可以提升列表中同一网站的记录。

我的数据看起来像:

{"company_name": "Kaiser Permanente",
 "website": "http://www.kaiserpermanente.org"},

{"company_name": "Kaiser Permanente - Urgent Care",
 "website": "http://kp.org"}.

域别名列表是:

["kaiserpermanente.org","kp.org","kpcomedicare.org", "kp.com"]

实际列表比上面的例子长。我试过这个查询:

{
  "bool": {
    "should": {
      "terms": {
        "website": [
          "kaiserpermanente.org",
          "kp.org",
          "kpcomedicare.org",
          "kp.com"
        ],
        "boost": 20
      }
    }
  }
}

该查询不返回任何内容,因为“条款”查询是完全匹配的。列表中的域和 url 相似但不一样。

我除了查询应该返回我的示例中的两条记录。我认为“匹配”可以工作,但我不知道如何将一个值与列表中的任何相似值进行匹配。

我发现了一个类似的问题How to do multiple "match" or "match_phrase" values in ElasticSearch。该解决方案有效,但我的别名列表包含 50 多个元素。如果我为每个元素编写多个“match_phrase”,那将非常冗长。有没有像“条款”这样更有效的方法,这样我就可以传入一个列表?

如果有人可以帮助我解决这个问题,我将不胜感激,谢谢!

标签: elasticsearch

解决方案


您所观察到的内容已在许多 stackoverflow 帖子/ES 文档中有所介绍 -termsmatch. 当您存储该信息时,我假设您正在使用standard分析器。这意味着当您推送“ http://kp.org ”时,Elasticsearch 会索引[ "http", "kp", "org" ]中断的令牌。但是,当您使用 时terms,它会查找“kp.org”,但没有这样的“kp.org”标记来查找匹配项,因为分析器在编制索引时已将其分解。 match但是,它将分解您查询的内容,以便 "kp.org" =>[ "kp", "org" ]并且它能够找到一个或两个。短语匹配只需要标记彼此相邻,这可能是您需要的必要条件。

不幸的是,似乎没有这样的选项可以像这样工作,match但允许许多值与 like 匹配terms。我相信你有三个选择:

  • 以编程方式生成查询,如您引用的 stackoverflow 帖子中所述,您指出这会很冗长,但我认为这可能没问题,除非您有 1k 个别名。

  • 分析该website字段,以便分析转换“ http://www.kaiserpermanente.org ”=>“kaiserpermanente.org”和“ http://kp.org ”=>“kp.org”进行索引。使用这种索引时间分析的方式,在查询的时候,可以成功的使用terms过滤器。这可能很好,因为 url 是结构化的,并且您概述的用例似乎只与域有关。如果您这样做,请使用多个字段以多种方式分析一个网站的价值。很高兴让 Elasticsearch 为您完成此类工作,而不必在您自己的代码中担心它。

  • 事先进行此处理(在将数据推送到 ES 之前),这样当您在 elasticsearch 中存储数据时,您不仅存储网站字段,还存储域、路径以及您事先计算的任何其他需要的内容。您需要付出努力才能获得控制权。


推荐阅读