2010-06-14 64 views
11

我们目前正在为使用Solr的客户端开发一个概念证明,并且已经能够配置除了评分以外他们想要的所有功能。Solr/Lucene Scorer

问题是,它们需要的分数,使结果落入水桶:

  • 铲斗1:类别完全匹配(得分= 4)
  • 桶2:名称完全匹配(得分= 3)
  • 铲斗3:类部分匹配(评分= 2)
  • 铲斗4:名称部分匹配(得分= 1)

第一件事我们二d开发了一个自定义相似类,根据字段和精确或部分匹配返回正确的分数。

现在唯一的问题是,当一个文档匹配类别和名称时,分数会加在一起。

例如:搜索“餐厅”返回类别的餐厅,也有字的餐厅,他们的名字,因此分数为5(4 + 1)的文件,但他们应该只得到4

我假设为了这个工作,我们需要开发一个自定义的Scorer类,但是我们不知道如何将它结合到Solr中。 另一种选择是创建一个类似于Solr中已经存在的RandomSortField的自定义SortField实现。

也许有更简单的解决方案,我们不知道。

欢迎任何建议!

回答

3

得分者是lucene查询的一部分,通过“权重”查询方法。

总之,框架调用Query.weight(..)。scorer(..)。看看

http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/search/Query.html

http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/search/Weight.html

http://lucene.apache.org/jva/2_4_0/api/org/apache/lucene/search/Scorer.html

要使用Solr中自己的查询类,你需要实现使用自己QParser生成自己的Solr QueryParserPlugin您以前实现的lucene查询。然后,您可以在这里指定Solr的使用它:

http://wiki.apache.org/solr/SolrPlugins#QParserPlugin

上实现这部分应该保持简单,这只是一些胶合代码。

享受黑客Solr!

3

您可以覆盖逻辑solr分数器使用的逻辑。 Solr使用DefaultSimilarity类进行评分。

  • 使扩展DefaultSimilarity一类和重写功能TF(),IDF()等根据您的需要:

    public class CustomSimilarity extends DefaultSimilarity { 
    
        public CustomSimilarity() { 
        super(); 
        } 
    
        public float tf(int freq) { 
        //your code 
        return (float) 1.0; 
        } 
    
        public float idf(int docFreq, int numDocs) { 
        //your code 
        return (float) 1.0; 
        } 
    
    } 
    

  • 创建类编译后做出了罐子。
  • 将jar放入相应索引或核心的lib文件夹中。
  • 变化相应指数的schema.xml: <similarity class="<your package name>.CustomSimilarity"/>
  • 您可以检查出影响得分here

    对于您的要求,如果你的分数是在特定的范围内,你可以创建桶的各种因素。另外阅读有关场增强,文件提升等。这可能会对你的情况有所帮助。

    +0

    这很好。只需补充一点,4.0之前的版本只允许全局相似。 4.0+允许每场相似性。 (请参阅https://wiki.apache.org/solr/SchemaXml#Similarity) – arun 2013-04-22 21:54:56

    2

    感谢上面的好答案。只需在Solr 4.2.1中进行设置,然后再添加它们即可。 (在Solr 4之前,您只能在全局范围内更改所有字段的相似性。)

    假设我们希望Solr对特定字段不使用逆文档频率(idf) - 我们应该为此编写自己的自定义相似度像上面提到的:

    package com.mycompany.similarity; 
    
    import org.apache.lucene.search.similarities.DefaultSimilarity; 
    
    public class NoIDFSimilarity extends DefaultSimilarity 
    { 
        @Override 
        public float idf(long docFreq, long numDocs) 
        { 
         return 1.0f; 
        } 
    
        @Override 
        public String toString() 
        { 
         return "NoIDFSimilarity"; 
        } 
    } 
    

    ,然后在我们的schema.xml中定义一个新的字段类型如下:

    <fieldType name="int_no_idf" 
          class="solr.TrieIntField" 
          precisionStep="0" 
          positionIncrementGap="0" 
          omitNorms="true"> 
        <similarity class="com.mycompany.similarity.NoIDFSimilarity"/> 
    </fieldType> 
    

    ,并用它在这样一个领域:

    <field name="tag_id_no_idf" 
         type="int_no_idf" 
         indexed="true" 
         stored="false" 
         multiValued="true" /> 
    

    如果我们这样做只是这么多,那么你会得到下面的异常:

    SEVERE: Unable to create core: SimilarList 
    org.apache.solr.common.SolrException: FieldType 'int_no_idf' is configured with a similarity, but the global similarity does not support it: class org.apache.solr.search.similarities.DefaultSimilarityFactory 
        at org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:466) 
        at org.apache.solr.schema.IndexSchema.<init>(IndexSchema.java:122) 
        at org.apache.solr.core.CoreContainer.createFromLocal(CoreContainer.java:1018) 
        at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1051) 
        at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:634) 
        at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:629) 
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
        at java.util.concurrent.FutureTask.run(Unknown Source) 
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
        at java.util.concurrent.FutureTask.run(Unknown Source) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
        at java.lang.Thread.run(Unknown Source) 
    Apr 25, 2013 5:02:08 PM org.apache.solr.common.SolrException log 
    SEVERE: null:org.apache.solr.common.SolrException: Unable to create core: SimilarList 
        at org.apache.solr.core.CoreContainer.recordAndThrow(CoreContainer.java:1672) 
        at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1057) 
        at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:634) 
        at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:629) 
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
        at java.util.concurrent.FutureTask.run(Unknown Source) 
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
        at java.util.concurrent.FutureTask.run(Unknown Source) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
        at java.lang.Thread.run(Unknown Source) 
    Caused by: org.apache.solr.common.SolrException: FieldType 'int_no_idf' is configured with a similarity, but the global similarity does not support it: class org.apache.solr.search.similarities.DefaultSimilarityFactory 
        at org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:466) 
        at org.apache.solr.schema.IndexSchema.<init>(IndexSchema.java:122) 
        at org.apache.solr.core.CoreContainer.createFromLocal(CoreContainer.java:1018) 
        at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1051) 
        ... 10 more 
    

    谷歌搜索导致你this,所以只需添加这条线在schema.xml中,这将被应用到字段的其余部分:

    <similarity class="solr.SchemaSimilarityFactory"/> 
    

    (从该链接:但是记住,坐标和queryNorm(= 1.0F)现在还没有实现,所以你会得到不同的分数为TF-IDF)

    相关问题