我正在尝试构建一个ElasticSearch索引,它将包含有产品名称的文档,例如笔记本电脑-
{ "name" : "Laptop Blue I7"}然后,通过查询ES索引,将其用于自动完成建议。我有两个主要的限制:
我想定义术语的同义词,比如“笔记本电脑”的“笔记本”-
"Laptop Blue I7"
"Laptop Blue I7"
"Laptop Blue I7"
"Laptop Blue I7"
"Laptop Red I7"
"Laptop Red I7"
"Notebook Blue I7"现在,我在创建索引时添加了以下设置和映射文件-
{
"settings": {
"index": {
"analysis": {
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms" : ["Laptop,Notebook"]
}
},
"analyzer": {
"synonym" : {
"tokenizer" : "keyword",
"filter" : ["synonym"]
}
}}}},
"mappings": {
"catalog": {
"properties": {
"name": {
"type": "text",
"analyzer": "synonym"
}
}
}
}
}当我用“笔记本”查询数据时,首选的响应应该按频率和同义词排序。但是,当我查询时,响应通常与同义词和频率无关。我使用以下查询-
/_search
{"query": {
"query_string" : {"default_field" : "name", "query" : "Notebook"}
} }我得到的反应是-
"Notebook Blue I7"虽然我希望以下两种方法之一-
"Laptop Blue I7"
"Laptop Red I7"或
"Notebook Blue I7"
"Laptop Blue I7"
"Laptop Red I7"解决这一问题的任何见解都是有帮助的。谢谢
========编辑1:
当我在“笔记本”上使用\_analyze时,响应是
{'tokens': [{'end_offset': 3,
'position': 0,
'start_offset': 0,
'token': 'Notebook',
'type': '<ALPHANUM>'},
{'end_offset': 3,
'position': 0,
'start_offset': 0,
'token': 'Laptop',
'type': 'SYNONYM'}]}发布于 2019-05-27 10:06:17
问题在于您在keyword分析器中使用的synonym令牌程序。请做下面的事情来调试你的问题。
如果在倒排索引中为文档生成的标记与从搜索项生成的标记匹配,那么elasticsearch将显示它匹配并解释查询提供了许多其他信息,比如一个片段中有多少文档与搜索项及其分数匹配等等。
以上只是解决问题的一个非常基本的步骤,但您还没有实现正确的自动完成搜索,而在您的情况下,自动完成搜索应该返回note和lapt的结果。要实现这一点,您需要使用edge n gram分析器,而这 ES官方帖子可以帮助您实现这一点。
如果你面临任何其他问题或需要澄清,请告诉我。
发布于 2019-05-28 03:36:42
正如Amit所提到的,实现自动完成edge n gram是您应该考虑的问题。我想解释一下为什么您使用的设置不适用于完整的单词Notebook,当被查询时,它没有产生预期的结果。为此,让我们了解上面的分析器是如何工作的。
在设置中定义的synonym分析器有两个组件,tokenizer和令牌filter。首先,对于输入字符串,将应用令牌程序。令牌器的输出将是令牌。然后,这些将充当令牌filter的输入,并将产生最终的令牌集。
您可以阅读更多关于分析器如何工作的这里。
现在让我们考虑第一个例子,例如Laptop Blue I7
对于这个输入字符串,首先将应用keyword令牌程序,正如您可能知道的那样,关键字标记器接受输入字符串并生成一个相同的令牌,这是相同的输入字符串,无需任何修改。因此,令牌程序的输出将是Laptop Blue I7作为单个令牌。现在,这个令牌将充当synonym令牌过滤器的输入。根据定义,Laptop和Notebook是同义词,但它们都不匹配令牌Laptop Blue I7,因此最终这个过滤器将什么也不做,而是传递令牌。因此,最后生成的令牌将是Laptop Blue I7。
因此,当您搜索Notebook时,它将与上面的name值不匹配。
注意,如果输入字符串只是Laptop或Notebook,您将得到预期的令牌,因为关键字标记器将为输入生成单个单词令牌。这就是为什么“笔记本”上的_analyze给出了预期的结果。
因此,结论是keyword是罪魁祸首。要解决这个问题,我们需要一个令牌器,它将生成独立的令牌,如laptop、blue、i7,最简单的解决方法是使用standard而不是keyword。
处理多词同义词
这个回答可能对你有帮助。
https://stackoverflow.com/questions/56322628
复制相似问题