我刚刚开始学习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”,将非常冗长。有没有更有效的方式,例如“条款”,这样我就可以通过列表?
如果有人可以帮助我,我将不胜感激,谢谢!
最佳答案
您正在观察的内容已在许多stackoverflow帖子/ ES文档中进行了介绍-terms
和match
之间的区别。当您存储该信息时,我假设您正在使用standard
分析器。这意味着当您按“http://kp.org”时,Elasticsearch会索引已破坏的[ "http", "kp", "org" ]
token 。但是,当您使用terms
时,它将查找“kp.org”,但没有此类“kp.org” token 来查找匹配项,因为在索引时分析器已将其分解。 match
,但是,它将分解您查询的内容,因此“kp.org” => [ "kp", "org" ]
可以找到一个或两个。短语匹配仅要求 token 彼此相邻,这可能是您需要的。
不幸的是,似乎没有像match
那样工作的选项,但允许许多值与terms
匹配。我相信您有三种选择:
website
字段,以便分析将“http://www.kaiserpermanente.org” =>“kaiserpermanente.org”和“http://kp.org” =>“kp.org”转换为索引。使用这种索引时间分析方法,在查询时,您可以成功使用terms
过滤器。鉴于url是结构化的,并且您概述的用例似乎只与域有关,所以这可能很好。如果这样做,请使用multi fields以多种方式分析一个网站的值(value)。最好让Elasticsearch为您完成这种工作,而不必担心自己的代码中有做。 关于elasticsearch - Elasticsearch:如何找出一个值是否匹配列表中的任何值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58824710/