我想知道这怎么可能。假设我正在搜索ka
,那么Karthik
的得分应该比Aakash
的得分要多。如何提升那些文档?。我已经试过了。
我正在尝试使用SpanFirstQuery
,如下所示。但不管用。我用的是Lucene4.0
//queryString is searchText. e.g ka
//NAME, ORGANIZATION_NAME and ORGANIZATION_POSITION are indexed field names.
Map<String, Analyzer> searchAnalyzers = new HashMap<String, Analyzer>();
searchAnalyzers.put(NAME, new KeywordAnalyzer());
searchAnalyzers.put(ORGANIZATION_NAME, new KeywordAnalyzer());
searchAnalyzers.put(ORGANIZATION_POSITION, new KeywordAnalyzer());
PerFieldAnalyzerWrapper perFieldAnalyzerWrapper = new PerFieldAnalyzerWrapper(new KeywordAnalyzer(), searchAnalyzers);
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(Version.LUCENE_40, mSearchFields, perFieldAnalyzerWrapper); //mSearchFiels is array of fiels
multiFieldQueryParser.setDefaultOperator(QueryParser.Operator.AND);
Query query = (Utils.isEmpty(queryString)) ? new MatchAllDocsQuery() : multiFieldQueryParser.parse(QueryParser.escape(queryString)); //queryString is text to be searched
Term term = new Term(NAME, queryString);
SpanFirstQuery spanFirstQuery = new SpanFirstQuery(new SpanTermQuery(term), 5);
spanFirstQuery.setBoost(5.0f);
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(spanFirstQuery, BooleanClause.Occur.SHOULD);
booleanQuery.add(query, BooleanClause.Occur.MUST);
indexSearcher.search(booleanQuery, 100);
我的想法是,为什么SpanFirstQuery是一个坏主意--它看起来很像一个变通方法,就性能而言,它可能工作不佳(另外,我不确定如何首先让它工作),而且还需要您存储位置(额外的空间),这并不是真的需要。
提议的解决办法:
警告-这是实验性的,可能不是生产就绪的解决方案,这仍然需要一些工作来做。
public class BoostPrefixScoringRewrite extends ScoringRewrite<BooleanQuery.Builder> {
private final String text;
public BoostPrefixScoringRewrite(String text) {
// todo should be handled more carefully, since wildcard query supports other than * symbols
this.text = text.replace("*", "");
}
@Override
protected BooleanQuery.Builder getTopLevelBuilder() {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.setDisableCoord(true);
return builder;
}
protected Query build(BooleanQuery.Builder builder) {
return builder.build();
}
@Override
protected void addClause(BooleanQuery.Builder topLevel, Term term, int docCount,
float boost, TermContext states) {
final TermQuery tq = new TermQuery(term, states);
if (term.text().startsWith(this.text)) {
// experiment with the boost value
topLevel.add(new BoostQuery(tq, 100f), BooleanClause.Occur.SHOULD);
} else {
topLevel.add(new BoostQuery(tq, boost), BooleanClause.Occur.SHOULD);
}
}
@Override
protected void checkMaxClauseCount(int count) {
if (count > BooleanQuery.getMaxClauseCount())
throw new BooleanQuery.TooManyClauses();
}
}
注意boosting值,现在它被硬编码为100,这应该足以始终将搜索文本开头的术语放在顶部。另外,需要注意的是--如果您的术语列表会变宽,使用Boolean重写,您可能会面临TooManyClauses异常,而您需要有一个变通方法,以增加这个数字,或者以不同的方式重写这个查询。
要获得完整的测试,请看这里-https://raw.githubusercontent.com/myslionrise/information-retrieval-adventure/master/lucene5/src/main/java/org/mystic/boostbeginningwithtest.java
问题内容: Lucene是否提供增强新文档的方法? 例如,假设Lucene文档包含日期字段。是否有可能在用户不以任何方式更改其查询的情况下,以更高的分数展示最新的文档? 我不想诉诸粗略的“按日期排序”解决方案,因为它将完全取消评分算法。 问题答案: 将文档放入索引时,请使用Document.setBoost(float value)。 您可以不断地重新调整现有文档上的值,或者具有随日期增加的浮点值
问题内容: 到目前为止,我已经能够找到如何在文件的开头添加一行,但这并不是我想要的。我会在一个例子中展示 档案内容 结果 相似,但是我不想用它创建任何新行… 如果可能的话,我想这样做。 问题答案: 可以在一个地址上运行: 您在这里的每个答案中看到的神奇之处是什么?线路寻址!。 要添加前10行吗? 或者您可以使用:
我有一个简单的需求,不确定配置solr是否容易做到这一点。 假设所有文档只有一个文本字段,没有标记化。 当查询进来时,我希望结果按匹配文本的百分比排序(包含)。百分比由计算 例如,有三个文档,文本字段如下: doc1:abcdefghij doc2:abcdefgh 3:abc 如果搜索词为“cde”,则文档1和文档2匹配(文本字段包含搜索词)。对于文件1,匹配百分比=3/10=30% 对于文件2
问题内容: 当没有从查询获得的数据时,我想显示默认消息。 例如让我们进行查询 从id = 100的雇员中选择empname 如果没有数据与该搜索匹配,我希望得到结果,或者应该显示所需的结果。 因此,我应该如何编写SQL查询来实现这一目标。 我正在使用Oracle 10g。 问题答案: 你有包裹到另一个或没有行会被退回。没有行的地方就不会有值。
问题内容: 这应该非常简单。如果我有这样的字符串: 那么通常会采用什么方式来获取与此模式匹配的文件列表?(例如,它应该匹配但不匹配 我看了一下,看起来像是对的野兽,但是我不确定如何使用它在相对目录路径中查找文件。 我想我可以查找ant的源代码,因为它使用了通配符语法,但是我必须在这里遗漏一些显而易见的内容。 (编辑:上面的示例只是一个示例案例。我正在寻找一种在运行时解析包含通配符的常规路径的方法。
问题内容: 我是Lucene的新手,在创建 用于查询文本文件集合的 简单代码时遇到一些问题。 我尝试了此示例,但与新版本的Lucene不兼容。 UDPATE: 这是我的新代码,但是仍然无法使用。 问题答案: Lucene是一个相当大的主题,涉及很多类和方法,通常您必须至少了解一些基本概念才能使用它。如果您需要快速可用的服务,请改用Solr。如果您需要对Lucene的完全控制,请继续阅读。我将介绍一