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,则几乎可以执行任何操作,因此只需尝试使用它即可。

08-03 13:22