Query DSL: `constant_score` should throw error on more than one filter

When specifying more than one `filter` in a `constant_score`
query, the last one will be the only one that will be
executed, overwriting previous filters. It should rather
raise a ParseException to notify the user that only one
filter query is accepted.

Closes #17126
This commit is contained in:
Christoph Büscher 2016-03-16 10:59:48 +01:00
parent 43f71d1ff5
commit 79356c8a3b
2 changed files with 50 additions and 12 deletions

View File

@ -42,7 +42,7 @@ public class ConstantScoreQueryParser implements QueryParser<ConstantScoreQueryB
public ConstantScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder query = null;
QueryBuilder<?> query = null;
boolean queryFound = false;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
@ -56,6 +56,10 @@ public class ConstantScoreQueryParser implements QueryParser<ConstantScoreQueryB
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, INNER_QUERY_FIELD)) {
if (queryFound) {
throw new ParsingException(parser.getTokenLocation(), "[" + ConstantScoreQueryBuilder.NAME + "]"
+ " accepts only one 'filter' element.");
}
query = parseContext.parseInnerQueryBuilder();
queryFound = true;
} else {
@ -69,6 +73,8 @@ public class ConstantScoreQueryParser implements QueryParser<ConstantScoreQueryB
} else {
throw new ParsingException(parser.getTokenLocation(), "[constant_score] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "]");
}
}
if (!queryFound) {

View File

@ -54,7 +54,7 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
* test that missing "filter" element causes {@link ParsingException}
*/
public void testFilterElement() throws IOException {
String queryString = "{ \"" + ConstantScoreQueryBuilder.NAME + "\" : {}";
String queryString = "{ \"" + ConstantScoreQueryBuilder.NAME + "\" : {} }";
try {
parseQuery(queryString);
fail("Expected ParsingException");
@ -63,6 +63,38 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
}
}
/**
* test that multiple "filter" elements causes {@link ParsingException}
*/
public void testMultipleFilterElements() throws IOException {
String queryString = "{ \"" + ConstantScoreQueryBuilder.NAME + "\" : {\n" +
"\"filter\" : { \"term\": { \"foo\": \"a\" } },\n" +
"\"filter\" : { \"term\": { \"foo\": \"x\" } },\n" +
"} }";
try {
parseQuery(queryString);
fail("Expected ParsingException");
} catch (ParsingException e) {
assertThat(e.getMessage(), containsString("accepts only one 'filter' element"));
}
}
/**
* test that "filter" does not accept an array of queries, throws {@link ParsingException}
*/
public void testNoArrayAsFilterElements() throws IOException {
String queryString = "{ \"" + ConstantScoreQueryBuilder.NAME + "\" : {\n" +
"\"filter\" : [ { \"term\": { \"foo\": \"a\" } },\n" +
"{ \"term\": { \"foo\": \"x\" } } ]\n" +
"} }";
try {
parseQuery(queryString);
fail("Expected ParsingException");
} catch (ParsingException e) {
assertThat(e.getMessage(), containsString("unexpected token [START_ARRAY]"));
}
}
public void testIllegalArguments() {
try {
new ConstantScoreQueryBuilder(null);
@ -79,16 +111,16 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
public void testFromJson() throws IOException {
String json =
"{\n" +
" \"constant_score\" : {\n" +
" \"filter\" : {\n" +
" \"terms\" : {\n" +
" \"user\" : [ \"kimchy\", \"elasticsearch\" ],\n" +
" \"boost\" : 42.0\n" +
" }\n" +
" },\n" +
" \"boost\" : 23.0\n" +
" }\n" +
"{\n" +
" \"constant_score\" : {\n" +
" \"filter\" : {\n" +
" \"terms\" : {\n" +
" \"user\" : [ \"kimchy\", \"elasticsearch\" ],\n" +
" \"boost\" : 42.0\n" +
" }\n" +
" },\n" +
" \"boost\" : 23.0\n" +
" }\n" +
"}";
ConstantScoreQueryBuilder parsed = (ConstantScoreQueryBuilder) parseQuery(json);