Solr:得分高于部分匹配的精确匹配

时间:2014-10-14 15:51:52

标签: java solr lucene solrj

在一个非常简单的例子中,我有三个文件,文件名为“Lark”,“Larker”和“Larking”(没有文件扩展名)。在solr中,我将这三个文件编入索引,将文件名映射到“标题”字段。当我搜索“Lark”时,返回所有三个文件(这是我想要的),但它们都被给予相同的分数。我希望“Lark”获得最高分,因为它与我的查询完全匹配,其他人则落后。

<field name="title" type="text_general" indexed="true" stored="true" multiValued="false"/>

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

我相信他们获得相同分数的原因是因为在索引时使用了EdgeNGramFilterFactory。每个文档被索引为“La”,“Lar”,“Lark”,其中两个文档(“Larker”和“Larking”)被索引了一些其他变体。因此,实际上每个文档都与查询“Lark”完全匹配。我想要一些执行查询的方法,其中术语“Lark”将返回所有三个文档,但标题为“Lark”的文档返回高于其他文档。

查询调试的结果:

<lst name="debug">
  <str name="rawquerystring">Lark</str>
  <str name="querystring">Lark</str>
  <str name="parsedquery">text:lark</str>
  <str name="parsedquery_toString">text:lark</str>
  <lst name="explain">
    <str name="543d6ee4cbb33c26bbcf288b/xxnullxx/543d6ef9cbb33c26bbcf2892">
2.7104912 = (MATCH) weight(text:lark in 0) [DefaultSimilarity], result of:
  2.7104912 = fieldWeight in 0, product of:
    1.4142135 = tf(freq=2.0), with freq of:
      2.0 = termFreq=2.0
    3.8332133 = idf(docFreq=3, maxDocs=68)
    0.5 = fieldNorm(doc=0)
</str>
    <str name="543d6ee4cbb33c26bbcf288b/xxnullxx/543d6ef9cbb33c26bbcf2893">
2.7104912 = (MATCH) weight(text:lark in 1) [DefaultSimilarity], result of:
  2.7104912 = fieldWeight in 1, product of:
    1.4142135 = tf(freq=2.0), with freq of:
      2.0 = termFreq=2.0
    3.8332133 = idf(docFreq=3, maxDocs=68)
    0.5 = fieldNorm(doc=1)
</str>
    <str name="543d6ee4cbb33c26bbcf288b/xxnullxx/543d6ef9cbb33c26bbcf2894">
2.7104912 = (MATCH) weight(text:lark in 2) [DefaultSimilarity], result of:
  2.7104912 = fieldWeight in 2, product of:
    1.4142135 = tf(freq=2.0), with freq of:
      2.0 = termFreq=2.0
    3.8332133 = idf(docFreq=3, maxDocs=68)
    0.5 = fieldNorm(doc=2)
</str>

2 个答案:

答案 0 :(得分:2)

为了提升完全匹配,您可以使用新类型&#34; text_exact&#34;创建一个名为&#34; exact_title&#34;的新字段。没有EdgeNGramFilterFactory的东西。

在您的架构中,您可以使用以下行:

<copyField source="title" dest="exact_title"/> 

将标题复制到exact_title。

然后针对字段,标题和exact_title运行查询。如果查询与确切的标题匹配,那么具有该确切标题的文档将获得比其他文档更高的分数,并将升至顶部。

答案 1 :(得分:0)

也许迟到了,但您也可以在不创建新字段的情况下使用KeywordRepeatFilterFactorySolr documentation描述了这一点:

  

一个重复的问题是“我怎么能让原来的术语有所贡献   更多的得分比词干版“?在Solr 4.3中,   已添加 KeywordRepeatFilterFactory 以协助此操作   功能。此过滤器为每个输入令牌发出两个令牌,一个   其中标有关键字属性。 Stemmers尊重   关键字属性将通过标记进行标记,而不进行标记   更改。所以这个过滤器的效果就是索引两者   原始单词和词干版本。