Solr 通配符评分和 NGramFIlterFactory
Solr Wildcards Scoring and NGramFIlterFactory
在 Solr 中使用通配符搜索时,文档似乎得不到分数。
假设我的索引中有以下包含名字的文档,并按以下顺序对它们进行了索引:
- 迈克尔
- 迈克尔森
- 迈克尔
搜索名字“Michael*”并将结果大小限制为 2 会返回前两个。但显然第 3 个人比第 2 个人更适合我的搜索。我应该在这里做什么?我可以通过使用 NGramFilterFactory 并省略通配符来解决这个问题吗?
你可以解决这种问题,这与自动完成问题非常相似,方法是将你的字段“first_name”复制到其他字段,分析器可以基于 EdgeNGramFilterFactory 并将索引:
米
米
麦克风
密歇根州
米夏
迈克尔
迈克尔
使用:
<field name="first_name" type="text_general" indexed="true" stored="true" required="true" multiValued="false"/>
<copyField source="first_name" dest="textnge"/>
<field name="textnge" type="autocomplete_edge" indexed="true" stored="false" />
<field name="textng" type="autocomplete_ngram" indexed="true" stored="false" />
和
<fieldType name="autocomplete_edge" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="([\.,;:-_])" replacement=" " replace="all"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="30" minGramSize="1"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="autocomplete_ngram" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="20" minGramSize="1"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
然后您可以像这样配置查询处理程序:
<requestHandler name="/select" class="solr.SearchHandler">
<lst name="defaults">
<str name="defType">edismax</str>
<str name="qf">first_name^30 textnge^100.0 textng^20.0</str>
</lst>
因此,完全匹配比部分匹配更重要,第一个单词的边缘也比另一个单词的部分匹配更重要。
在 Solr 中使用通配符搜索时,文档似乎得不到分数。 假设我的索引中有以下包含名字的文档,并按以下顺序对它们进行了索引:
- 迈克尔
- 迈克尔森
- 迈克尔
搜索名字“Michael*”并将结果大小限制为 2 会返回前两个。但显然第 3 个人比第 2 个人更适合我的搜索。我应该在这里做什么?我可以通过使用 NGramFilterFactory 并省略通配符来解决这个问题吗?
你可以解决这种问题,这与自动完成问题非常相似,方法是将你的字段“first_name”复制到其他字段,分析器可以基于 EdgeNGramFilterFactory 并将索引: 米 米 麦克风 密歇根州 米夏 迈克尔 迈克尔
使用:
<field name="first_name" type="text_general" indexed="true" stored="true" required="true" multiValued="false"/>
<copyField source="first_name" dest="textnge"/>
<field name="textnge" type="autocomplete_edge" indexed="true" stored="false" />
<field name="textng" type="autocomplete_ngram" indexed="true" stored="false" />
和
<fieldType name="autocomplete_edge" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="([\.,;:-_])" replacement=" " replace="all"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="30" minGramSize="1"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="autocomplete_ngram" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="20" minGramSize="1"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
然后您可以像这样配置查询处理程序:
<requestHandler name="/select" class="solr.SearchHandler">
<lst name="defaults">
<str name="defType">edismax</str>
<str name="qf">first_name^30 textnge^100.0 textng^20.0</str>
</lst>
因此,完全匹配比部分匹配更重要,第一个单词的边缘也比另一个单词的部分匹配更重要。