From 900eb4f8826d115e770cefeb87cf5ea2135cdc67 Mon Sep 17 00:00:00 2001 From: Jim Ferenczi Date: Tue, 11 Jun 2019 11:53:04 +0200 Subject: [PATCH] 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 --- .../search/slice/TermsSliceQuery.java | 3 +++ .../search/slice/TermsSliceQueryTests.java | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/search/slice/TermsSliceQuery.java b/server/src/main/java/org/elasticsearch/search/slice/TermsSliceQuery.java index 52ac72d01b7..1ec34794241 100644 --- a/server/src/main/java/org/elasticsearch/search/slice/TermsSliceQuery.java +++ b/server/src/main/java/org/elasticsearch/search/slice/TermsSliceQuery.java @@ -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()) { diff --git a/server/src/test/java/org/elasticsearch/search/slice/TermsSliceQueryTests.java b/server/src/test/java/org/elasticsearch/search/slice/TermsSliceQueryTests.java index 881dc6f9587..9093e3e87a6 100644 --- a/server/src/test/java/org/elasticsearch/search/slice/TermsSliceQueryTests.java +++ b/server/src/test/java/org/elasticsearch/search/slice/TermsSliceQueryTests.java @@ -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();