0

鉴于我有一个模型

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 和/或搜索才能通过这两个查询找到这家公司?

4

1 回答 1

3

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

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

  1. 该字段被分成更小的部分(标记化),
  2. 然后过滤每个令牌。

这对于索引和查询分别发生。

在这种情况下,您将使用 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> 

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

于 2012-11-19T01:48:51.653 回答