【问题标题】:Synonyms with concepts that have spaces, or are multiple words具有空格或多个单词的概念的同义词
【发布时间】:2012-08-31 14:06:22
【问题描述】:

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

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 从分析器,它会构造一个 MultiPhraseQuery,但不会产生预期的效果。

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

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

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

有人有什么想法吗?

【问题讨论】:

标签: solr


【解决方案1】:

您正在使用=&gt; 进行显式映射。

Solr documentation

显式映射匹配“=>”的 LHS 上的任何标记序列,并用 RHS 上的所有替代项替换。这些类型的映射会忽略架构中的 expand 参数。

所以我猜如果你搜索 NYC 你什么也得不到,因为它在索引时被 New York 替换了。

相反,您可以尝试将它们声明为等效的同义词吗?即喜欢 NYC, New York 而不是 NYC =&gt; New York

那我相信你可以搜索其中任何一个,结果都会是一样的。

【讨论】:

    【解决方案2】:

    问题在于,当第一个短语中的单词数少于第二个短语中的单词数时,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 => New_York

    在第二个过滤器中:NYC => New_York

    现在搜索 New York 将返回包含 NYC 的结果,反之亦然。

    最后一点:只有在索引和查询时,此方法才会起作用。

    【讨论】:

    • 那么,如果您的索引中有“New York”,则在键入“new”或“york”时将永远找不到它
    • 我同意 dzezzz。为什么你不能只做 NYC => NYC New York?
    【解决方案3】:

    关于

    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 似乎会产生积极影响时,添加 WhitespaceTokenizerFactory 或 StandardTokenizerFactory 似乎并没有改变任何东西。

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

    【讨论】:

      【解决方案4】:

      根据 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" />
      

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

      【讨论】:

        猜你喜欢
        • 2014-04-10
        • 2017-02-28
        • 2012-03-19
        • 2014-10-16
        • 2018-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        相关资源
        最近更新 更多