Skip to content

Commit 2cedeb5

Browse files
committed
Ensure that _exists queries on keyword fields use norms when they're available.
1 parent cd83ddc commit 2cedeb5

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.lucene.index.IndexableField;
2929
import org.apache.lucene.index.Term;
3030
import org.apache.lucene.search.DocValuesFieldExistsQuery;
31+
import org.apache.lucene.search.NormsFieldExistsQuery;
3132
import org.apache.lucene.search.Query;
3233
import org.apache.lucene.search.TermQuery;
3334
import org.apache.lucene.util.BytesRef;
@@ -256,8 +257,10 @@ public void setSplitQueriesOnWhitespace(boolean splitQueriesOnWhitespace) {
256257
public Query existsQuery(QueryShardContext context) {
257258
if (hasDocValues()) {
258259
return new DocValuesFieldExistsQuery(name());
259-
} else {
260+
} else if (omitNorms()) {
260261
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
262+
} else {
263+
return new NormsFieldExistsQuery(name());
261264
}
262265
}
263266

server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package org.elasticsearch.index.mapper;
2020

2121
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
22-
2322
import org.apache.lucene.analysis.Analyzer;
2423
import org.apache.lucene.analysis.LowerCaseFilter;
2524
import org.apache.lucene.analysis.TokenFilter;
@@ -28,9 +27,11 @@
2827
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
2928
import org.apache.lucene.index.IndexOptions;
3029
import org.apache.lucene.index.Term;
31-
import org.apache.lucene.search.TermInSetQuery;
30+
import org.apache.lucene.search.DocValuesFieldExistsQuery;
3231
import org.apache.lucene.search.FuzzyQuery;
32+
import org.apache.lucene.search.NormsFieldExistsQuery;
3333
import org.apache.lucene.search.RegexpQuery;
34+
import org.apache.lucene.search.TermInSetQuery;
3435
import org.apache.lucene.search.TermQuery;
3536
import org.apache.lucene.util.BytesRef;
3637
import org.elasticsearch.common.lucene.Lucene;
@@ -132,6 +133,23 @@ public void testTermsQuery() {
132133
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
133134
}
134135

136+
public void testExistsQuery() {
137+
MappedFieldType ft = createDefaultFieldType();
138+
ft.setName("field");
139+
140+
ft.setHasDocValues(true);
141+
ft.setOmitNorms(true);
142+
assertEquals(new DocValuesFieldExistsQuery("field"), ft.existsQuery(null));
143+
144+
ft.setHasDocValues(false);
145+
ft.setOmitNorms(false);
146+
assertEquals(new NormsFieldExistsQuery("field"), ft.existsQuery(null));
147+
148+
ft.setHasDocValues(false);
149+
ft.setOmitNorms(true);
150+
assertEquals(new TermQuery(new Term(FieldNamesFieldMapper.NAME, "field")), ft.existsQuery(null));
151+
}
152+
135153
public void testRegexpQuery() {
136154
MappedFieldType ft = createDefaultFieldType();
137155
ft.setName("field");

0 commit comments

Comments
 (0)