Skip to content

Commit 15f95a9

Browse files
author
Christoph Büscher
authored
Fix range queries on _type field for singe type indices (#31756)
With the introduction of single types in 6.x, the `_type` field is no longer indexed, which leads to certain queries that were working before throw errors now. One such query is the `range` query, that, if performed on a single typer index, currently throws an IAE since the field is not indexed. This change adds special treatment for this case in the TypeFieldMapper, comparing the range queries lower and upper bound to the one existing type and either returns a MatchAllDocs or a MatchNoDocs query. Relates to #31632 Closes #31476
1 parent 487cfc3 commit 15f95a9

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import org.apache.lucene.search.TermInSetQuery;
3636
import org.apache.lucene.search.TermQuery;
3737
import org.apache.lucene.util.BytesRef;
38+
import org.elasticsearch.common.logging.DeprecationLogger;
39+
import org.elasticsearch.common.logging.ESLoggerFactory;
3840
import org.elasticsearch.common.lucene.Lucene;
3941
import org.elasticsearch.common.lucene.search.Queries;
4042
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -90,6 +92,8 @@ public MetadataFieldMapper getDefault(MappedFieldType fieldType, ParserContext c
9092

9193
static final class TypeFieldType extends StringFieldType {
9294

95+
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(ESLoggerFactory.getLogger(TypeFieldType.class));
96+
9397
TypeFieldType() {
9498
}
9599

@@ -154,6 +158,29 @@ public Query termsQuery(List<?> values, QueryShardContext context) {
154158
}
155159
}
156160

161+
@Override
162+
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) {
163+
DEPRECATION_LOGGER.deprecatedAndMaybeLog("range_single_type",
164+
"Running [range] query on [_type] field for an index with a single type. As types are deprecated, this functionality will be removed in future releases.");
165+
Query result = new MatchAllDocsQuery();
166+
String type = context.getMapperService().documentMapper().type();
167+
if (type != null) {
168+
BytesRef typeBytes = new BytesRef(type);
169+
if (lowerTerm != null) {
170+
int comp = indexedValueForSearch(lowerTerm).compareTo(typeBytes);
171+
if (comp > 0 || (comp == 0 && includeLower == false)) {
172+
result = new MatchNoDocsQuery("[_type] was lexicographically smaller than lower bound of range");
173+
}
174+
}
175+
if (upperTerm != null) {
176+
int comp = indexedValueForSearch(upperTerm).compareTo(typeBytes);
177+
if (comp < 0 || (comp == 0 && includeUpper == false)) {
178+
result = new MatchNoDocsQuery("[_type] was lexicographically greater than upper bound of range");
179+
}
180+
}
181+
}
182+
return result;
183+
}
157184
}
158185

159186
/**

server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,4 +1822,40 @@ public void testRangeQueryRangeFields_24744() throws Exception {
18221822
SearchResponse searchResponse = client().prepareSearch("test").setQuery(range).get();
18231823
assertHitCount(searchResponse, 1);
18241824
}
1825+
1826+
public void testRangeQueryTypeField_31476() throws Exception {
1827+
assertAcked(prepareCreate("test").addMapping("foo", "field", "type=keyword"));
1828+
1829+
client().prepareIndex("test", "foo", "1").setSource("field", "value").get();
1830+
refresh();
1831+
1832+
RangeQueryBuilder range = new RangeQueryBuilder("_type").from("ape").to("zebra");
1833+
SearchResponse searchResponse = client().prepareSearch("test").setQuery(range).get();
1834+
assertHitCount(searchResponse, 1);
1835+
1836+
range = new RangeQueryBuilder("_type").from("monkey").to("zebra");
1837+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1838+
assertHitCount(searchResponse, 0);
1839+
1840+
range = new RangeQueryBuilder("_type").from("ape").to("donkey");
1841+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1842+
assertHitCount(searchResponse, 0);
1843+
1844+
range = new RangeQueryBuilder("_type").from("ape").to("foo").includeUpper(false);
1845+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1846+
assertHitCount(searchResponse, 0);
1847+
1848+
range = new RangeQueryBuilder("_type").from("ape").to("foo").includeUpper(true);
1849+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1850+
assertHitCount(searchResponse, 1);
1851+
1852+
range = new RangeQueryBuilder("_type").from("foo").to("zebra").includeLower(false);
1853+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1854+
assertHitCount(searchResponse, 0);
1855+
1856+
range = new RangeQueryBuilder("_type").from("foo").to("zebra").includeLower(true);
1857+
searchResponse = client().prepareSearch("test").setQuery(range).get();
1858+
assertHitCount(searchResponse, 1);
1859+
}
1860+
18251861
}

0 commit comments

Comments
 (0)