我们目前正在为使用Solr的客户进行概念验证,并且能够配置他们想要的所有功能,除了得分。
问题是他们想要得分使得结果落在桶中:
我们做的第一件事就是开发一个自定义相似度类,它会根据字段和精确或部分匹配返回正确的分数。
现在唯一的问题是,当文档在类别和名称上匹配时,分数会加在一起。
示例:搜索“餐馆”会返回类别餐厅中的文档,这些文档的名称中也包含“餐馆”字样,因此得分为5(4 + 1),但只能得到4分。
我认为为了实现这个目的,我们需要开发一个自定义的Scorer类,但我们不知道如何在Solr中加入它。 另一种选择是创建一个类似于Solr中已经存在的RandomSortField的自定义SortField实现。
也许甚至还有一个我们不了解的简单解决方案。
欢迎所有建议!
答案 0 :(得分: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中使用您自己的Query类,您需要实现自己的solr QueryParserPlugin,它使用您自己的QParser生成以前实现的lucene Query。然后,您可以在此处指定的Solr中使用它:
http://wiki.apache.org/solr/SolrPlugins#QParserPlugin
这部分实现应该保持简单,因为这只是一些粘合代码。
享受黑客Solr!
答案 1 :(得分:3)
您可以覆盖逻辑solr得分者使用。 Solr使用DefaultSimilarity类进行评分。
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;
}
}
<similarity class="<your package name>.CustomSimilarity"/>
您可以查看影响得分的各种因素here
根据您的要求,如果您的分数在特定范围内,您可以创建存储桶。还可以阅读有关现场提升,文档提升等信息。这可能对您的情况有所帮助。
答案 2 :(得分:2)
我相信Solr的DisMaxRequestHandler可以帮到你。
以下是hossman's explanation of the dismax和Mark Miller's survey of query parsers。
答案 3 :(得分: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:
<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
Google搜索引导您this,因此只需在schema.xml中添加此行,该行将应用于其他字段:
<similarity class="solr.SchemaSimilarityFactory"/>
(从该链接:但请记住,coord和queryNorm(= 1.0f)现在没有实现,因此您将获得TF-IDF的不同分数!)