F.e.我有3个文件。
1.“猫狗球”
2.“狗是猫”
3.“狗,猫和猫”
所以。通过查询“ dog AND cat AND ball”,我只希望接收前两个文档。
所以。我想只在结果中包含我要求的单词的主要思想。
我将不胜感激。
谢谢。
最佳答案
好吧,如果您存储TermVector(在创建Field
时,在将Document
添加到索引之前,请使用TermVector.YES
),可以通过重写收集器来完成。这是一个简单的实现(仅返回没有分数的文档):
private static class MyCollector extends Collector {
private IndexReader ir;
private int numberOfTerms;
private Set<Integer> set = new HashSet<Integer>();
public MyCollector(IndexReader ir,int numberOfTerms) {
this.ir = ir;
this.numberOfTerms = numberOfTerms;
}
@Override
public void setScorer(Scorer scorer) throws IOException { } //we do not use a scorer in this example
@Override
public void setNextReader(IndexReader reader, int docBase) {
//ignore
}
@Override
public void collect(int doc) throws IOException {
TermFreqVector vector = ir.getTermFreqVector(doc, CONTENT_FIELD);
//CONTENT_FILED is the name of the field you are searching in...
if (vector != null) {
if (vector.getTerms().length == numberOfTerms) {
set.add(doc);
}
} else {
set.add(doc); //well, assume it doesn't happen, because you stored your TermVectors.
}
}
@Override
public boolean acceptsDocsOutOfOrder() {
return true;
}
public Set<Integer> getSet() {
return set;
}
};
现在,使用
IndexSearcher#search(Query,Collector)
这个想法是:您知道要接受的文档中应包含多少个术语,因此您只需对其进行验证,然后仅收集与该规则匹配的文档。当然,这可能会更复杂(在“向量”中查找特定术语,在“向量”中查找单词顺序),但这是总的思路。
实际上,如果存储TermVector,则几乎可以执行任何操作,因此只需尝试使用它即可。