хорошо, если вы храните свой TermVector (при создании Field
, прежде чем добавить Document
в индекс, используйте TermVector.YES
), это можно сделать, переопределив Collector.Вот простая реализация (которая возвращает только документы без оценок):
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, вы можете сделать почтичто угодно, так что попробуйте поработать с ним.