0

1. 我在做什么:

我目前正在尝试实现一些流行的同义词,以增加显示的广告数量。


2. 限制:

由于业务逻辑,我的默认运算符是 AND 因此,据我了解,搜索:

“ps3 slim 250gb 新”

应该返回包含该查询中每个术语的项目。我尝试切换到“OR”,但这将返回仅包含“new”或“slim”字样的项目。

由于我们总是按日期而不是按相关性排序,这是一个大问题。所以'和'它是。

这个想法是用大量的同义词和停用词来处理这个问题。


3. 我的设置:

我当前的 SOLR 设置包含以下分析器链:

<fieldtype name="text_pt" class="solr.TextField" positionIncrementGap="100">
   <analyzer type="index">
       <tokenizer class="solr.WhitespaceTokenizerFactory"/>
       <filter class="solr.ASCIIFoldingFilterFactory" protected="protwords.txt"/>
       <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" 
            generateNumberParts="1" preserveOriginal="1" catenateWords="1" 
            catenateNumbers="1" catenateAll="0"/>
       <filter class="solr.LowerCaseFilterFactory"/>
       <filter class="solr.StopFilterFactory" ignoreCase="false" words="portugueseStopWords.txt"/>
       <filter class="solr.BrazilianStemFilterFactory"/>
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
   </analyzer>
   <analyzer type="query">
       <tokenizer class="solr.WhitespaceTokenizerFactory"/>
       <filter class="solr.ASCIIFoldingFilterFactory" protected="protwords.txt"/>
       <filter class="solr.SynonymFilterFactory" ignoreCase="true" synonyms="portugueseSynonyms.txt" 
                expand="true"/>
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="portugueseStopWords.txt"/>
       <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" 
                catenateWords="1" preserveOriginal="1" catenateNumbers="1" catenateAll="0"/>
       <filter class="solr.LowerCaseFilterFactory"/>
       <filter class="solr.BrazilianStemFilterFactory"/>
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
   </analyzer>
</fieldtype>



4.问题:

我有同义词:

plaistation, plastation => playstation  #dirty spelling correction
ps3, playstation3  #just a synonym

第一个只是工作。第二个结果似乎是同义词和 WordDelimiter 之间的冲突,如分析页面和&debugQuery 所示

调试查询

<str name="querystring">title_search_pt:(ps3)</str>
<str name="parsedquery">MultiPhraseQuery(title_search_pt:"(ps3 ps) (3 playstation3 playstation) 3")</str>

查询分析器

WhitespaceTokenizerFactory => [pos:1] ps3
ASCIIFoldingFilterFactory  => [pos:1] ps3
SynonymFilterFactory       => [pos:1] ps3 
                              [pos:1] playstation3

StopFilterFactory          => [pos:1] ps3 
                              [pos:1] playstation3

WordDelimiterFilterFactory => [pos:1] ps3  [pos:2] 3              [pos:3] 3
                              [pos:1] ps   [pos:2] playstation3
                                           [pos:2] playstation


如您所见,在 WordDelimiterFilter 搞砸之前一切都很好。
我所期待的是psplaystation都在 pos:1 和 3 在 pos:2。
如果我将“OR”作为默认操作,这将不是问题,但由于这对我来说不可能,这将尝试匹配同时具有 ps3 和 playstation3 的文档,而不是给我更多结果,它甚至给了我较少的..


5.问题:

我能做些什么呢?我认为 WordDelimiterFilter 提供了很多很好的东西来完全删除它,但是这个令牌位置移动对我来说看起来不正确。

4

3 回答 3

1

我使用添加同义词的讨厌方法解决了这个问题,利用了这样的短语同义词的“限制”:

ps3 => playstation 3, ps 3
ps2 => playstation 2, ps 2

这是一种同时使用替换(=>)和同义词(用逗号分隔的两个词)的技巧。

查询分析器是这样的:

WhitespaceTokenizerFactory => [pos:1] ps3
ASCIIFoldingFilterFactory  => [pos:1] ps3
SynonymFilterFactory       => [pos:1] ps            [pos:2] 3
                              [pos:1] playstation   [pos:2] 3

StopFilterFactory          => [pos:1] ps            [pos:2] 3
                              [pos:1] playstation   [pos:2] 3

WordDelimiterFilterFactory => [pos:1] ps            [pos:2] 3
                              [pos:1] playstation   [pos:2] 3
...
RemoveDuplicatesTokenFilterFactory =>  [pos:1] ps            [pos:2] 3
                                       [pos:1] playstation   

调试查询

<str name="querystring">title_search_pt:(ps3 new)</str>
<str name="parsedquery">+MultiPhraseQuery(title_search_pt:"(playstation ps) 3") +title_search_pt:new</str>

我可以从同义词中删除 3 中的一个,因为这两个 3 最终将位于相同的标记位置,并且将被 RemoveDuplicatesTokenFilterFactory 删除。但是我保持这样,所以我的同义词文件不那么神秘。

于 2013-03-08T13:14:56.010 回答
0

要完成您的答案:

您也可以在文件中添加您放入同义词中的所有单词(或仅添加一个给您带来问题的单词),protwords.txt以便所有标记器都会忽略它们并按原样索引它们。

如果与同义词文件一起使用,这是有道理的,因为同义词是您要按原样查找的单词。

于 2013-08-05T14:48:26.260 回答
0

您可以设置splitOnNumerics="0"WordDelimiterFilterFactory的属性

splitOnNumerics="1"导致字母 => 数字转换生成一个新部分

“j2se” => “j” “2” “se”

默认为真(“1”);设置为 0 以关闭

这应该消除将 ps3 和 playstation3 分成两个标记的问题,一个带有单词,一个带有数值。

于 2013-03-07T20:06:28.213 回答