constant_score query might apply deletes wrongly, closes #477.

This commit is contained in:
kimchy 2010-11-04 20:18:05 +02:00
parent 770ccf421b
commit bbd63f0ffe
6 changed files with 29 additions and 39 deletions

View File

@ -58,6 +58,6 @@ public class MissingFieldQueryExtension implements FieldQueryExtension {
filter = wrapSmartNameFilter(filter, smartNameFieldMappers, parseContext);
return new DeletionAwareConstantScoreQuery(filter, true);
return new DeletionAwareConstantScoreQuery(filter);
}
}

View File

@ -33,15 +33,9 @@ import java.util.Set;
// See more: https://issues.apache.org/jira/browse/LUCENE-2468
public class DeletionAwareConstantScoreQuery extends Query {
protected final Filter filter;
protected final boolean deletionAware;
public DeletionAwareConstantScoreQuery(Filter filter) {
this(filter, false);
}
public DeletionAwareConstantScoreQuery(Filter filter, boolean deletionAware) {
this.filter = filter;
this.deletionAware = deletionAware;
}
/**
@ -102,7 +96,7 @@ public class DeletionAwareConstantScoreQuery extends Query {
public Explanation explain(IndexReader reader, int doc) throws IOException {
ConstantScorer cs = new ConstantScorer(similarity, reader, this);
boolean exists = cs.docIdSetIterator.advance(doc) == doc;
boolean exists = cs._innerIter.advance(doc) == doc;
ComplexExplanation result = new ComplexExplanation();
@ -125,8 +119,9 @@ public class DeletionAwareConstantScoreQuery extends Query {
protected class ConstantScorer extends Scorer {
final IndexReader reader;
final DocIdSetIterator docIdSetIterator;
final DocIdSetIterator _innerIter;
final float theScore;
private int doc = -1;
public ConstantScorer(Similarity similarity, IndexReader reader, Weight w) throws IOException {
super(similarity);
@ -134,35 +129,30 @@ public class DeletionAwareConstantScoreQuery extends Query {
theScore = w.getValue();
DocIdSet docIdSet = filter.getDocIdSet(reader);
if (docIdSet == null) {
docIdSetIterator = DocIdSet.EMPTY_DOCIDSET.iterator();
_innerIter = DocIdSet.EMPTY_DOCIDSET.iterator();
} else {
DocIdSetIterator iter = docIdSet.iterator();
if (iter == null) {
docIdSetIterator = DocIdSet.EMPTY_DOCIDSET.iterator();
_innerIter = DocIdSet.EMPTY_DOCIDSET.iterator();
} else {
docIdSetIterator = iter;
_innerIter = iter;
}
}
}
@Override
public int nextDoc() throws IOException {
if (deletionAware) {
int nextDoc;
while ((nextDoc = docIdSetIterator.nextDoc()) != NO_MORE_DOCS) {
if (!reader.isDeleted(nextDoc)) {
return nextDoc;
while ((doc = _innerIter.nextDoc()) != NO_MORE_DOCS) {
if (!reader.isDeleted(doc)) {
return doc;
}
}
return nextDoc;
} else {
return docIdSetIterator.nextDoc();
}
return doc;
}
@Override
public int docID() {
return docIdSetIterator.docID();
return doc;
}
@Override
@ -172,24 +162,21 @@ public class DeletionAwareConstantScoreQuery extends Query {
@Override
public int advance(int target) throws IOException {
if (deletionAware) {
int doc = docIdSetIterator.advance(target);
if (doc == NO_MORE_DOCS) {
return doc;
}
doc = _innerIter.advance(target);
if (doc != NO_MORE_DOCS) {
if (!reader.isDeleted(doc)) {
return doc;
}
while ((doc = nextDoc()) < target) {
if (!reader.isDeleted(doc)) {
return doc;
}
}
return doc;
} else {
return docIdSetIterator.advance(target);
while ((doc = _innerIter.nextDoc()) != NO_MORE_DOCS) {
if (!reader.isDeleted(doc)) {
return doc;
}
}
return doc;
}
}
return doc;
}
}
@Override

View File

@ -30,7 +30,7 @@ import java.util.List;
public class Queries {
// We don't use MatchAllDocsQuery, its slower than the one below ... (much slower)
public final static Query MATCH_ALL_QUERY = new DeletionAwareConstantScoreQuery(new MatchAllDocsFilter(), true);
public final static Query MATCH_ALL_QUERY = new DeletionAwareConstantScoreQuery(new MatchAllDocsFilter());
/**
* A match all docs filter. Note, requires no caching!.

View File

@ -81,7 +81,7 @@ public class ConstantScoreQueryParser extends AbstractIndexComponent implements
filter = parseContext.cacheFilter(filter);
}
Query query = new DeletionAwareConstantScoreQuery(filter, true);
Query query = new DeletionAwareConstantScoreQuery(filter);
query.setBoost(boost);
return query;
}

View File

@ -19,7 +19,10 @@
package org.elasticsearch.search.facet;
import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FilterClause;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.Lists;
@ -61,7 +64,7 @@ public class FacetsPhase implements SearchPhase {
// run global facets ...
if (context.searcher().globalCollectors() != null) {
Query query = new DeletionAwareConstantScoreQuery(Queries.MATCH_ALL_FILTER, true); // no need to cache a MATCH ALL FILTER
Query query = Queries.MATCH_ALL_QUERY;
if (context.types().length > 0) {
if (context.types().length == 1) {
String type = context.types()[0];

View File

@ -82,7 +82,7 @@ public class FilterCacheTests {
long constantScoreCount = filter == cachedFilter ? 0 : 1;
// sadly, when caching based on cacheKey with NRT, this fails, that's why we have DeletionAware one
assertThat(Lucene.count(searcher, new ConstantScoreQuery(cachedFilter), -1), equalTo(constantScoreCount));
assertThat(Lucene.count(searcher, new DeletionAwareConstantScoreQuery(cachedFilter, true), -1), equalTo(0l));
assertThat(Lucene.count(searcher, new DeletionAwareConstantScoreQuery(cachedFilter), -1), equalTo(0l));
assertThat(Lucene.count(searcher, new FilteredQuery(new MatchAllDocsQuery(), cachedFilter), -1), equalTo(0l));
indexWriter.close();