我的一个客户是一家专门从事新闻摄影(以及八卦)的摄影机构,因此他们的许多客户的搜索都围绕特定的人。
我们索引了大约 150 万篇文档,对标题和标题进行了全文搜索;和全文搜索,而无需基于标签。我们有一个不错的停用词列表,它们提供了一个他们认为没有正确词干的受保护词列表。我们正在使用 Dismax 搜索标题、标题和标签,并有不同的提升)这一切都很好。
然而,事实证明,有些人很难做到正确。例如,阿尔·戈尔。在意大利语中,“al”是一个停用词,因此对“al gore”(不带引号)的简单查询变为:
+((DisjunctionMaxQuery((caption_text:gor | tags_text:gore^100.0 | headline_text:gor)))~1) ()
这确实为前副总裁带来了成功,当然还有“Lesley Gore”和“Tipper Gore”;而且,由于词干,“Gori”等的热门歌曲。暂且不说排序,它确实使结果混乱,我想做得更好。
将搜索词用引号括起来并没有帮助,无论如何,“al”都会被删除。将“gore”标记为受保护的词让我走到了一半,限制了误报的数量。我也尝试过使用 SynonymFilterFactory,但并没有走得太远——我将 SynonymFilterFactory 作为第一个过滤器,所以无论如何“al”都会被删除。
我认为我真正需要的是一种将“al gore”标记为单个标记的方法。对于一组可配置的“短语”,有什么可以让我这样做的吗?还有另一种我忽略的方法吗?solr.CommonGramsFilterFactory 也许?
更多背景信息:我们使用的是 Solr 1.4.0。schema.xml 的相关部分
<!-- used for headline and caption -->
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.it.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.SnowballPorterFilterFactory" language="Italian" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.it.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.SnowballPorterFilterFactory" language="Italian" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="tagsText" class="solr.TextField" sortMissingLast="true" omitNorms="false">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.it.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.it.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>