Solr - 包含多个单词的同义词

时间:2012-08-31 14:06:22

标签: solr synonym

快速提问,我不知道如何处理包含空格的同义词! 我有以下配置:

SOLR配置文件

<fieldType ... >
  <analyzer type="index">
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.WordDelimiterFilterFactory" 
                            catenateWords="1" 
                            preserveOriginal="1"
                            splitOnCaseChange="1"
                            generateWordParts="1" 
                            generateNumberParts="1"         
                            catenateNumbers="1" 
                            catenateAll="1" 
                            />
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="30" side="front"/>
  </analyzer>
  <analyzer type="query">    
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.LengthFilterFactory" min="2" max="70" />
    <filter class="solr.SynonymFilterFactory" synonyms="syn.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
 </analyzer>
</fieldType>

我的档案:syn.txt

st., st => saint
istambul => istanbul
airport, apt => aéroport
NYC => New York
pt., pt => port
brussels => bruxelles

除了同义词外,一切都运行良好:

"NYC => New York"

我做了一些研究,发现了以下内容:

  

请记住,虽然SynonymFilter会很乐意使用包含多个单词的同义词(例如:“sea biscuit,sea biscit,seabiscuit”)

     

处理这样的同义词的推荐方法是在索引时扩展同义词。这是因为在查询时可能会出现两个潜在的问题:

     

Lucene QueryParser在向分析器提供任何文本之前在空格上进行标记,因此如果一个人搜索单词sea biscit,分析器将分别给出单词“sea”和“biscit”,并且不会知道它们匹配同义词。

     

短语搜索(即:“sea biscit”)将导致QueryParser将整个字符串传递给分析器,但是如果SynonymFilter配置为扩展同义词,那么当QueryParser从中获取生成的标记列表时在Analyzer中,它将构造一个不具备预期效果的MultiPhraseQuery。

     

这是因为分析器可用的机制有限,表明两个术语占据相同位置:无法指示“短语”占据与术语相同的位置。

     

对于我们的示例,生成的MultiPhraseQuery将是“(sea | sea | seabiscuit)(饼干| biscit)”,它与文档中出现的“seabiscuit”的简单情况不匹配

所以我尝试更改配置文件并在索引处添加我的过滤器,但它无效。

有什么想法吗?

4 个答案:

答案 0 :(得分:7)

您正在使用=>进行显式映射。

Solr documentation

  

显式映射匹配LHS“=&gt;”上的任何标记序列和替换与RHS上的所有替代品。这些类型的映射会忽略模式中的expand参数。

所以我猜测,如果你搜索NYC,你什么也得不回来,因为它在索引时被New York取代了。

相反,您可以尝试将它们声明为等效的同义词吗?即喜欢 NYC, New York代替NYC => New York

然后我相信你可以搜索其中任何一个,结果将是相同的。

答案 1 :(得分:3)

问题在于,当第一个短语中的单词数小于第二个短语中的单词数时,solr同义词往往会引发问题。发生这种情况时,令牌会溢出到其他令牌的位置。

我有解决此问题的方法,但在索引和查询时需要两次使用 solr.SynonymFilterFactory

像这样:

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

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

在第一个过滤器中,您将拥有:New York =&gt; New_York

在第二个过滤器中:NYC =&gt; New_York

现在搜索纽约将返回包含NYC和反之诗节的结果。

最后一点:除非处于索引和查询时,否则此方法将无效。

答案 2 :(得分:2)

关于

st., st => saint

我认为你应该这样做:

st. => saint
st => saint

关于

NY => New York

我正面临类似的问题并得出结论,这是因为解析是在同义词替换之前完成的,这可能会导致多字时出现问题。 我发现可以在SynonymFactory中包含一个解析器:

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

我刚试过它我得到了更好的结果,但还不是预期的结果。 奇怪的是,当添加KeywordTokenizerFactory似乎对positvely产生影响时,添加WhitespaceTokenizerFactory或StandardTokenizerFactory似乎没有任何改变。

顺便说一句,如果不使用带状疱疹,这应该已经没事了。

答案 3 :(得分:0)

基于Pr Shadoko的回答:

了解分析仪的工作方式,例如与

http://localhost/solr/analysis/field?analysis.fieldvalue=EXAMPLE-KEYWORDS&q=EXAMPLE-KEYWORD%203&analysis.fieldname=EXAMPLEFIELD&analysis.showmatch=true

analysis / field是一个开箱即用的请求处理程序(位于solrconfig.xml中)。 Here您找到了参数列表。 (“analysis.query”对我不起作用,所以我不得不使用“q”)

由于SynonymFilter在匹配任何同义词之前解析(剪切)传入的文本,因此多词同义词不会受到影响。 诀窍是告诉SynonymFilter采用一个实际上不解析的解析器:keywordTokenizer

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

无论如何,这种方法感觉像是黑客,我无法估计副作用(可扩展性,......) - 所以要小心!