support in compound queries / filter parsers for lower level ones returning null as the result of parsing the inner query / filter.
This commit is contained in:
parent
4b5c89478c
commit
0998f3f8a6
|
@ -33,6 +33,7 @@ public class Queries {
|
|||
|
||||
// We don't use MatchAllDocsQuery, its slower than the one below ... (much slower)
|
||||
public final static Query MATCH_ALL_QUERY = new DeletionAwareConstantScoreQuery(new MatchAllDocsFilter());
|
||||
public final static Query NO_MATCH_QUERY = MatchNoDocsQuery.INSTANCE;
|
||||
|
||||
/**
|
||||
* A match all docs filter. Note, requires no caching!.
|
||||
|
|
|
@ -51,6 +51,7 @@ public class AndFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
ArrayList<Filter> filters = newArrayList();
|
||||
boolean filtersFound = false;
|
||||
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
@ -60,7 +61,11 @@ public class AndFilterParser implements FilterParser {
|
|||
XContentParser.Token token = parser.currentToken();
|
||||
if (token == XContentParser.Token.START_ARRAY) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
filtersFound = true;
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
|
@ -68,12 +73,20 @@ public class AndFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("filters".equals(currentFieldName)) {
|
||||
filtersFound = true;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filtersFound = true;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
|
@ -90,10 +103,14 @@ public class AndFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (filters.isEmpty()) {
|
||||
if (!filtersFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[and] filter requires 'filters' to be set on it'");
|
||||
}
|
||||
|
||||
if (filters.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// no need to cache this one
|
||||
Filter filter = new AndFilter(filters);
|
||||
if (cache) {
|
||||
|
|
|
@ -62,26 +62,44 @@ public class BoolFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("must".equals(currentFieldName)) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.MUST));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.MUST));
|
||||
}
|
||||
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.MUST_NOT));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.MUST_NOT));
|
||||
}
|
||||
} else if ("should".equals(currentFieldName)) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.SHOULD));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[bool] filter does not support [" + currentFieldName + "]");
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("must".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.MUST));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.MUST));
|
||||
}
|
||||
}
|
||||
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.MUST_NOT));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.MUST_NOT));
|
||||
}
|
||||
}
|
||||
} else if ("should".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
boolFilter.add(new FilterClause(parseContext.parseInnerFilter(), BooleanClause.Occur.SHOULD));
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
boolFilter.add(new FilterClause(filter, BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[bool] filter does not support [" + currentFieldName + "]");
|
||||
|
@ -99,6 +117,10 @@ public class BoolFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (boolFilter.getMustFilters().isEmpty() && boolFilter.getNotFilters().isEmpty() && boolFilter.getShouldFilters().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Filter filter = boolFilter;
|
||||
if (cache) {
|
||||
filter = parseContext.cacheFilter(filter, cacheKey);
|
||||
|
|
|
@ -67,26 +67,44 @@ public class BoolQueryParser implements QueryParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("must".equals(currentFieldName)) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.MUST));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST));
|
||||
}
|
||||
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.MUST_NOT));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT));
|
||||
}
|
||||
} else if ("should".equals(currentFieldName)) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.SHOULD));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("must".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.MUST));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST));
|
||||
}
|
||||
}
|
||||
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.MUST_NOT));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT));
|
||||
}
|
||||
}
|
||||
} else if ("should".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
clauses.add(new BooleanClause(parseContext.parseInnerQuery(), BooleanClause.Occur.SHOULD));
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
clauses.add(new BooleanClause(query, BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "bool query does not support [" + currentFieldName + "]");
|
||||
|
@ -106,6 +124,10 @@ public class BoolQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (clauses.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clauses.size() == 1) {
|
||||
BooleanClause clause = clauses.get(0);
|
||||
if (clause.getOccur() == BooleanClause.Occur.MUST) {
|
||||
|
|
|
@ -47,7 +47,9 @@ public class BoostingQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query positiveQuery = null;
|
||||
boolean positiveQueryFound = false;
|
||||
Query negativeQuery = null;
|
||||
boolean negativeQueryFound = false;
|
||||
float boost = -1;
|
||||
float negativeBoost = -1;
|
||||
|
||||
|
@ -59,8 +61,10 @@ public class BoostingQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("positive".equals(currentFieldName)) {
|
||||
positiveQuery = parseContext.parseInnerQuery();
|
||||
positiveQueryFound = true;
|
||||
} else if ("negative".equals(currentFieldName)) {
|
||||
negativeQuery = parseContext.parseInnerQuery();
|
||||
negativeQueryFound = true;
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[boosting] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -75,16 +79,21 @@ public class BoostingQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (positiveQuery == null) {
|
||||
if (positiveQuery == null && !positiveQueryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[boosting] query requires 'positive' query to be set'");
|
||||
}
|
||||
if (negativeQuery == null) {
|
||||
if (negativeQuery == null && !negativeQueryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[boosting] query requires 'negative' query to be set'");
|
||||
}
|
||||
if (negativeBoost == -1) {
|
||||
throw new QueryParsingException(parseContext.index(), "[boosting] query requires 'negative_boost' to be set'");
|
||||
}
|
||||
|
||||
// parsers returned null
|
||||
if (positiveQuery == null || negativeQuery == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BoostingQuery boostingQuery = new BoostingQuery(positiveQuery, negativeQuery, negativeBoost);
|
||||
if (boost != -1) {
|
||||
boostingQuery.setBoost(boost);
|
||||
|
|
|
@ -51,7 +51,9 @@ public class ConstantScoreQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
@ -64,8 +66,10 @@ public class ConstantScoreQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("filter".equals(currentFieldName)) {
|
||||
filter = parseContext.parseInnerFilter();
|
||||
filterFound = true;
|
||||
} else if ("query".equals(currentFieldName)) {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[constant_score] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -81,10 +85,14 @@ public class ConstantScoreQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (filter == null && query == null) {
|
||||
if (!filterFound && !queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[constant_score] requires either 'filter' or 'query' element");
|
||||
}
|
||||
|
||||
if (query == null && filter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (filter != null) {
|
||||
// cache the filter if possible needed
|
||||
if (cache) {
|
||||
|
|
|
@ -49,6 +49,7 @@ public class CustomBoostFactorQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
float boostFactor = 1.0f;
|
||||
|
||||
|
@ -60,6 +61,7 @@ public class CustomBoostFactorQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_boost_factor] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -73,9 +75,12 @@ public class CustomBoostFactorQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[constant_factor_query] requires 'query' element");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
FunctionScoreQuery functionScoreQuery = new FunctionScoreQuery(query, new BoostScoreFunction(boostFactor));
|
||||
functionScoreQuery.setBoost(boost);
|
||||
return functionScoreQuery;
|
||||
|
|
|
@ -55,12 +55,14 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
String scriptLang = null;
|
||||
Map<String, Object> vars = null;
|
||||
|
||||
FiltersFunctionScoreQuery.ScoreMode scoreMode = FiltersFunctionScoreQuery.ScoreMode.First;
|
||||
ArrayList<Filter> filters = new ArrayList<Filter>();
|
||||
boolean filtersFound = false;
|
||||
ArrayList<String> scripts = new ArrayList<String>();
|
||||
TFloatArrayList boosts = new TFloatArrayList();
|
||||
|
||||
|
@ -72,6 +74,7 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} else if ("params".equals(currentFieldName)) {
|
||||
vars = parser.map();
|
||||
} else {
|
||||
|
@ -79,9 +82,11 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
}
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("filters".equals(currentFieldName)) {
|
||||
filtersFound = true;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
String script = null;
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
float fboost = Float.NaN;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
|
@ -89,6 +94,7 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("filter".equals(currentFieldName)) {
|
||||
filter = parseContext.parseInnerFilter();
|
||||
filterFound = true;
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if ("script".equals(currentFieldName)) {
|
||||
|
@ -101,13 +107,15 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
if (script == null && fboost == -1) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] missing 'script' or 'boost' in filters array element");
|
||||
}
|
||||
if (filter == null) {
|
||||
if (!filterFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] missing 'filter' in filters array element");
|
||||
}
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
scripts.add(script);
|
||||
boosts.add(fboost);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -138,12 +146,19 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] requires 'query' field");
|
||||
}
|
||||
if (filters.isEmpty()) {
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
if (!filtersFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] requires 'filters' field");
|
||||
}
|
||||
// if all filter elements returned null, just use the query
|
||||
if (filters.isEmpty()) {
|
||||
return query;
|
||||
}
|
||||
|
||||
FiltersFunctionScoreQuery.FilterFunction[] filterFunctions = new FiltersFunctionScoreQuery.FilterFunction[filters.size()];
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
|
|
|
@ -53,6 +53,7 @@ public class CustomScoreQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
String script = null;
|
||||
String scriptLang = null;
|
||||
|
@ -66,6 +67,7 @@ public class CustomScoreQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} else if ("params".equals(currentFieldName)) {
|
||||
vars = parser.map();
|
||||
} else {
|
||||
|
@ -83,12 +85,15 @@ public class CustomScoreQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_score] requires 'query' field");
|
||||
}
|
||||
if (script == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[custom_score] requires 'script' field");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SearchScript searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptLang, script, vars);
|
||||
FunctionScoreQuery functionScoreQuery = new FunctionScoreQuery(query, new ScriptScoreFunction(script, vars, searchScript));
|
||||
|
|
|
@ -54,6 +54,7 @@ public class DisMaxQueryParser implements QueryParser {
|
|||
float tieBreaker = 0.0f;
|
||||
|
||||
List<Query> queries = newArrayList();
|
||||
boolean queriesFound = false;
|
||||
|
||||
String currentFieldName = null;
|
||||
XContentParser.Token token;
|
||||
|
@ -62,14 +63,22 @@ public class DisMaxQueryParser implements QueryParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("queries".equals(currentFieldName)) {
|
||||
queries.add(parseContext.parseInnerQuery());
|
||||
queriesFound = true;
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
queries.add(query);
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("queries".equals(currentFieldName)) {
|
||||
queriesFound = true;
|
||||
while (token != XContentParser.Token.END_ARRAY) {
|
||||
queries.add(parseContext.parseInnerQuery());
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query != null) {
|
||||
queries.add(query);
|
||||
}
|
||||
token = parser.nextToken();
|
||||
}
|
||||
} else {
|
||||
|
@ -86,6 +95,14 @@ public class DisMaxQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (!queriesFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[dis_max] requires 'queries' field");
|
||||
}
|
||||
|
||||
if (queries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker);
|
||||
query.setBoost(boost);
|
||||
return query;
|
||||
|
|
|
@ -50,6 +50,7 @@ public class FQueryFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
||||
|
@ -61,6 +62,7 @@ public class FQueryFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
queryFound = true;
|
||||
query = parseContext.parseInnerQuery();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[fquery] filter does not support [" + currentFieldName + "]");
|
||||
|
@ -77,6 +79,12 @@ public class FQueryFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[fquery] requires 'query' element");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
Filter filter = new QueryWrapperFilter(query);
|
||||
if (cache) {
|
||||
filter = parseContext.cacheFilter(filter, cacheKey);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -37,5 +38,6 @@ public interface FilterParser {
|
|||
* Parses the into a filter from the current parser location. Will be at "START_OBJECT" location,
|
||||
* and should end when the token is at the matching "END_OBJECT".
|
||||
*/
|
||||
@Nullable
|
||||
Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException;
|
||||
}
|
|
@ -51,7 +51,9 @@ public class FilteredQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
float boost = 1.0f;
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
@ -63,8 +65,10 @@ public class FilteredQueryParser implements QueryParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
queryFound = true;
|
||||
query = parseContext.parseInnerQuery();
|
||||
} else if ("filter".equals(currentFieldName)) {
|
||||
filterFound = true;
|
||||
filter = parseContext.parseInnerFilter();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[filtered] query does not support [" + currentFieldName + "]");
|
||||
|
@ -81,12 +85,21 @@ public class FilteredQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[filtered] requires 'query' element");
|
||||
}
|
||||
// we allow for null filter, so it makes compositions on the client side to be simpler
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
if (filter == null) {
|
||||
if (!filterFound) {
|
||||
// we allow for null filter, so it makes compositions on the client side to be simpler
|
||||
return query;
|
||||
} else {
|
||||
// the filter was provided, but returned null, meaning we should discard it, this means no
|
||||
// matches for this query...
|
||||
return Queries.NO_MATCH_QUERY;
|
||||
}
|
||||
}
|
||||
|
||||
// cache if required
|
||||
|
|
|
@ -52,6 +52,7 @@ public class HasChildFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
String childType = null;
|
||||
String scope = null;
|
||||
|
||||
|
@ -68,6 +69,7 @@ public class HasChildFilterParser implements FilterParser {
|
|||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||
try {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} finally {
|
||||
QueryParseContext.setTypes(origTypes);
|
||||
}
|
||||
|
@ -86,9 +88,12 @@ public class HasChildFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[child] filter requires 'query' field");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
if (childType == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[child] filter requires 'type' field");
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public class HasChildQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
String childType = null;
|
||||
String scope = null;
|
||||
|
@ -68,6 +69,7 @@ public class HasChildQueryParser implements QueryParser {
|
|||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||
try {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} finally {
|
||||
QueryParseContext.setTypes(origTypes);
|
||||
}
|
||||
|
@ -86,9 +88,12 @@ public class HasChildQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[has_child] requires 'query' field");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
if (childType == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[has_child] requires 'type' field");
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.ElasticSearchException;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.BytesStream;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -232,12 +233,14 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Filter parseInnerFilter(XContentParser parser) throws IOException {
|
||||
QueryParseContext context = cache.get();
|
||||
context.reset(parser);
|
||||
return context.parseInnerFilter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Query parseInnerQuery(XContentParser parser) throws IOException {
|
||||
QueryParseContext context = cache.get();
|
||||
context.reset(parser);
|
||||
|
@ -247,6 +250,9 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
|||
private ParsedQuery parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
|
||||
parseContext.reset(parser);
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query == null) {
|
||||
query = Queries.NO_MATCH_QUERY;
|
||||
}
|
||||
return new ParsedQuery(query, parseContext.copyNamedFilters());
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ public class IndicesFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
Set<String> indices = Sets.newHashSet();
|
||||
|
||||
String currentFieldName = null;
|
||||
|
@ -66,6 +67,7 @@ public class IndicesFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("filter".equals(currentFieldName)) {
|
||||
filterFound = true;
|
||||
filter = parseContext.parseInnerFilter();
|
||||
} else if ("no_match_filter".equals(currentFieldName)) {
|
||||
noMatchFilter = parseContext.parseInnerFilter();
|
||||
|
@ -99,13 +101,17 @@ public class IndicesFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (filter == null) {
|
||||
if (!filterFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'filter' element");
|
||||
}
|
||||
if (indices.isEmpty()) {
|
||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
||||
}
|
||||
|
||||
if (filter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] concreteIndices = indices.toArray(new String[indices.size()]);
|
||||
if (clusterService != null) {
|
||||
MetaData metaData = clusterService.state().metaData();
|
||||
|
|
|
@ -57,6 +57,7 @@ public class IndicesQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
Set<String> indices = Sets.newHashSet();
|
||||
|
||||
String currentFieldName = null;
|
||||
|
@ -68,6 +69,7 @@ public class IndicesQueryParser implements QueryParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
query = parseContext.parseInnerQuery();
|
||||
queryFound = true;
|
||||
} else if ("no_match_query".equals(currentFieldName)) {
|
||||
noMatchQuery = parseContext.parseInnerQuery();
|
||||
} else {
|
||||
|
@ -100,9 +102,12 @@ public class IndicesQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'query' element");
|
||||
}
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
if (indices.isEmpty()) {
|
||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
||||
}
|
||||
|
|
|
@ -50,7 +50,9 @@ public class NestedFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
float boost = 1.0f;
|
||||
String scope = null;
|
||||
String path = null;
|
||||
|
@ -72,8 +74,10 @@ public class NestedFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
queryFound = true;
|
||||
query = parseContext.parseInnerQuery();
|
||||
} else if ("filter".equals(currentFieldName)) {
|
||||
filterFound = true;
|
||||
filter = parseContext.parseInnerFilter();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] filter does not support [" + currentFieldName + "]");
|
||||
|
@ -96,13 +100,17 @@ public class NestedFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null && filter == null) {
|
||||
if (!queryFound && !filterFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] requires either 'query' or 'filter' field");
|
||||
}
|
||||
if (path == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
||||
}
|
||||
|
||||
if (query == null && filter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (filter != null) {
|
||||
query = new DeletionAwareConstantScoreQuery(filter);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,9 @@ public class NestedQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
float boost = 1.0f;
|
||||
String scope = null;
|
||||
String path = null;
|
||||
|
@ -70,8 +72,10 @@ public class NestedQueryParser implements QueryParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
queryFound = true;
|
||||
query = parseContext.parseInnerQuery();
|
||||
} else if ("filter".equals(currentFieldName)) {
|
||||
filterFound = true;
|
||||
filter = parseContext.parseInnerFilter();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] query does not support [" + currentFieldName + "]");
|
||||
|
@ -101,13 +105,17 @@ public class NestedQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null && filter == null) {
|
||||
if (!queryFound && !filterFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] requires either 'query' or 'filter' field");
|
||||
}
|
||||
if (path == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
||||
}
|
||||
|
||||
if (query == null && filter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (filter != null) {
|
||||
query = new DeletionAwareConstantScoreQuery(filter);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public class NotFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Filter filter = null;
|
||||
boolean filterFound = false;
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
||||
|
@ -60,7 +61,9 @@ public class NotFilterParser implements FilterParser {
|
|||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("filter".equals(currentFieldName)) {
|
||||
filter = parseContext.parseInnerFilter();
|
||||
filterFound = true;
|
||||
} else {
|
||||
filterFound = true;
|
||||
// its the filter, and the name is the field
|
||||
filter = parseContext.parseInnerFilter(currentFieldName);
|
||||
}
|
||||
|
@ -77,10 +80,14 @@ public class NotFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (filter == null) {
|
||||
if (!filterFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "filter is required when using `not` filter");
|
||||
}
|
||||
|
||||
if (filter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Filter notFilter = new NotFilter(filter);
|
||||
if (cache) {
|
||||
notFilter = parseContext.cacheFilter(notFilter, cacheKey);
|
||||
|
|
|
@ -51,6 +51,7 @@ public class OrFilterParser implements FilterParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
ArrayList<Filter> filters = newArrayList();
|
||||
boolean filtersFound = false;
|
||||
|
||||
boolean cache = false;
|
||||
CacheKeyFilter.Key cacheKey = null;
|
||||
|
@ -60,7 +61,11 @@ public class OrFilterParser implements FilterParser {
|
|||
XContentParser.Token token = parser.currentToken();
|
||||
if (token == XContentParser.Token.START_ARRAY) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
filtersFound = true;
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
|
@ -68,12 +73,20 @@ public class OrFilterParser implements FilterParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("filters".equals(currentFieldName)) {
|
||||
filtersFound = true;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
filters.add(parseContext.parseInnerFilter());
|
||||
filtersFound = true;
|
||||
Filter filter = parseContext.parseInnerFilter();
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
|
@ -90,10 +103,14 @@ public class OrFilterParser implements FilterParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (filters.isEmpty()) {
|
||||
if (!filtersFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[or] filter requires 'filters' to be set on it'");
|
||||
}
|
||||
|
||||
if (filters.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// no need to cache this one
|
||||
Filter filter = new OrFilter(filters);
|
||||
if (cache) {
|
||||
|
|
|
@ -45,6 +45,9 @@ public class QueryFilterParser implements FilterParser {
|
|||
@Override
|
||||
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
Query query = parseContext.parseInnerQuery();
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
return new QueryWrapperFilter(query);
|
||||
}
|
||||
}
|
|
@ -160,6 +160,7 @@ public class QueryParseContext {
|
|||
return ImmutableMap.copyOf(namedFilters);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Query parseInnerQuery() throws IOException, QueryParsingException {
|
||||
// move to START object
|
||||
XContentParser.Token token;
|
||||
|
@ -192,6 +193,7 @@ public class QueryParseContext {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Filter parseInnerFilter() throws IOException, QueryParsingException {
|
||||
// move to START object
|
||||
XContentParser.Token token;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -36,6 +37,9 @@ public interface QueryParser {
|
|||
/**
|
||||
* Parses the into a query from the current parser location. Will be at "START_OBJECT" location,
|
||||
* and should end when the token is at the matching "END_OBJECT".
|
||||
* <p/>
|
||||
* Returns <tt>null</tt> if this query should be ignored in the context of the DSL.
|
||||
*/
|
||||
@Nullable
|
||||
Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
|||
XContentParser parser = parseContext.parser();
|
||||
|
||||
Query query = null;
|
||||
boolean queryFound = false;
|
||||
float boost = 1.0f;
|
||||
String childType = null;
|
||||
String scope = null;
|
||||
|
@ -65,6 +66,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("query".equals(currentFieldName)) {
|
||||
queryFound = true;
|
||||
// TODO we need to set the type, but, `query` can come before `type`... (see HasChildFilterParser)
|
||||
// since we switch types, make sure we change the context
|
||||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||
|
@ -94,13 +96,17 @@ public class TopChildrenQueryParser implements QueryParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (query == null) {
|
||||
if (!queryFound) {
|
||||
throw new QueryParsingException(parseContext.index(), "[child] requires 'query' field");
|
||||
}
|
||||
if (childType == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "[child] requires 'type' field");
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DocumentMapper childDocMapper = parseContext.mapperService().documentMapper(childType);
|
||||
if (childDocMapper == null) {
|
||||
throw new QueryParsingException(parseContext.index(), "No mapping for for type [" + childType + "]");
|
||||
|
|
Loading…
Reference in New Issue