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)
|
// 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 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!.
|
* A match all docs filter. Note, requires no caching!.
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class AndFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
ArrayList<Filter> filters = newArrayList();
|
ArrayList<Filter> filters = newArrayList();
|
||||||
|
boolean filtersFound = false;
|
||||||
|
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
@ -60,7 +61,11 @@ public class AndFilterParser implements FilterParser {
|
||||||
XContentParser.Token token = parser.currentToken();
|
XContentParser.Token token = parser.currentToken();
|
||||||
if (token == XContentParser.Token.START_ARRAY) {
|
if (token == XContentParser.Token.START_ARRAY) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_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 {
|
} else {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
@ -68,12 +73,20 @@ public class AndFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("filters".equals(currentFieldName)) {
|
if ("filters".equals(currentFieldName)) {
|
||||||
|
filtersFound = true;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
filters.add(parseContext.parseInnerFilter());
|
Filter filter = parseContext.parseInnerFilter();
|
||||||
|
if (filter != null) {
|
||||||
|
filters.add(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
filtersFound = true;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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()) {
|
} 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'");
|
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
|
// no need to cache this one
|
||||||
Filter filter = new AndFilter(filters);
|
Filter filter = new AndFilter(filters);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
|
|
|
@ -62,26 +62,44 @@ public class BoolFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("must".equals(currentFieldName)) {
|
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)) {
|
} 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)) {
|
} 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 {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[bool] filter does not support [" + currentFieldName + "]");
|
throw new QueryParsingException(parseContext.index(), "[bool] filter does not support [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("must".equals(currentFieldName)) {
|
if ("must".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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)) {
|
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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)) {
|
} else if ("should".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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 {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[bool] filter does not support [" + currentFieldName + "]");
|
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;
|
Filter filter = boolFilter;
|
||||||
if (cache) {
|
if (cache) {
|
||||||
filter = parseContext.cacheFilter(filter, cacheKey);
|
filter = parseContext.cacheFilter(filter, cacheKey);
|
||||||
|
|
|
@ -67,26 +67,44 @@ public class BoolQueryParser implements QueryParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("must".equals(currentFieldName)) {
|
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)) {
|
} 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)) {
|
} 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 {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]");
|
throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("must".equals(currentFieldName)) {
|
if ("must".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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)) {
|
} else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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)) {
|
} else if ("should".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
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 {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "bool query does not support [" + currentFieldName + "]");
|
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) {
|
if (clauses.size() == 1) {
|
||||||
BooleanClause clause = clauses.get(0);
|
BooleanClause clause = clauses.get(0);
|
||||||
if (clause.getOccur() == BooleanClause.Occur.MUST) {
|
if (clause.getOccur() == BooleanClause.Occur.MUST) {
|
||||||
|
|
|
@ -47,7 +47,9 @@ public class BoostingQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query positiveQuery = null;
|
Query positiveQuery = null;
|
||||||
|
boolean positiveQueryFound = false;
|
||||||
Query negativeQuery = null;
|
Query negativeQuery = null;
|
||||||
|
boolean negativeQueryFound = false;
|
||||||
float boost = -1;
|
float boost = -1;
|
||||||
float negativeBoost = -1;
|
float negativeBoost = -1;
|
||||||
|
|
||||||
|
@ -59,8 +61,10 @@ public class BoostingQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("positive".equals(currentFieldName)) {
|
if ("positive".equals(currentFieldName)) {
|
||||||
positiveQuery = parseContext.parseInnerQuery();
|
positiveQuery = parseContext.parseInnerQuery();
|
||||||
|
positiveQueryFound = true;
|
||||||
} else if ("negative".equals(currentFieldName)) {
|
} else if ("negative".equals(currentFieldName)) {
|
||||||
negativeQuery = parseContext.parseInnerQuery();
|
negativeQuery = parseContext.parseInnerQuery();
|
||||||
|
negativeQueryFound = true;
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[boosting] query does not support [" + currentFieldName + "]");
|
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'");
|
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'");
|
throw new QueryParsingException(parseContext.index(), "[boosting] query requires 'negative' query to be set'");
|
||||||
}
|
}
|
||||||
if (negativeBoost == -1) {
|
if (negativeBoost == -1) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[boosting] query requires 'negative_boost' to be set'");
|
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);
|
BoostingQuery boostingQuery = new BoostingQuery(positiveQuery, negativeQuery, negativeBoost);
|
||||||
if (boost != -1) {
|
if (boost != -1) {
|
||||||
boostingQuery.setBoost(boost);
|
boostingQuery.setBoost(boost);
|
||||||
|
|
|
@ -51,7 +51,9 @@ public class ConstantScoreQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
@ -64,8 +66,10 @@ public class ConstantScoreQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("filter".equals(currentFieldName)) {
|
if ("filter".equals(currentFieldName)) {
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
|
filterFound = true;
|
||||||
} else if ("query".equals(currentFieldName)) {
|
} else if ("query".equals(currentFieldName)) {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[constant_score] query does not support [" + currentFieldName + "]");
|
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");
|
throw new QueryParsingException(parseContext.index(), "[constant_score] requires either 'filter' or 'query' element");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query == null && filter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
// cache the filter if possible needed
|
// cache the filter if possible needed
|
||||||
if (cache) {
|
if (cache) {
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class CustomBoostFactorQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
float boostFactor = 1.0f;
|
float boostFactor = 1.0f;
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ public class CustomBoostFactorQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[custom_boost_factor] query does not support [" + currentFieldName + "]");
|
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");
|
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 functionScoreQuery = new FunctionScoreQuery(query, new BoostScoreFunction(boostFactor));
|
||||||
functionScoreQuery.setBoost(boost);
|
functionScoreQuery.setBoost(boost);
|
||||||
return functionScoreQuery;
|
return functionScoreQuery;
|
||||||
|
|
|
@ -55,12 +55,14 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String scriptLang = null;
|
String scriptLang = null;
|
||||||
Map<String, Object> vars = null;
|
Map<String, Object> vars = null;
|
||||||
|
|
||||||
FiltersFunctionScoreQuery.ScoreMode scoreMode = FiltersFunctionScoreQuery.ScoreMode.First;
|
FiltersFunctionScoreQuery.ScoreMode scoreMode = FiltersFunctionScoreQuery.ScoreMode.First;
|
||||||
ArrayList<Filter> filters = new ArrayList<Filter>();
|
ArrayList<Filter> filters = new ArrayList<Filter>();
|
||||||
|
boolean filtersFound = false;
|
||||||
ArrayList<String> scripts = new ArrayList<String>();
|
ArrayList<String> scripts = new ArrayList<String>();
|
||||||
TFloatArrayList boosts = new TFloatArrayList();
|
TFloatArrayList boosts = new TFloatArrayList();
|
||||||
|
|
||||||
|
@ -72,6 +74,7 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} else if ("params".equals(currentFieldName)) {
|
} else if ("params".equals(currentFieldName)) {
|
||||||
vars = parser.map();
|
vars = parser.map();
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,9 +82,11 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("filters".equals(currentFieldName)) {
|
if ("filters".equals(currentFieldName)) {
|
||||||
|
filtersFound = true;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
String script = null;
|
String script = null;
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
float fboost = Float.NaN;
|
float fboost = Float.NaN;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
@ -89,6 +94,7 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("filter".equals(currentFieldName)) {
|
if ("filter".equals(currentFieldName)) {
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
|
filterFound = true;
|
||||||
}
|
}
|
||||||
} else if (token.isValue()) {
|
} else if (token.isValue()) {
|
||||||
if ("script".equals(currentFieldName)) {
|
if ("script".equals(currentFieldName)) {
|
||||||
|
@ -101,13 +107,15 @@ public class CustomFiltersScoreQueryParser implements QueryParser {
|
||||||
if (script == null && fboost == -1) {
|
if (script == null && fboost == -1) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] missing 'script' or 'boost' in filters array element");
|
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");
|
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] missing 'filter' in filters array element");
|
||||||
}
|
}
|
||||||
|
if (filter != null) {
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
scripts.add(script);
|
scripts.add(script);
|
||||||
boosts.add(fboost);
|
boosts.add(fboost);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[custom_filters_score] query does not support [" + currentFieldName + "]");
|
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");
|
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");
|
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()];
|
FiltersFunctionScoreQuery.FilterFunction[] filterFunctions = new FiltersFunctionScoreQuery.FilterFunction[filters.size()];
|
||||||
for (int i = 0; i < filterFunctions.length; i++) {
|
for (int i = 0; i < filterFunctions.length; i++) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class CustomScoreQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String script = null;
|
String script = null;
|
||||||
String scriptLang = null;
|
String scriptLang = null;
|
||||||
|
@ -66,6 +67,7 @@ public class CustomScoreQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} else if ("params".equals(currentFieldName)) {
|
} else if ("params".equals(currentFieldName)) {
|
||||||
vars = parser.map();
|
vars = parser.map();
|
||||||
} else {
|
} 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");
|
throw new QueryParsingException(parseContext.index(), "[custom_score] requires 'query' field");
|
||||||
}
|
}
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[custom_score] requires 'script' field");
|
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);
|
SearchScript searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptLang, script, vars);
|
||||||
FunctionScoreQuery functionScoreQuery = new FunctionScoreQuery(query, new ScriptScoreFunction(script, vars, searchScript));
|
FunctionScoreQuery functionScoreQuery = new FunctionScoreQuery(query, new ScriptScoreFunction(script, vars, searchScript));
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class DisMaxQueryParser implements QueryParser {
|
||||||
float tieBreaker = 0.0f;
|
float tieBreaker = 0.0f;
|
||||||
|
|
||||||
List<Query> queries = newArrayList();
|
List<Query> queries = newArrayList();
|
||||||
|
boolean queriesFound = false;
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -62,14 +63,22 @@ public class DisMaxQueryParser implements QueryParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("queries".equals(currentFieldName)) {
|
if ("queries".equals(currentFieldName)) {
|
||||||
queries.add(parseContext.parseInnerQuery());
|
queriesFound = true;
|
||||||
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query != null) {
|
||||||
|
queries.add(query);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]");
|
throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("queries".equals(currentFieldName)) {
|
if ("queries".equals(currentFieldName)) {
|
||||||
|
queriesFound = true;
|
||||||
while (token != XContentParser.Token.END_ARRAY) {
|
while (token != XContentParser.Token.END_ARRAY) {
|
||||||
queries.add(parseContext.parseInnerQuery());
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query != null) {
|
||||||
|
queries.add(query);
|
||||||
|
}
|
||||||
token = parser.nextToken();
|
token = parser.nextToken();
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker);
|
||||||
query.setBoost(boost);
|
query.setBoost(boost);
|
||||||
return query;
|
return query;
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class FQueryFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ public class FQueryFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
|
queryFound = true;
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[fquery] filter does not support [" + currentFieldName + "]");
|
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);
|
Filter filter = new QueryWrapperFilter(query);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
filter = parseContext.cacheFilter(filter, cacheKey);
|
filter = parseContext.cacheFilter(filter, cacheKey);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
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,
|
* 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".
|
* and should end when the token is at the matching "END_OBJECT".
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException;
|
Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException;
|
||||||
}
|
}
|
|
@ -51,7 +51,9 @@ public class FilteredQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
@ -63,8 +65,10 @@ public class FilteredQueryParser implements QueryParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
|
queryFound = true;
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
} else if ("filter".equals(currentFieldName)) {
|
} else if ("filter".equals(currentFieldName)) {
|
||||||
|
filterFound = true;
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[filtered] query does not support [" + currentFieldName + "]");
|
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");
|
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 (filter == null) {
|
||||||
|
if (!filterFound) {
|
||||||
|
// we allow for null filter, so it makes compositions on the client side to be simpler
|
||||||
return query;
|
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
|
// cache if required
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class HasChildFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
String childType = null;
|
String childType = null;
|
||||||
String scope = null;
|
String scope = null;
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ public class HasChildFilterParser implements FilterParser {
|
||||||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||||
try {
|
try {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} finally {
|
} finally {
|
||||||
QueryParseContext.setTypes(origTypes);
|
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");
|
throw new QueryParsingException(parseContext.index(), "[child] filter requires 'query' field");
|
||||||
}
|
}
|
||||||
|
if (query == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (childType == null) {
|
if (childType == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[child] filter requires 'type' field");
|
throw new QueryParsingException(parseContext.index(), "[child] filter requires 'type' field");
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class HasChildQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String childType = null;
|
String childType = null;
|
||||||
String scope = null;
|
String scope = null;
|
||||||
|
@ -68,6 +69,7 @@ public class HasChildQueryParser implements QueryParser {
|
||||||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
||||||
try {
|
try {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} finally {
|
} finally {
|
||||||
QueryParseContext.setTypes(origTypes);
|
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");
|
throw new QueryParsingException(parseContext.index(), "[has_child] requires 'query' field");
|
||||||
}
|
}
|
||||||
|
if (query == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (childType == null) {
|
if (childType == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[has_child] requires 'type' field");
|
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.Nullable;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.io.BytesStream;
|
import org.elasticsearch.common.io.BytesStream;
|
||||||
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
@ -232,12 +233,14 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Filter parseInnerFilter(XContentParser parser) throws IOException {
|
public Filter parseInnerFilter(XContentParser parser) throws IOException {
|
||||||
QueryParseContext context = cache.get();
|
QueryParseContext context = cache.get();
|
||||||
context.reset(parser);
|
context.reset(parser);
|
||||||
return context.parseInnerFilter();
|
return context.parseInnerFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Query parseInnerQuery(XContentParser parser) throws IOException {
|
public Query parseInnerQuery(XContentParser parser) throws IOException {
|
||||||
QueryParseContext context = cache.get();
|
QueryParseContext context = cache.get();
|
||||||
context.reset(parser);
|
context.reset(parser);
|
||||||
|
@ -247,6 +250,9 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
||||||
private ParsedQuery parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
|
private ParsedQuery parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
|
||||||
parseContext.reset(parser);
|
parseContext.reset(parser);
|
||||||
Query query = parseContext.parseInnerQuery();
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query == null) {
|
||||||
|
query = Queries.NO_MATCH_QUERY;
|
||||||
|
}
|
||||||
return new ParsedQuery(query, parseContext.copyNamedFilters());
|
return new ParsedQuery(query, parseContext.copyNamedFilters());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class IndicesFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
Set<String> indices = Sets.newHashSet();
|
Set<String> indices = Sets.newHashSet();
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
|
@ -66,6 +67,7 @@ public class IndicesFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("filter".equals(currentFieldName)) {
|
if ("filter".equals(currentFieldName)) {
|
||||||
|
filterFound = true;
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
} else if ("no_match_filter".equals(currentFieldName)) {
|
} else if ("no_match_filter".equals(currentFieldName)) {
|
||||||
noMatchFilter = parseContext.parseInnerFilter();
|
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");
|
throw new QueryParsingException(parseContext.index(), "[indices] requires 'filter' element");
|
||||||
}
|
}
|
||||||
if (indices.isEmpty()) {
|
if (indices.isEmpty()) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String[] concreteIndices = indices.toArray(new String[indices.size()]);
|
String[] concreteIndices = indices.toArray(new String[indices.size()]);
|
||||||
if (clusterService != null) {
|
if (clusterService != null) {
|
||||||
MetaData metaData = clusterService.state().metaData();
|
MetaData metaData = clusterService.state().metaData();
|
||||||
|
|
|
@ -57,6 +57,7 @@ public class IndicesQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
Set<String> indices = Sets.newHashSet();
|
Set<String> indices = Sets.newHashSet();
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
|
@ -68,6 +69,7 @@ public class IndicesQueryParser implements QueryParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
|
queryFound = true;
|
||||||
} else if ("no_match_query".equals(currentFieldName)) {
|
} else if ("no_match_query".equals(currentFieldName)) {
|
||||||
noMatchQuery = parseContext.parseInnerQuery();
|
noMatchQuery = parseContext.parseInnerQuery();
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,9 +102,12 @@ public class IndicesQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (query == null) {
|
if (!queryFound) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'query' element");
|
throw new QueryParsingException(parseContext.index(), "[indices] requires 'query' element");
|
||||||
}
|
}
|
||||||
|
if (query == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (indices.isEmpty()) {
|
if (indices.isEmpty()) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
throw new QueryParsingException(parseContext.index(), "[indices] requires 'indices' element");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,9 @@ public class NestedFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String scope = null;
|
String scope = null;
|
||||||
String path = null;
|
String path = null;
|
||||||
|
@ -72,8 +74,10 @@ public class NestedFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
|
queryFound = true;
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
} else if ("filter".equals(currentFieldName)) {
|
} else if ("filter".equals(currentFieldName)) {
|
||||||
|
filterFound = true;
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[nested] filter does not support [" + currentFieldName + "]");
|
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");
|
throw new QueryParsingException(parseContext.index(), "[nested] requires either 'query' or 'filter' field");
|
||||||
}
|
}
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query == null && filter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
query = new DeletionAwareConstantScoreQuery(filter);
|
query = new DeletionAwareConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,9 @@ public class NestedQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String scope = null;
|
String scope = null;
|
||||||
String path = null;
|
String path = null;
|
||||||
|
@ -70,8 +72,10 @@ public class NestedQueryParser implements QueryParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
|
queryFound = true;
|
||||||
query = parseContext.parseInnerQuery();
|
query = parseContext.parseInnerQuery();
|
||||||
} else if ("filter".equals(currentFieldName)) {
|
} else if ("filter".equals(currentFieldName)) {
|
||||||
|
filterFound = true;
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[nested] query does not support [" + currentFieldName + "]");
|
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");
|
throw new QueryParsingException(parseContext.index(), "[nested] requires either 'query' or 'filter' field");
|
||||||
}
|
}
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
throw new QueryParsingException(parseContext.index(), "[nested] requires 'path' field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query == null && filter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
query = new DeletionAwareConstantScoreQuery(filter);
|
query = new DeletionAwareConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class NotFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
|
boolean filterFound = false;
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
|
||||||
|
@ -60,7 +61,9 @@ public class NotFilterParser implements FilterParser {
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("filter".equals(currentFieldName)) {
|
if ("filter".equals(currentFieldName)) {
|
||||||
filter = parseContext.parseInnerFilter();
|
filter = parseContext.parseInnerFilter();
|
||||||
|
filterFound = true;
|
||||||
} else {
|
} else {
|
||||||
|
filterFound = true;
|
||||||
// its the filter, and the name is the field
|
// its the filter, and the name is the field
|
||||||
filter = parseContext.parseInnerFilter(currentFieldName);
|
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");
|
throw new QueryParsingException(parseContext.index(), "filter is required when using `not` filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Filter notFilter = new NotFilter(filter);
|
Filter notFilter = new NotFilter(filter);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
notFilter = parseContext.cacheFilter(notFilter, cacheKey);
|
notFilter = parseContext.cacheFilter(notFilter, cacheKey);
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class OrFilterParser implements FilterParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
ArrayList<Filter> filters = newArrayList();
|
ArrayList<Filter> filters = newArrayList();
|
||||||
|
boolean filtersFound = false;
|
||||||
|
|
||||||
boolean cache = false;
|
boolean cache = false;
|
||||||
CacheKeyFilter.Key cacheKey = null;
|
CacheKeyFilter.Key cacheKey = null;
|
||||||
|
@ -60,7 +61,11 @@ public class OrFilterParser implements FilterParser {
|
||||||
XContentParser.Token token = parser.currentToken();
|
XContentParser.Token token = parser.currentToken();
|
||||||
if (token == XContentParser.Token.START_ARRAY) {
|
if (token == XContentParser.Token.START_ARRAY) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_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 {
|
} else {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
@ -68,12 +73,20 @@ public class OrFilterParser implements FilterParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("filters".equals(currentFieldName)) {
|
if ("filters".equals(currentFieldName)) {
|
||||||
|
filtersFound = true;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
filters.add(parseContext.parseInnerFilter());
|
Filter filter = parseContext.parseInnerFilter();
|
||||||
|
if (filter != null) {
|
||||||
|
filters.add(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_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 if (token.isValue()) {
|
} 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'");
|
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
|
// no need to cache this one
|
||||||
Filter filter = new OrFilter(filters);
|
Filter filter = new OrFilter(filters);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
|
|
|
@ -45,6 +45,9 @@ public class QueryFilterParser implements FilterParser {
|
||||||
@Override
|
@Override
|
||||||
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||||
Query query = parseContext.parseInnerQuery();
|
Query query = parseContext.parseInnerQuery();
|
||||||
|
if (query == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return new QueryWrapperFilter(query);
|
return new QueryWrapperFilter(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -160,6 +160,7 @@ public class QueryParseContext {
|
||||||
return ImmutableMap.copyOf(namedFilters);
|
return ImmutableMap.copyOf(namedFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Query parseInnerQuery() throws IOException, QueryParsingException {
|
public Query parseInnerQuery() throws IOException, QueryParsingException {
|
||||||
// move to START object
|
// move to START object
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -192,6 +193,7 @@ public class QueryParseContext {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Filter parseInnerFilter() throws IOException, QueryParsingException {
|
public Filter parseInnerFilter() throws IOException, QueryParsingException {
|
||||||
// move to START object
|
// move to START object
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
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,
|
* 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".
|
* 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;
|
Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
|
|
||||||
Query query = null;
|
Query query = null;
|
||||||
|
boolean queryFound = false;
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
String childType = null;
|
String childType = null;
|
||||||
String scope = null;
|
String scope = null;
|
||||||
|
@ -65,6 +66,7 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
|
queryFound = true;
|
||||||
// TODO we need to set the type, but, `query` can come before `type`... (see HasChildFilterParser)
|
// 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
|
// since we switch types, make sure we change the context
|
||||||
String[] origTypes = QueryParseContext.setTypesWithPrevious(childType == null ? null : new String[]{childType});
|
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");
|
throw new QueryParsingException(parseContext.index(), "[child] requires 'query' field");
|
||||||
}
|
}
|
||||||
if (childType == null) {
|
if (childType == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "[child] requires 'type' field");
|
throw new QueryParsingException(parseContext.index(), "[child] requires 'type' field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
DocumentMapper childDocMapper = parseContext.mapperService().documentMapper(childType);
|
DocumentMapper childDocMapper = parseContext.mapperService().documentMapper(childType);
|
||||||
if (childDocMapper == null) {
|
if (childDocMapper == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), "No mapping for for type [" + childType + "]");
|
throw new QueryParsingException(parseContext.index(), "No mapping for for type [" + childType + "]");
|
||||||
|
|
Loading…
Reference in New Issue