用太阳黑子进行部分搜索

时间:2012-11-17 22:12:21

标签: ruby-on-rails solr sunspot

鉴于我有一个模特

class Firm < ActiveRecord::Base
  searchable do
    text :name
  end
end

solr的schema.xml包含

<fieldType name="text" class="solr.TextField" omitNorms="false">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="30"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

我有一个名字=='Ойл-М(Oil-M)'的公司

当我尝试搜索时

Sunspot.search(Firm) do
  fulltext 'Ойл-М'
end

然后我什么都没得到

当我尝试搜索时

Sunspot.search(Firm) do
  fulltext 'Ойл'
end

然后我需要坚定

如何设置Solr和/或搜索以便能够通过两个查询找到此公司?

1 个答案:

答案 0 :(得分:3)

你的NGramFilter正在切断最后的'M',因为你有minGramSize=2。设置minGramSize=1会起作用,但这会大大增加Solr必须存储的数据大小,并且还会增加噪音。

索引并查询Solr中的字段时,会发生两件事:

  1. 该字段被拆分为较小的部分(标记化),
  2. 然后过滤每个令牌。
  3. 单独进行索引和查询。

    在这种情况下,您使用StandardTokenizerFactory,StandardFilter,LowercaseFilter和NGramFilter索引字段,并使用除NGramFilter之外的所有内容查询字段。

    当您将“Ойл-М(Oil-M)”索引到Solr时,会发生什么。

    StandardTokenizerFactory: ['Ойл', 'М', 'Oil', 'M']
    StandardFilter: ['Ойл', 'М', 'Oil', 'M']
    LowerCaseFilter: ['ойл', 'м', 'oil', 'm']
    NGramFilter: ['ой', 'йл', 'ойл', 'oi', 'il', 'oil']
    

    'm'完全消失了。搜索“Ойл-М”不会返回任何内容,因为没有 M 来搜索

    切除NGramFilter,除非你有充分的理由使用它,并坚持使用标准的俄罗斯fieldType。

    <fieldType name="text_ru" class="solr.TextField" positionIncrementGap="100">                                                            
      <analyzer>                                                                                                                            
        <tokenizer class="solr.StandardTokenizerFactory"/>                                                                                  
        <filter class="solr.LowerCaseFilterFactory"/>                                                                                       
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ru.txt" format="snowball" enablePositionIncrements="~
        <filter class="solr.SnowballPorterFilterFactory" language="Russian"/>                                                               
      </analyzer>                                                                                                                           
    </fieldType> 
    

    注意:请注意,索引分析器和查询分析器之间没有区别。每个查询的转换方式与索引时完全相同。