Fix `_exists_` in query_string on empty indices. (#25993)

It currently fails if there are no mappings yet.

Closes #25956
This commit is contained in:
Adrien Grand 2017-08-02 10:06:34 +02:00 committed by GitHub
parent 69f8641568
commit 58feb5efa0
3 changed files with 33 additions and 16 deletions

View File

@ -47,7 +47,6 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.analysis.ShingleTokenFilterFactory;
import org.elasticsearch.index.mapper.AllFieldMapper;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.index.mapper.DocumentMapper;
@ -683,6 +682,9 @@ public class QueryStringQueryParser extends XQueryParser {
private Query existsQuery(String fieldName) {
final FieldNamesFieldMapper.FieldNamesFieldType fieldNamesFieldType =
(FieldNamesFieldMapper.FieldNamesFieldType) context.getMapperService().fullName(FieldNamesFieldMapper.NAME);
if (fieldNamesFieldType == null) {
return new MatchNoDocsQuery("No mappings yet");
}
if (fieldNamesFieldType.isEnabled() == false) {
// The field_names_field is disabled so we switch to a wildcard query that matches all terms
return new WildcardQuery(new Term(fieldName, "*"));

View File

@ -779,12 +779,15 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
}
public void testExistsFieldQuery() throws Exception {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
QueryShardContext context = createShardContext();
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("foo:*");
Query query = queryBuilder.toQuery(context);
Query expected = new ConstantScoreQuery(new TermQuery(new Term("_field_names", "foo")));
Query expected;
if (getCurrentTypes().length > 0) {
expected = new ConstantScoreQuery(new TermQuery(new Term("_field_names", "foo")));
} else {
expected = new MatchNoDocsQuery();
}
assertThat(query, equalTo(expected));
queryBuilder = new QueryStringQueryBuilder("_all:*");
@ -804,6 +807,7 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
}
public void testDisabledFieldNamesField() throws Exception {
assumeTrue("No types", getCurrentTypes().length > 0);
QueryShardContext context = createShardContext();
context.getMapperService().merge("doc",
new CompressedXContent(
@ -811,16 +815,20 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
"foo", "type=text",
"_field_names", "enabled=false").string()),
MapperService.MergeReason.MAPPING_UPDATE, true);
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("foo:*");
Query query = queryBuilder.toQuery(context);
Query expected = new WildcardQuery(new Term("foo", "*"));
assertThat(query, equalTo(expected));
context.getMapperService().merge("doc",
new CompressedXContent(
PutMappingRequest.buildFromSimplifiedDef("doc",
"foo", "type=text",
"_field_names", "enabled=true").string()),
MapperService.MergeReason.MAPPING_UPDATE, true);
try {
QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder("foo:*");
Query query = queryBuilder.toQuery(context);
Query expected = new WildcardQuery(new Term("foo", "*"));
assertThat(query, equalTo(expected));
} finally {
// restore mappings as they were before
context.getMapperService().merge("doc",
new CompressedXContent(
PutMappingRequest.buildFromSimplifiedDef("doc",
"foo", "type=text",
"_field_names", "enabled=true").string()),
MapperService.MergeReason.MAPPING_UPDATE, true);
}
}

View File

@ -166,7 +166,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
protected static String[] getCurrentTypes() {
return currentTypes == null ? Strings.EMPTY_ARRAY : currentTypes;
return currentTypes;
}
protected Collection<Class<? extends Plugin>> getPlugins() {
@ -186,7 +186,14 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
index = new Index(randomAlphaOfLengthBetween(1, 10), "_na_");
// Set a single type in the index
currentTypes = new String[] { "doc" };
switch (random().nextInt(3)) {
case 0:
currentTypes = new String[0]; // no types
break;
default:
currentTypes = new String[] { "doc" };
break;
}
randomTypes = getRandomTypes();
}