Handle empty terms index in TermsSliceQuery (#43078)

#40741 introduced a merge policy that can drop the postings for the `_id`
field on soft deleted documents. The TermsSliceQuery assumes that every document
has has an entry in the postings for that field so it doesn't check if the terms
index exists or not. This change fixes this bug by checking if the terms index for
the `_id` field is null and ignore the segment entirely if it's the case. This should
be harmless since segments without an `_id` terms index should only contain soft deleted
documents.

Closes #42996
This commit is contained in:
Jim Ferenczi 2019-06-11 11:53:04 +02:00 committed by jimczi
parent 8de65daa45
commit 900eb4f882
2 changed files with 21 additions and 1 deletions

View File

@ -78,6 +78,9 @@ public final class TermsSliceQuery extends SliceQuery {
private DocIdSet build(LeafReader reader) throws IOException {
final DocIdSetBuilder builder = new DocIdSetBuilder(reader.maxDoc());
final Terms terms = reader.terms(getField());
if (terms == null) {
return DocIdSet.EMPTY;
}
final TermsEnum te = terms.iterator();
PostingsEnum docsEnum = null;
for (BytesRef term = te.next(); term != null; term = te.next()) {

View File

@ -46,7 +46,6 @@ import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
public class TermsSliceQueryTests extends ESTestCase {
public void testBasics() {
TermsSliceQuery query1 =
new TermsSliceQuery("field1", 1, 10);
@ -62,6 +61,24 @@ public class TermsSliceQueryTests extends ESTestCase {
QueryUtils.checkUnequal(query1, query4);
}
public void testEmpty() throws Exception {
final Directory dir = newDirectory();
final RandomIndexWriter w = new RandomIndexWriter(random(), dir, new KeywordAnalyzer());
for (int i = 0; i < 10; ++i) {
Document doc = new Document();
doc.add(new StringField("field", Integer.toString(i), Field.Store.YES));
w.addDocument(doc);
}
final IndexReader reader = w.getReader();
final IndexSearcher searcher = newSearcher(reader);
TermsSliceQuery query =
new TermsSliceQuery("unknown", 1, 1);
assertThat(searcher.count(query), equalTo(0));
w.close();
reader.close();
dir.close();
}
public void testSearch() throws Exception {
final int numDocs = randomIntBetween(100, 200);
final Directory dir = newDirectory();