diff --git a/server/src/main/java/org/opensearch/index/mapper/BooleanFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/BooleanFieldMapper.java index 3ea70800d0763..7c4587f719f36 100644 --- a/server/src/main/java/org/opensearch/index/mapper/BooleanFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/BooleanFieldMapper.java @@ -39,10 +39,11 @@ import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.Term; import org.apache.lucene.search.BoostQuery; +import org.apache.lucene.search.FieldExistsQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.Query; -import org.apache.lucene.search.TermInSetQuery; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.util.BytesRef; @@ -283,19 +284,27 @@ public Query termQuery(Object value, QueryShardContext context) { @Override public Query termsQuery(List values, QueryShardContext context) { failIfNotIndexedAndNoDocValues(); - if (!isSearchable()) { - long[] v = new long[values.size()]; - for (int i = 0; i < v.length; i++) { - v[i] = Values.TRUE.bytesEquals(indexedValueForSearch(values.get(i))) ? 1 : 0; + boolean seenTrue = false; + boolean seenFalse = false; + for (Object value : values) { + if (Values.TRUE.equals(indexedValueForSearch(value))) { + seenTrue = true; + } else if (Values.FALSE.equals(indexedValueForSearch(value))) { + seenFalse = true; + } else { + return new MatchNoDocsQuery("Values did not contain True or False"); + } + } + if (seenTrue) { + if (seenFalse) { + return new FieldExistsQuery(name()); } - return SortedNumericDocValuesField.newSlowSetQuery(name(), v); + return termQuery("true", context); } - BytesRef[] bytesRefs = new BytesRef[values.size()]; - for (int i = 0; i < bytesRefs.length; i++) { - bytesRefs[i] = indexedValueForSearch(values.get(i)); + if (seenFalse) { + return termQuery("false", context); } - return new TermInSetQuery(name(), List.of(bytesRefs)); - + return new MatchNoDocsQuery("Values did not contain True or False"); } @Override diff --git a/server/src/test/java/org/opensearch/index/mapper/BooleanFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/BooleanFieldTypeTests.java index 6d077b1b188b4..33c30beef6c7d 100644 --- a/server/src/test/java/org/opensearch/index/mapper/BooleanFieldTypeTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/BooleanFieldTypeTests.java @@ -34,7 +34,7 @@ import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.index.Term; import org.apache.lucene.search.BoostQuery; -import org.apache.lucene.search.TermInSetQuery; +import org.apache.lucene.search.FieldExistsQuery; import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; @@ -42,7 +42,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.stream.Stream; public class BooleanFieldTypeTests extends FieldTypeTestCase { @@ -85,18 +84,15 @@ public void testTermsQuery() { List terms = new ArrayList<>(); terms.add(new BytesRef("true")); terms.add(new BytesRef("false")); - assertEquals(new TermInSetQuery("field", List.of(new BytesRef("T"), newBytesRef("F"))), ft.termsQuery(terms, null)); + assertEquals(new FieldExistsQuery("field"), ft.termsQuery(terms, null)); List newTerms = new ArrayList<>(); newTerms.add(new BytesRef("true")); - assertEquals(new TermInSetQuery("field", List.of(new BytesRef("T"))), ft.termsQuery(newTerms, null)); + assertEquals(new TermQuery(new Term("field", "T")), ft.termsQuery(newTerms, null)); MappedFieldType doc_only_ft = new BooleanFieldMapper.BooleanFieldType("field", false, true); - assertEquals( - SortedNumericDocValuesField.newSlowSetQuery("field", Stream.of(1).mapToLong(l -> l).toArray()), - doc_only_ft.termsQuery(newTerms, null) - ); + assertEquals(SortedNumericDocValuesField.newSlowExactQuery("field", 1), doc_only_ft.termsQuery(newTerms, null)); MappedFieldType unsearchable = new BooleanFieldMapper.BooleanFieldType("field", false, false); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> unsearchable.termsQuery(terms, null));