2016-12-03 3 views
2

주어진 org.apache.lucene.util.Bits 개체에 org.apache.lucene.search.Query을 적용하는 방법은 무엇입니까?비트에 Lucene 쿼리 적용

배경 : "비트"에 대한 쿼리를 적용하여 livedocs를 필터링하려는 org.apache.lucene.index.FilterLeafReader의 하위 클래스가 있습니다.

getLiveDocs()을 무시하면 javadoc에 따르면 numDocs()을 재정의해야합니다. 그래서 질문합니다 (루씬 메일 링리스트에 질문을 한 후) 나는이 솔루션 결국

답변

1

(A FilterLeafReader 내) 쿼리를 기반으로 문서의 수를 필터링하는 방법으로도 확장 :

final IndexSearcher searcher = new IndexSearcher(reader); 
searcher.setQueryCache(null); 
final boolean needsScores = false; // scores are not needed, only matching docs 
final Weight preserveWeight = searcher.createNormalizedWeight(preserveFilter, needsScores); 
final int maxDoc = in.maxDoc(); 
final FixedBitSet bits = new FixedBitSet(maxDoc); 
// ignore livedocs here, as we filter them later: 
final Scorer preverveScorer = preserveWeight.scorer(context); 
if (preverveScorer != null) { 
    bits.or(preverveScorer.iterator()); 
} 
if (negateFilter) { 
    bits.flip(0, maxDoc); 
} 

if (in.hasDeletions()) { 
    final Bits oldLiveDocs = in.getLiveDocs(); 
    assert oldLiveDocs != null; 
    final DocIdSetIterator it = new BitSetIterator(bits, 0L); // the cost is not useful here 
    for (int i = it.nextDoc(); i != DocIdSetIterator.NO_MORE_DOCS; i = it.nextDoc()) { 
    if (!oldLiveDocs.get(i)) { 
     // we can safely modify the current bit, as the iterator already stepped over it: 
     bits.clear(i); 
    } 
} 
} 

this.liveDocs = bits; 
this.numDocs = bits.cardinality(); 

https://github.com/apache/lucene-solr/blob/master/lucene/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java#L127-L170