Solr中的多字同义词搜索

时间:2015-04-16 16:07:06

标签: solr synonym

我正在尝试使用同义词过滤器来搜索短语。

peter=> spider man, spiderman, Mary Jane, .....

我使用默认配置。当我将这些同义词放入synonym.txt并重新启动Solr时,它似乎只是部分工作:它开始搜索"spider""man""spiderman""Mary""Jane"但我要搜索的是有意义的组合 - 例如"spider man""Mary Jane""spiderman"

3 个答案:

答案 0 :(得分:2)

很遗憾,这是一个众所周知的问题,因为Solr查询解析器在分析之前如何在空白上分解。因此,而不是看到"蜘蛛"之前"男人"在令牌流中,您只需单独查看每个单词。只是"蜘蛛"之前/之后没有任何东西只是" man"没有任何前/后。

这是因为大多数Solr查询表单都将空格视为" OR"。搜索"蜘蛛或男人"而不是查看全文,分析它以生成同义词,然后从中生成查询。

有关更多背景信息,请this blog post

这个问题有很多解决方案,包括:

  • hon-lucene-synonyms。此插件在生成多个字段的edismax查询之前运行分析器。它有点像黑盒子,而且我发现它可以生成一些复杂的查询表单,这些表单会产生奇怪的性能和相关性错误。
  • Lucidwork's autophrase query parser通过有选择地自动断层,这个插件可以让你指定不应该被分解为OR查询并且可以应用同义词扩展的关键短语(蜘蛛侠)
  • OpenSource Connection' Match query parser。在搜索字段之前,使用查询指定的分析器搜索单个字段。还将多词同义词搜索为短语。我最喜欢的,但免责声明:我是作者:)
  • Rene Kriegler' Querqy - Querqy是查询预处理规则的Solr插件。这些规则可以识别您的关键短语,并将查询重写为非multiterm形式。
  • 自己动手:学习编写自己的query parser plugin,然后根据需要处理问题。

答案 1 :(得分:1)

我对此类问题的通常策略是使用同义词过滤器不扩展搜索以包含所有可能的同义词,而是规范化为单个表单。我在索引和查询字段分析中执行两者

例如,fieldType/analyzer中的schema.xml块中包含此行:

<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>

(注意expand="false"
......我的synonyms.txt中的这一行:

spiderman, spider man, Mary Jane => peter

这样我就可以确保将这四个值中的任何一个索引为搜索为“peter”。例如,如果源文件提到“神奇的蜘蛛侠”,它将被编入索引为“The Amazing peter”。当用户搜索“Mary Jane”时,它将搜索“peter”,因此将匹配

这里重要的是因为“Mary”不是逗号分隔的同义词之一,如果没有“Jane”跟随,它将不会被更改。所以搜索“Mary is amazing”实际上会搜索“Mary is amazing”,并且它与文档不匹配。

其中一个重要的细节是,我选择的标准化形式(例如“彼得”)只是一个单词。我可以用这种方式组织它:

peter, spiderman, spider man => Mary Jane

但是因为Mary Jane是两个单词,它可能(取决于我的搜索的其他功能),分别匹配两个单词以及一起。通过选择单个单词形式进行标准化,我确保我的标记器不会尝试将其分解。

答案 2 :(得分:0)

这是Solr / Lucene的一个已知限制。基本上,您必须提供另一种标记化形式,以便将特定空格分隔的单词(即短语)视为单个单词。 实现此目的的一种方法是执行此客户端 - 即在您的应用程序中调用Solr,在编制索引时,保留同义词短语列表并使用替代方法查找/替换这些短语值(例如删除空格或将其替换为不被视为标记边界的分隔符。)

E.g。如果您将“Hello There”作为要在同义词中使用的短语,则在编制索引时将其替换为“HelloThere”。

现在在您的synonyms.txt文件中,您可以(例如):

Hi HelloThere Wotcha => Hello

同样在搜索时,用HelloThere替换查询字符串中“Hello There”的任何事件,然后将它们作为Hello的同义词进行匹配。

或者,您可以使用LucidWorks创建的AutoPhraseTokenFilter,可在github上找到。这通过维护令牌流来工作,以便如果两个或更多个连续令牌的组合与同义词短语中的一个匹配,则它可以解决,如果不匹配,则它将第一个令牌丢弃为与该短语不匹配。我不确定这会增加多少开销,但这似乎是一个很好的方法 - 默认情况下在Solr中作为SynonymFilter的一部分会很好。