From 60ac34ff3a191d83132c2727a7b0f8862a26d362 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 28 Aug 2013 10:42:33 +0200 Subject: [PATCH] Added `_name` support to queries. This extends the named filter support from only filters to also queries. Closes #3581 --- .../index/query/BoolQueryBuilder.java | 13 ++++ .../index/query/BoolQueryParser.java | 18 +++-- .../index/query/CommonTermsQueryBuilder.java | 17 ++++- .../index/query/CommonTermsQueryParser.java | 13 +++- .../index/query/DisMaxQueryBuilder.java | 13 ++++ .../index/query/DisMaxQueryParser.java | 6 ++ .../query/FieldMaskingSpanQueryBuilder.java | 14 ++++ .../query/FieldMaskingSpanQueryParser.java | 6 ++ .../index/query/FieldQueryBuilder.java | 14 ++++ .../index/query/FieldQueryParser.java | 6 ++ .../index/query/FilteredQueryBuilder.java | 13 ++++ .../index/query/FilteredQueryParser.java | 6 ++ .../query/FuzzyLikeThisFieldQueryBuilder.java | 12 ++++ .../query/FuzzyLikeThisFieldQueryParser.java | 17 +++-- .../query/FuzzyLikeThisQueryBuilder.java | 12 ++++ .../index/query/FuzzyLikeThisQueryParser.java | 7 +- .../index/query/FuzzyQueryBuilder.java | 15 ++++- .../index/query/FuzzyQueryParser.java | 9 ++- .../index/query/GeoShapeQueryBuilder.java | 17 ++++- .../index/query/GeoShapeQueryParser.java | 6 ++ .../index/query/HasChildQueryBuilder.java | 13 ++++ .../index/query/HasChildQueryParser.java | 6 ++ .../index/query/HasParentQueryBuilder.java | 13 ++++ .../index/query/HasParentQueryParser.java | 6 ++ .../index/query/IdsQueryBuilder.java | 13 ++++ .../index/query/IdsQueryParser.java | 6 ++ .../index/query/IndicesQueryBuilder.java | 13 ++++ .../index/query/IndicesQueryParser.java | 9 +++ .../index/query/MatchQueryBuilder.java | 13 ++++ .../index/query/MatchQueryParser.java | 7 +- .../query/MoreLikeThisFieldQueryBuilder.java | 12 ++++ .../query/MoreLikeThisFieldQueryParser.java | 9 ++- .../index/query/MoreLikeThisQueryBuilder.java | 12 ++++ .../index/query/MoreLikeThisQueryParser.java | 7 +- .../index/query/MultiMatchQueryBuilder.java | 14 ++++ .../index/query/MultiMatchQueryParser.java | 6 ++ .../index/query/NestedQueryBuilder.java | 13 ++++ .../index/query/NestedQueryParser.java | 6 ++ .../index/query/PrefixQueryBuilder.java | 15 ++++- .../index/query/PrefixQueryParser.java | 9 ++- .../index/query/QueryParseContext.java | 5 ++ .../index/query/QueryStringQueryBuilder.java | 13 ++++ .../index/query/QueryStringQueryParser.java | 8 ++- .../index/query/RangeQueryBuilder.java | 13 ++++ .../index/query/RangeQueryParser.java | 9 ++- .../index/query/RegexpQueryBuilder.java | 14 +++- .../index/query/RegexpQueryParser.java | 9 ++- .../index/query/SpanFirstQueryBuilder.java | 13 ++++ .../index/query/SpanFirstQueryParser.java | 6 ++ .../index/query/SpanNearQueryBuilder.java | 13 ++++ .../index/query/SpanNearQueryParser.java | 6 ++ .../index/query/SpanNotQueryBuilder.java | 13 ++++ .../index/query/SpanNotQueryParser.java | 6 ++ .../index/query/SpanOrQueryBuilder.java | 13 ++++ .../index/query/SpanOrQueryParser.java | 6 ++ .../index/query/SpanTermQueryBuilder.java | 19 +++++- .../index/query/SpanTermQueryParser.java | 8 ++- .../index/query/TermQueryBuilder.java | 19 +++++- .../index/query/TermQueryParser.java | 9 ++- .../index/query/TermsQueryBuilder.java | 13 ++++ .../index/query/TermsQueryParser.java | 19 ++++-- .../index/query/TopChildrenQueryBuilder.java | 13 ++++ .../index/query/TopChildrenQueryParser.java | 6 ++ .../index/query/WildcardQueryBuilder.java | 15 ++++- .../index/query/WildcardQueryParser.java | 17 +++-- .../MatchedFiltersFetchSubPhase.java | 18 +++-- .../matchedfilters/MatchedFiltersTests.java | 67 +++++++++++++++++-- 67 files changed, 749 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index 3d4bbcae2ea..e28dda8e953 100644 --- a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -45,6 +45,8 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery private Boolean adjustPureNegative; + private String queryName; + /** * Adds a query that must appear in the matching documents. */ @@ -133,6 +135,14 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public BoolQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject("bool"); @@ -151,6 +161,9 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery if (adjustPureNegative != null) { builder.field("adjust_pure_negative", adjustPureNegative); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java b/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java index 49cb1300d7a..4333a062c68 100644 --- a/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java @@ -61,6 +61,8 @@ public class BoolQueryParser implements QueryParser { List clauses = newArrayList(); boolean adjustPureNegative = true; + String queryName = null; + String currentFieldName = null; XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -121,6 +123,8 @@ public class BoolQueryParser implements QueryParser { minimumShouldMatch = parser.textOrNull(); } else if ("adjust_pure_negative".equals(currentFieldName) || "adjustPureNegative".equals(currentFieldName)) { adjustPureNegative = parser.booleanValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]"); } @@ -131,12 +135,16 @@ public class BoolQueryParser implements QueryParser { return null; } - BooleanQuery query = new BooleanQuery(disableCoord); + BooleanQuery booleanQuery = new BooleanQuery(disableCoord); for (BooleanClause clause : clauses) { - query.add(clause); + booleanQuery.add(clause); } - query.setBoost(boost); - Queries.applyMinimumShouldMatch(query, minimumShouldMatch); - return optimizeQuery(adjustPureNegative ? fixNegativeQueryIfNeeded(query) : query); + booleanQuery.setBoost(boost); + Queries.applyMinimumShouldMatch(booleanQuery, minimumShouldMatch); + Query query = optimizeQuery(adjustPureNegative ? fixNegativeQueryIfNeeded(booleanQuery) : booleanQuery); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java index ff09e9adc97..f5aec5770ef 100644 --- a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java @@ -19,11 +19,11 @@ package org.elasticsearch.index.query; -import java.io.IOException; - import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.common.xcontent.XContentBuilder; +import java.io.IOException; + /** * CommonTermsQuery query is a query that executes high-frequency terms in a * optional sub-query to prevent slow queries due to "common" terms like @@ -66,6 +66,8 @@ public class CommonTermsQueryBuilder extends BaseQueryBuilder implements Boostab private Float cutoffFrequency = null; + private String queryName; + /** * Constructs a new common terms query. */ @@ -146,6 +148,14 @@ public class CommonTermsQueryBuilder extends BaseQueryBuilder implements Boostab return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public CommonTermsQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(CommonTermsQueryParser.NAME); @@ -180,6 +190,9 @@ public class CommonTermsQueryBuilder extends BaseQueryBuilder implements Boostab } builder.endObject(); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryParser.java b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryParser.java index ef855858c66..5ad03f466df 100644 --- a/src/main/java/org/elasticsearch/index/query/CommonTermsQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/CommonTermsQueryParser.java @@ -81,6 +81,7 @@ public class CommonTermsQueryParser implements QueryParser { Occur highFreqOccur = DEFAULT_HIGH_FREQ_OCCUR; Occur lowFreqOccur = DEFAULT_LOW_FREQ_OCCUR; float maxTermFrequency = DEFAULT_MAX_TERM_DOC_FREQ; + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { String currentFieldName = null; @@ -141,6 +142,8 @@ public class CommonTermsQueryParser implements QueryParser { lowFreqMinimumShouldMatch = parser.text(); } else if ("cutoff_frequency".equals(currentFieldName)) { maxTermFrequency = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[common] query does not support [" + currentFieldName + "]"); } @@ -161,9 +164,13 @@ public class CommonTermsQueryParser implements QueryParser { if (value == null) { throw new QueryParsingException(parseContext.index(), "No text specified for text query"); } - ExtendedCommonTermsQuery query = new ExtendedCommonTermsQuery(highFreqOccur, lowFreqOccur, maxTermFrequency, disableCoords); - query.setBoost(boost); - return parseQueryString(query, value.toString(), fieldName, parseContext, queryAnalyzer, lowFreqMinimumShouldMatch, highFreqMinimumShouldMatch); + ExtendedCommonTermsQuery commonsQuery = new ExtendedCommonTermsQuery(highFreqOccur, lowFreqOccur, maxTermFrequency, disableCoords); + commonsQuery.setBoost(boost); + Query query = parseQueryString(commonsQuery, value.toString(), fieldName, parseContext, queryAnalyzer, lowFreqMinimumShouldMatch, highFreqMinimumShouldMatch); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } diff --git a/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java index 415c765e102..d58926cd0f2 100644 --- a/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java @@ -41,6 +41,8 @@ public class DisMaxQueryBuilder extends BaseQueryBuilder implements BoostableQue private float tieBreaker = -1; + private String queryName; + /** * Add a sub-query to this disjunction. */ @@ -69,6 +71,14 @@ public class DisMaxQueryBuilder extends BaseQueryBuilder implements BoostableQue return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public DisMaxQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(DisMaxQueryParser.NAME); @@ -78,6 +88,9 @@ public class DisMaxQueryBuilder extends BaseQueryBuilder implements BoostableQue if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.startArray("queries"); for (QueryBuilder queryBuilder : queries) { queryBuilder.toXContent(builder, params); diff --git a/src/main/java/org/elasticsearch/index/query/DisMaxQueryParser.java b/src/main/java/org/elasticsearch/index/query/DisMaxQueryParser.java index 9252d3a11e1..7427e1ef1b4 100644 --- a/src/main/java/org/elasticsearch/index/query/DisMaxQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/DisMaxQueryParser.java @@ -55,6 +55,7 @@ public class DisMaxQueryParser implements QueryParser { List queries = newArrayList(); boolean queriesFound = false; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -89,6 +90,8 @@ public class DisMaxQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("tie_breaker".equals(currentFieldName) || "tieBreaker".equals(currentFieldName)) { tieBreaker = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]"); } @@ -105,6 +108,9 @@ public class DisMaxQueryParser implements QueryParser { DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java index a7922b01b73..c2d441d0fae 100644 --- a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java @@ -34,6 +34,9 @@ public class FieldMaskingSpanQueryBuilder extends BaseQueryBuilder implements Sp private float boost = -1; + private String queryName; + + public FieldMaskingSpanQueryBuilder(SpanQueryBuilder queryBuilder, String field) { this.queryBuilder = queryBuilder; this.field = field; @@ -44,6 +47,14 @@ public class FieldMaskingSpanQueryBuilder extends BaseQueryBuilder implements Sp return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FieldMaskingSpanQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FieldMaskingSpanQueryParser.NAME); @@ -53,6 +64,9 @@ public class FieldMaskingSpanQueryBuilder extends BaseQueryBuilder implements Sp if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryParser.java b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryParser.java index ff7e36779d6..7bef406b24b 100644 --- a/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryParser.java @@ -53,6 +53,7 @@ public class FieldMaskingSpanQueryParser implements QueryParser { SpanQuery inner = null; String field = null; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -74,6 +75,8 @@ public class FieldMaskingSpanQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("field".equals(currentFieldName)) { field = parser.text(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[field_masking_span] query does not support [" + currentFieldName + "]"); } @@ -93,6 +96,9 @@ public class FieldMaskingSpanQueryParser implements QueryParser { FieldMaskingSpanQuery query = new FieldMaskingSpanQuery(inner, field); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/FieldQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FieldQueryBuilder.java index cceb79f3d1e..5c805514ce7 100644 --- a/src/main/java/org/elasticsearch/index/query/FieldQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FieldQueryBuilder.java @@ -69,6 +69,8 @@ public class FieldQueryBuilder extends BaseQueryBuilder implements BoostableQuer private String minimumShouldMatch; + private String queryName; + /** * A query that executes the query string against a field. It is a simplified * version of {@link QueryStringQueryBuilder} that simply runs against @@ -294,6 +296,15 @@ public class FieldQueryBuilder extends BaseQueryBuilder implements BoostableQuer return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FieldQueryBuilder queryName(String queryName) { + this.queryName = queryName; + this.extraSet = true; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FieldQueryParser.NAME); @@ -347,6 +358,9 @@ public class FieldQueryBuilder extends BaseQueryBuilder implements BoostableQuer if (minimumShouldMatch != null) { builder.field("minimum_should_match", minimumShouldMatch); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/FieldQueryParser.java b/src/main/java/org/elasticsearch/index/query/FieldQueryParser.java index 1dd847e5879..2404119997f 100644 --- a/src/main/java/org/elasticsearch/index/query/FieldQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FieldQueryParser.java @@ -71,6 +71,7 @@ public class FieldQueryParser implements QueryParser { qpSettings.defaultField(fieldName); qpSettings.analyzeWildcard(defaultAnalyzeWildcard); qpSettings.allowLeadingWildcard(defaultAllowLeadingWildcard); + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { @@ -132,6 +133,8 @@ public class FieldQueryParser implements QueryParser { qpSettings.minimumShouldMatch(parser.textOrNull()); } else if ("quote_field_suffix".equals(currentFieldName) || "quoteFieldSuffix".equals(currentFieldName)) { qpSettings.quoteFieldSuffix(parser.textOrNull()); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[field] query does not support [" + currentFieldName + "]"); } @@ -175,6 +178,9 @@ public class FieldQueryParser implements QueryParser { Queries.applyMinimumShouldMatch((BooleanQuery) query, qpSettings.minimumShouldMatch()); } parseContext.indexCache().queryParserCache().put(qpSettings, query); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } catch (ParseException e) { throw new QueryParsingException(parseContext.index(), "Failed to parse query [" + qpSettings.queryString() + "]", e); diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java index 8219f136c6a..cf7dc260659 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java @@ -35,6 +35,8 @@ public class FilteredQueryBuilder extends BaseQueryBuilder implements BoostableQ private float boost = -1; + private String queryName; + /** * A query that applies a filter to the results of another query. * @@ -55,6 +57,14 @@ public class FilteredQueryBuilder extends BaseQueryBuilder implements BoostableQ return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FilteredQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FilteredQueryParser.NAME); @@ -67,6 +77,9 @@ public class FilteredQueryBuilder extends BaseQueryBuilder implements BoostableQ if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java index ae1f0c666ba..fc3ff716a02 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java @@ -57,6 +57,7 @@ public class FilteredQueryParser implements QueryParser { float boost = 1.0f; boolean cache = false; CacheKeyFilter.Key cacheKey = null; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -93,6 +94,8 @@ public class FilteredQueryParser implements QueryParser { filterStrategy = FilteredQuery.LEAP_FROG_QUERY_FIRST_STRATEGY; } else if ("leap_frog_filter_first".equals(value) || "leapFrogFilterFirst".equals(value)) { filterStrategy = FilteredQuery.LEAP_FROG_FILTER_FIRST_STRATEGY; + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[filtered] strategy value not supported [" + value + "]"); } @@ -142,6 +145,9 @@ public class FilteredQueryParser implements QueryParser { XFilteredQuery filteredQuery = new XFilteredQuery(query, filter, filterStrategy); filteredQuery.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, filteredQuery); + } return filteredQuery; } } diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryBuilder.java index cb6c8d3743f..3e95f1aaf40 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryBuilder.java @@ -39,6 +39,7 @@ public class FuzzyLikeThisFieldQueryBuilder extends BaseQueryBuilder implements private Boolean ignoreTF; private String analyzer; private Boolean failOnUnsupportedField; + private String queryName; /** * A fuzzy more like this query on the provided field. @@ -98,6 +99,14 @@ public class FuzzyLikeThisFieldQueryBuilder extends BaseQueryBuilder implements return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FuzzyLikeThisFieldQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FuzzyLikeThisFieldQueryParser.NAME); @@ -127,6 +136,9 @@ public class FuzzyLikeThisFieldQueryBuilder extends BaseQueryBuilder implements if (failOnUnsupportedField != null) { builder.field("fail_on_unsupported_field", failOnUnsupportedField); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryParser.java b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryParser.java index 77ce20de294..c5b2e7dfefb 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisFieldQueryParser.java @@ -70,6 +70,7 @@ public class FuzzyLikeThisFieldQueryParser implements QueryParser { boolean ignoreTF = false; Analyzer analyzer = null; boolean failOnUnsupportedField = true; + String queryName = null; XContentParser.Token token = parser.nextToken(); if (token != XContentParser.Token.FIELD_NAME) { @@ -105,6 +106,8 @@ public class FuzzyLikeThisFieldQueryParser implements QueryParser { analyzer = parseContext.analysisService().analyzer(parser.text()); } else if ("fail_on_unsupported_field".equals(currentFieldName) || "failOnUnsupportedField".equals(currentFieldName)) { failOnUnsupportedField = parser.booleanValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[flt_field] query does not support [" + currentFieldName + "]"); } @@ -135,10 +138,10 @@ public class FuzzyLikeThisFieldQueryParser implements QueryParser { } } - FuzzyLikeThisQuery query = new FuzzyLikeThisQuery(maxNumTerms, analyzer); - query.addTerms(likeText, fieldName, minSimilarity, prefixLength); - query.setBoost(boost); - query.setIgnoreTF(ignoreTF); + FuzzyLikeThisQuery fuzzyLikeThisQuery = new FuzzyLikeThisQuery(maxNumTerms, analyzer); + fuzzyLikeThisQuery.addTerms(likeText, fieldName, minSimilarity, prefixLength); + fuzzyLikeThisQuery.setBoost(boost); + fuzzyLikeThisQuery.setIgnoreTF(ignoreTF); // move to the next end object, to close the field name token = parser.nextToken(); @@ -147,6 +150,10 @@ public class FuzzyLikeThisFieldQueryParser implements QueryParser { } assert token == XContentParser.Token.END_OBJECT; - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + Query query = wrapSmartNameQuery(fuzzyLikeThisQuery, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryBuilder.java index fb66c820d61..b9d39f3589f 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryBuilder.java @@ -39,6 +39,7 @@ public class FuzzyLikeThisQueryBuilder extends BaseQueryBuilder implements Boost private Boolean ignoreTF; private String analyzer; private Boolean failOnUnsupportedField; + private String queryName; /** * Constructs a new fuzzy like this query which uses the "_all" field. @@ -105,6 +106,14 @@ public class FuzzyLikeThisQueryBuilder extends BaseQueryBuilder implements Boost return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FuzzyLikeThisQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FuzzyLikeThisQueryParser.NAME); @@ -140,6 +149,9 @@ public class FuzzyLikeThisQueryBuilder extends BaseQueryBuilder implements Boost if (failOnUnsupportedField != null) { builder.field("fail_on_unsupported_field", failOnUnsupportedField); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryParser.java b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryParser.java index 79f15bafdf8..bed7b066353 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyLikeThisQueryParser.java @@ -19,7 +19,6 @@ package org.elasticsearch.index.query; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.sandbox.queries.FuzzyLikeThisQuery; @@ -71,6 +70,7 @@ public class FuzzyLikeThisQueryParser implements QueryParser { boolean ignoreTF = false; Analyzer analyzer = null; boolean failOnUnsupportedField = true; + String queryName = null; XContentParser.Token token; String currentFieldName = null; @@ -94,6 +94,8 @@ public class FuzzyLikeThisQueryParser implements QueryParser { analyzer = parseContext.analysisService().analyzer(parser.text()); } else if ("fail_on_unsupported_field".equals(currentFieldName) || "failOnUnsupportedField".equals(currentFieldName)) { failOnUnsupportedField = parser.booleanValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[flt] query does not support [" + currentFieldName + "]"); } @@ -142,6 +144,9 @@ public class FuzzyLikeThisQueryParser implements QueryParser { query.setBoost(boost); query.setIgnoreTF(ignoreTF); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java index 124a509f6fa..c4a99399939 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java @@ -45,6 +45,8 @@ public class FuzzyQueryBuilder extends BaseQueryBuilder implements MultiTermQuer //LUCENE 4 UPGRADE we need a testcase for this + documentation private Boolean transpositions; + private String queryName; + /** * Constructs a new term query. * @@ -90,10 +92,18 @@ public class FuzzyQueryBuilder extends BaseQueryBuilder implements MultiTermQuer return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public FuzzyQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(FuzzyQueryParser.NAME); - if (boost == -1 && minSimilarity == null && prefixLength == null) { + if (boost == -1 && minSimilarity == null && prefixLength == null && queryName != null) { builder.field(name, value); } else { builder.startObject(name); @@ -113,6 +123,9 @@ public class FuzzyQueryBuilder extends BaseQueryBuilder implements MultiTermQuer if (maxExpansions != null) { builder.field("max_expansions", maxExpansions); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/FuzzyQueryParser.java b/src/main/java/org/elasticsearch/index/query/FuzzyQueryParser.java index 7bb9b072b72..0c264613046 100644 --- a/src/main/java/org/elasticsearch/index/query/FuzzyQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FuzzyQueryParser.java @@ -65,6 +65,7 @@ public class FuzzyQueryParser implements QueryParser { int prefixLength = FuzzyQuery.defaultPrefixLength; int maxExpansions = FuzzyQuery.defaultMaxExpansions; boolean transpositions = false; + String queryName = null; MultiTermQuery.RewriteMethod rewriteMethod = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { @@ -89,6 +90,8 @@ public class FuzzyQueryParser implements QueryParser { transpositions = parser.booleanValue(); } else if ("rewrite".equals(currentFieldName)) { rewriteMethod = QueryParsers.parseRewriteMethod(parser.textOrNull(), null); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[fuzzy] query does not support [" + currentFieldName + "]"); } @@ -123,6 +126,10 @@ public class FuzzyQueryParser implements QueryParser { } query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + query = wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java index c8b60ded8a2..552f1666fec 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java @@ -19,12 +19,12 @@ package org.elasticsearch.index.query; -import java.io.IOException; - import org.elasticsearch.common.geo.SpatialStrategy; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.xcontent.XContentBuilder; +import java.io.IOException; + /** * {@link QueryBuilder} that builds a GeoShape Query */ @@ -44,6 +44,8 @@ public class GeoShapeQueryBuilder extends BaseQueryBuilder implements BoostableQ private String indexedShapeIndex; private String indexedShapeFieldName; + private String queryName; + /** * Creates a new GeoShapeQueryBuilder whose Query will be against the * given field name using the given Shape @@ -117,6 +119,14 @@ public class GeoShapeQueryBuilder extends BaseQueryBuilder implements BoostableQ return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public GeoShapeQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(GeoShapeQueryParser.NAME); @@ -145,6 +155,9 @@ public class GeoShapeQueryBuilder extends BaseQueryBuilder implements BoostableQ if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryParser.java b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryParser.java index b9735fbd281..46e1ceeda3e 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoShapeQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoShapeQueryParser.java @@ -70,6 +70,7 @@ public class GeoShapeQueryParser implements QueryParser { XContentParser.Token token; String currentFieldName = null; float boost = 1f; + String queryName = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -118,6 +119,8 @@ public class GeoShapeQueryParser implements QueryParser { } else if (token.isValue()) { if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } } } @@ -147,6 +150,9 @@ public class GeoShapeQueryParser implements QueryParser { } Query query = strategy.makeQuery(getArgs(shape, shapeRelation)); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } diff --git a/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java index 69a85e14889..8665f4a9e62 100644 --- a/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java @@ -38,6 +38,8 @@ public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQ private Integer shortCircuitCutoff; + private String queryName; + public HasChildQueryBuilder(String type, QueryBuilder queryBuilder) { this.childType = type; this.queryBuilder = queryBuilder; @@ -69,6 +71,14 @@ public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQ return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public HasChildQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(HasChildQueryParser.NAME); @@ -84,6 +94,9 @@ public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQ if (shortCircuitCutoff != null) { builder.field("short_circuit_cutoff", shortCircuitCutoff); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java b/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java index 998e48daf71..265c0504acd 100644 --- a/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/HasChildQueryParser.java @@ -60,6 +60,7 @@ public class HasChildQueryParser implements QueryParser { String childType = null; ScoreType scoreType = null; int shortCircuitParentDocSet = 8192; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -99,6 +100,8 @@ public class HasChildQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("short_circuit_cutoff".equals(currentFieldName)) { shortCircuitParentDocSet = parser.intValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[has_child] query does not support [" + currentFieldName + "]"); } @@ -146,6 +149,9 @@ public class HasChildQueryParser implements QueryParser { searchContext.addRewrite(hasChildFilter); query = new XConstantScoreQuery(hasChildFilter); } + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } query.setBoost(boost); return query; } diff --git a/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java index cf66b5f341a..60abb6b36e9 100644 --- a/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java @@ -32,6 +32,7 @@ public class HasParentQueryBuilder extends BaseQueryBuilder implements Boostable private final String parentType; private String scoreType; private float boost = 1.0f; + private String queryName; /** * @param parentType The parent type @@ -55,6 +56,14 @@ public class HasParentQueryBuilder extends BaseQueryBuilder implements Boostable return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public HasParentQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(HasParentQueryParser.NAME); builder.field("query"); @@ -66,6 +75,10 @@ public class HasParentQueryBuilder extends BaseQueryBuilder implements Boostable if (boost != 1.0f) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } + builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/HasParentQueryParser.java b/src/main/java/org/elasticsearch/index/query/HasParentQueryParser.java index 798dd89002c..df726c6063d 100644 --- a/src/main/java/org/elasticsearch/index/query/HasParentQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/HasParentQueryParser.java @@ -62,6 +62,7 @@ public class HasParentQueryParser implements QueryParser { float boost = 1.0f; String parentType = null; boolean score = false; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -102,6 +103,8 @@ public class HasParentQueryParser implements QueryParser { } } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[has_parent] query does not support [" + currentFieldName + "]"); } @@ -170,6 +173,9 @@ public class HasParentQueryParser implements QueryParser { query = new XConstantScoreQuery(hasParentFilter); } query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } diff --git a/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java index 0d521acab75..d234032b6da 100644 --- a/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/IdsQueryBuilder.java @@ -37,6 +37,8 @@ public class IdsQueryBuilder extends BaseQueryBuilder implements BoostableQueryB private float boost = -1; + private String queryName; + public IdsQueryBuilder(String... types) { this.types = types == null ? null : Arrays.asList(types); } @@ -65,6 +67,14 @@ public class IdsQueryBuilder extends BaseQueryBuilder implements BoostableQueryB return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public IdsQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(IdsQueryParser.NAME); @@ -87,6 +97,9 @@ public class IdsQueryBuilder extends BaseQueryBuilder implements BoostableQueryB if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java b/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java index 7e931ff1810..725f2493ac2 100644 --- a/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java @@ -60,6 +60,7 @@ public class IdsQueryParser implements QueryParser { Collection types = null; String currentFieldName = null; float boost = 1.0f; + String queryName = null; XContentParser.Token token; boolean idsProvided = false; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -92,6 +93,8 @@ public class IdsQueryParser implements QueryParser { types = ImmutableList.of(parser.text()); } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[ids] query does not support [" + currentFieldName + "]"); } @@ -116,6 +119,9 @@ public class IdsQueryParser implements QueryParser { // no need for constant score filter, since we don't cache the filter, and it always takes deletes into account ConstantScoreQuery query = new ConstantScoreQuery(filter); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java index b9399c5d529..8a2038455be 100644 --- a/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java @@ -36,6 +36,8 @@ public class IndicesQueryBuilder extends BaseQueryBuilder { private String sNoMatchQuery; private QueryBuilder noMatchQuery; + private String queryName; + public IndicesQueryBuilder(QueryBuilder queryBuilder, String... indices) { this.queryBuilder = queryBuilder; this.indices = indices; @@ -57,6 +59,14 @@ public class IndicesQueryBuilder extends BaseQueryBuilder { return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public IndicesQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(IndicesQueryParser.NAME); @@ -69,6 +79,9 @@ public class IndicesQueryBuilder extends BaseQueryBuilder { } else if (sNoMatchQuery != null) { builder.field("no_match_query", sNoMatchQuery); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java b/src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java index 801bb958a06..10e3f0e98b4 100644 --- a/src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java @@ -60,6 +60,7 @@ public class IndicesQueryParser implements QueryParser { Query query = null; boolean queryFound = false; Set indices = Sets.newHashSet(); + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -98,6 +99,8 @@ public class IndicesQueryParser implements QueryParser { } else if ("none".equals(type)) { noMatchQuery = MatchNoDocsQuery.INSTANCE; } + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[indices] query does not support [" + currentFieldName + "]"); } @@ -121,9 +124,15 @@ public class IndicesQueryParser implements QueryParser { for (String index : concreteIndices) { if (Regex.simpleMatch(index, parseContext.index().name())) { + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } + if (queryName != null) { + parseContext.addNamedQuery(queryName, noMatchQuery); + } return noMatchQuery; } } diff --git a/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java index 809044d6221..2aa8413fe12 100644 --- a/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java @@ -89,6 +89,8 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer private Float cutoff_Frequency = null; + private String queryName; + /** * Constructs a new text query. */ @@ -204,6 +206,14 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public MatchQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(MatchQueryParser.NAME); @@ -256,6 +266,9 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer if (cutoff_Frequency != null) { builder.field("cutoff_frequency", cutoff_Frequency); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/MatchQueryParser.java b/src/main/java/org/elasticsearch/index/query/MatchQueryParser.java index 54d4b7a750b..765286a5861 100644 --- a/src/main/java/org/elasticsearch/index/query/MatchQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/MatchQueryParser.java @@ -19,7 +19,6 @@ package org.elasticsearch.index.query; -import org.apache.lucene.queries.CommonTermsQuery; import org.apache.lucene.queries.ExtendedCommonTermsQuery; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; @@ -74,6 +73,7 @@ public class MatchQueryParser implements QueryParser { float boost = 1.0f; MatchQuery matchQuery = new MatchQuery(parseContext); String minimumShouldMatch = null; + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { @@ -139,6 +139,8 @@ public class MatchQueryParser implements QueryParser { } else { throw new QueryParsingException(parseContext.index(), "Unsupported zero_terms_docs value [" + zeroTermsDocs + "]"); } + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[match] query does not support [" + currentFieldName + "]"); } @@ -169,6 +171,9 @@ public class MatchQueryParser implements QueryParser { ((ExtendedCommonTermsQuery)query).setLowFreqMinimumNumberShouldMatch(minimumShouldMatch); } query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryBuilder.java index bbcac6a5b1a..ff318b40b91 100644 --- a/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryBuilder.java @@ -43,6 +43,7 @@ public class MoreLikeThisFieldQueryBuilder extends BaseQueryBuilder implements B private float boost = -1; private String analyzer; private Boolean failOnUnsupportedField; + private String queryName; /** * A more like this query that runs against a specific field. @@ -164,6 +165,14 @@ public class MoreLikeThisFieldQueryBuilder extends BaseQueryBuilder implements B return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public MoreLikeThisFieldQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(MoreLikeThisFieldQueryParser.NAME); @@ -212,6 +221,9 @@ public class MoreLikeThisFieldQueryBuilder extends BaseQueryBuilder implements B if (failOnUnsupportedField != null) { builder.field("fail_on_unsupported_field", failOnUnsupportedField); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryParser.java b/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryParser.java index 6ad95c7f3a9..11b741d2191 100644 --- a/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/MoreLikeThisFieldQueryParser.java @@ -68,6 +68,7 @@ public class MoreLikeThisFieldQueryParser implements QueryParser { mltQuery.setSimilarity(parseContext.searchSimilarity()); Analyzer analyzer = null; boolean failOnUnsupportedField = true; + String queryName = null; String currentFieldName = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -99,6 +100,8 @@ public class MoreLikeThisFieldQueryParser implements QueryParser { mltQuery.setBoost(parser.floatValue()); } else if ("fail_on_unsupported_field".equals(currentFieldName) || "failOnUnsupportedField".equals(currentFieldName)) { failOnUnsupportedField = parser.booleanValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[mlt_field] query does not support [" + currentFieldName + "]"); } @@ -144,6 +147,10 @@ public class MoreLikeThisFieldQueryParser implements QueryParser { } mltQuery.setAnalyzer(analyzer); mltQuery.setMoreLikeFields(new String[]{fieldName}); - return wrapSmartNameQuery(mltQuery, smartNameFieldMappers, parseContext); + Query query = wrapSmartNameQuery(mltQuery, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index c22c25a863b..a08411fa277 100644 --- a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -44,6 +44,7 @@ public class MoreLikeThisQueryBuilder extends BaseQueryBuilder implements Boosta private float boost = -1; private String analyzer; private Boolean failOnUnsupportedField; + private String queryName; /** * Constructs a new more like this query which uses the "_all" field. @@ -172,6 +173,14 @@ public class MoreLikeThisQueryBuilder extends BaseQueryBuilder implements Boosta return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public MoreLikeThisQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(MoreLikeThisQueryParser.NAME); @@ -226,6 +235,9 @@ public class MoreLikeThisQueryBuilder extends BaseQueryBuilder implements Boosta if (failOnUnsupportedField != null) { builder.field("fail_on_unsupported_field", failOnUnsupportedField); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryParser.java b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryParser.java index 48c476c619a..db57e0208a7 100644 --- a/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryParser.java @@ -60,6 +60,7 @@ public class MoreLikeThisQueryParser implements QueryParser { Analyzer analyzer = null; List moreLikeFields = null; boolean failOnUnsupportedField = true; + String queryName = null; XContentParser.Token token; String currentFieldName = null; @@ -92,6 +93,8 @@ public class MoreLikeThisQueryParser implements QueryParser { mltQuery.setBoost(parser.floatValue()); } else if ("fail_on_unsupported_field".equals(currentFieldName) || "failOnUnsupportedField".equals(currentFieldName)) { failOnUnsupportedField = parser.booleanValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[mlt] query does not support [" + currentFieldName + "]"); } @@ -142,7 +145,9 @@ public class MoreLikeThisQueryParser implements QueryParser { return null; } mltQuery.setMoreLikeFields(moreLikeFields.toArray(Strings.EMPTY_ARRAY)); - + if (queryName != null) { + parseContext.addNamedQuery(queryName, mltQuery); + } return mltQuery; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java index f280233fbec..1bb18defabc 100644 --- a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java @@ -71,6 +71,8 @@ public class MultiMatchQueryBuilder extends BaseQueryBuilder implements Boostabl private MatchQueryBuilder.ZeroTermsQuery zeroTermsQuery = null; + private String queryName; + /** * Constructs a new text query. */ @@ -213,6 +215,14 @@ public class MultiMatchQueryBuilder extends BaseQueryBuilder implements Boostabl return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public MultiMatchQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(MultiMatchQueryParser.NAME); @@ -285,6 +295,10 @@ public class MultiMatchQueryBuilder extends BaseQueryBuilder implements Boostabl builder.field("zero_terms_query", zeroTermsQuery.toString()); } + if (queryName != null) { + builder.field("_name", queryName); + } + builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryParser.java b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryParser.java index d49370349fa..6dc13226ac8 100644 --- a/src/main/java/org/elasticsearch/index/query/MultiMatchQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/MultiMatchQueryParser.java @@ -60,6 +60,7 @@ public class MultiMatchQueryParser implements QueryParser { MultiMatchQuery multiMatchQuery = new MultiMatchQuery(parseContext); String minimumShouldMatch = null; Map fieldNameWithBoosts = Maps.newHashMap(); + String queryName = null; XContentParser.Token token; String currentFieldName = null; @@ -156,6 +157,8 @@ public class MultiMatchQueryParser implements QueryParser { } else { throw new QueryParsingException(parseContext.index(), "Unsupported zero_terms_docs value [" + zeroTermsDocs + "]"); } + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[match] query does not support [" + currentFieldName + "]"); } @@ -176,6 +179,9 @@ public class MultiMatchQueryParser implements QueryParser { } query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java index 9ef47d122d6..6961e78cc88 100644 --- a/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java @@ -34,6 +34,8 @@ public class NestedQueryBuilder extends BaseQueryBuilder implements BoostableQue private float boost = 1.0f; + private String queryName; + public NestedQueryBuilder(String path, QueryBuilder queryBuilder) { this.path = path; this.queryBuilder = queryBuilder; @@ -63,6 +65,14 @@ public class NestedQueryBuilder extends BaseQueryBuilder implements BoostableQue return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public NestedQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(NestedQueryParser.NAME); @@ -80,6 +90,9 @@ public class NestedQueryBuilder extends BaseQueryBuilder implements BoostableQue if (boost != 1.0f) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/NestedQueryParser.java b/src/main/java/org/elasticsearch/index/query/NestedQueryParser.java index 5c1386fbeaa..5f57fbfe586 100644 --- a/src/main/java/org/elasticsearch/index/query/NestedQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/NestedQueryParser.java @@ -61,6 +61,7 @@ public class NestedQueryParser implements QueryParser { float boost = 1.0f; String path = null; ScoreMode scoreMode = ScoreMode.Avg; + String queryName = null; // we need a late binding filter so we can inject a parent nested filter inner nested queries LateBindingParentFilter currentParentFilterContext = parentFilterContext.get(); @@ -104,6 +105,8 @@ public class NestedQueryParser implements QueryParser { } else { throw new QueryParsingException(parseContext.index(), "illegal score_mode for nested query [" + sScoreMode + "]"); } + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[nested] query does not support [" + currentFieldName + "]"); } @@ -154,6 +157,9 @@ public class NestedQueryParser implements QueryParser { ToParentBlockJoinQuery joinQuery = new ToParentBlockJoinQuery(query, parentFilter, scoreMode); joinQuery.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, joinQuery); + } return joinQuery; } finally { // restore the thread local one... diff --git a/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java index 0dd8c521bfc..097ef0e1877 100644 --- a/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java @@ -38,6 +38,8 @@ public class PrefixQueryBuilder extends BaseQueryBuilder implements MultiTermQue private String rewrite; + private String queryName; + /** * A Query that matches documents containing terms with a specified prefix. * @@ -63,10 +65,18 @@ public class PrefixQueryBuilder extends BaseQueryBuilder implements MultiTermQue return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public PrefixQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(PrefixQueryParser.NAME); - if (boost == -1 && rewrite == null) { + if (boost == -1 && rewrite == null && queryName != null) { builder.field(name, prefix); } else { builder.startObject(name); @@ -77,6 +87,9 @@ public class PrefixQueryBuilder extends BaseQueryBuilder implements MultiTermQue if (rewrite != null) { builder.field("rewrite", rewrite); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/PrefixQueryParser.java b/src/main/java/org/elasticsearch/index/query/PrefixQueryParser.java index db273a47a10..aa68e025e6c 100644 --- a/src/main/java/org/elasticsearch/index/query/PrefixQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/PrefixQueryParser.java @@ -59,6 +59,7 @@ public class PrefixQueryParser implements QueryParser { } String fieldName = parser.currentName(); String rewriteMethod = null; + String queryName = null; Object value = null; float boost = 1.0f; @@ -77,6 +78,8 @@ public class PrefixQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("rewrite".equals(currentFieldName)) { rewriteMethod = parser.textOrNull(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } } else { throw new QueryParsingException(parseContext.index(), "[prefix] query does not support [" + currentFieldName + "]"); @@ -116,6 +119,10 @@ public class PrefixQueryParser implements QueryParser { query = prefixQuery; } query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + query = wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/src/main/java/org/elasticsearch/index/query/QueryParseContext.java index eee60fb3b51..9bc213fd3f8 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryParseContext.java +++ b/src/main/java/org/elasticsearch/index/query/QueryParseContext.java @@ -25,6 +25,7 @@ import org.apache.lucene.queryparser.classic.MapperQueryParser; import org.apache.lucene.queryparser.classic.QueryParserSettings; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryWrapperFilter; import org.apache.lucene.search.similarities.Similarity; import org.elasticsearch.cache.recycler.CacheRecycler; import org.elasticsearch.common.Nullable; @@ -167,6 +168,10 @@ public class QueryParseContext { namedFilters.put(name, filter); } + public void addNamedQuery(String name, Query query) { + namedFilters.put(name, new QueryWrapperFilter(query)); + } + public ImmutableMap copyNamedFilters() { if (namedFilters.isEmpty()) { return ImmutableMap.of(); diff --git a/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java index 7e55faf871c..61158c7ae72 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java @@ -90,6 +90,8 @@ public class QueryStringQueryBuilder extends BaseQueryBuilder implements Boostab private Boolean lenient; + private String queryName; + public QueryStringQueryBuilder(String queryString) { this.queryString = queryString; } @@ -303,6 +305,14 @@ public class QueryStringQueryBuilder extends BaseQueryBuilder implements Boostab return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public QueryStringQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(QueryStringQueryParser.NAME); @@ -384,6 +394,9 @@ public class QueryStringQueryBuilder extends BaseQueryBuilder implements Boostab if (lenient != null) { builder.field("lenient", lenient); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/QueryStringQueryParser.java b/src/main/java/org/elasticsearch/index/query/QueryStringQueryParser.java index 2710ee700aa..e9484a4c756 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryStringQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/QueryStringQueryParser.java @@ -22,9 +22,7 @@ package org.elasticsearch.index.query; import com.google.common.collect.Lists; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TObjectFloatHashMap; - import org.apache.lucene.queryparser.classic.MapperQueryParser; -import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParserSettings; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; @@ -67,6 +65,7 @@ public class QueryStringQueryParser implements QueryParser { public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); + String queryName = null; QueryParserSettings qpSettings = new QueryParserSettings(); qpSettings.defaultField(parseContext.defaultField()); qpSettings.lenient(parseContext.queryStringLenient()); @@ -185,6 +184,8 @@ public class QueryStringQueryParser implements QueryParser { qpSettings.quoteFieldSuffix(parser.textOrNull()); } else if ("lenient".equalsIgnoreCase(currentFieldName)) { qpSettings.lenient(parser.booleanValue()); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[query_string] query does not support [" + currentFieldName + "]"); } @@ -222,6 +223,9 @@ public class QueryStringQueryParser implements QueryParser { Queries.applyMinimumShouldMatch((BooleanQuery) query, qpSettings.minimumShouldMatch()); } parseContext.indexCache().queryParserCache().put(qpSettings, query); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } catch (org.apache.lucene.queryparser.classic.ParseException e) { throw new QueryParsingException(parseContext.index(), "Failed to parse query [" + qpSettings.queryString() + "]", e); diff --git a/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java index fbffd45eccc..df082110798 100644 --- a/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java @@ -42,6 +42,8 @@ public class RangeQueryBuilder extends BaseQueryBuilder implements MultiTermQuer private float boost = -1; + private String queryName; + /** * A Query that matches documents within an range of terms. * @@ -388,6 +390,14 @@ public class RangeQueryBuilder extends BaseQueryBuilder implements MultiTermQuer return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public RangeQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(RangeQueryParser.NAME); @@ -399,6 +409,9 @@ public class RangeQueryBuilder extends BaseQueryBuilder implements MultiTermQuer if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/RangeQueryParser.java b/src/main/java/org/elasticsearch/index/query/RangeQueryParser.java index 21a7c24e654..de03c550ad8 100644 --- a/src/main/java/org/elasticsearch/index/query/RangeQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/RangeQueryParser.java @@ -65,6 +65,7 @@ public class RangeQueryParser implements QueryParser { boolean includeLower = true; boolean includeUpper = true; float boost = 1.0f; + String queryName = null; String currentFieldName = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -93,6 +94,8 @@ public class RangeQueryParser implements QueryParser { } else if ("lte".equals(currentFieldName) || "le".equals(currentFieldName)) { to = parser.objectBytes(); includeUpper = true; + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[range] query does not support [" + currentFieldName + "]"); } @@ -117,6 +120,10 @@ public class RangeQueryParser implements QueryParser { query = new TermRangeQuery(fieldName, BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to), includeLower, includeUpper); } query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + query = wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java index 2a978cfeb43..732768b23d9 100644 --- a/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java @@ -36,6 +36,7 @@ public class RegexpQueryBuilder extends BaseQueryBuilder implements BoostableQue private int flags = -1; private float boost = -1; private String rewrite; + private String queryName; /** * Constructs a new term query. @@ -75,10 +76,18 @@ public class RegexpQueryBuilder extends BaseQueryBuilder implements BoostableQue return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public RegexpQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(RegexpQueryParser.NAME); - if (boost == -1 && rewrite == null) { + if (boost == -1 && rewrite == null && queryName != null) { builder.field(name, regexp); } else { builder.startObject(name); @@ -92,6 +101,9 @@ public class RegexpQueryBuilder extends BaseQueryBuilder implements BoostableQue if (rewrite != null) { builder.field("rewrite", rewrite); } + if (queryName != null) { + builder.field("name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/RegexpQueryParser.java b/src/main/java/org/elasticsearch/index/query/RegexpQueryParser.java index e6acbf83ea8..46ab2522da4 100644 --- a/src/main/java/org/elasticsearch/index/query/RegexpQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/RegexpQueryParser.java @@ -64,6 +64,7 @@ public class RegexpQueryParser implements QueryParser { Object value = null; float boost = 1.0f; int flagsValue = -1; + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { String currentFieldName = null; @@ -85,6 +86,8 @@ public class RegexpQueryParser implements QueryParser { if (flagsValue < 0) { flagsValue = RegExp.ALL; } + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } } else { throw new QueryParsingException(parseContext.index(), "[regexp] query does not support [" + currentFieldName + "]"); @@ -124,7 +127,11 @@ public class RegexpQueryParser implements QueryParser { query = regexpQuery; } query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + query = wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } diff --git a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java index ca5beca1a2e..34fe923f4cc 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java @@ -34,6 +34,8 @@ public class SpanFirstQueryBuilder extends BaseQueryBuilder implements SpanQuery private float boost = -1; + private String queryName; + public SpanFirstQueryBuilder(SpanQueryBuilder matchBuilder, int end) { this.matchBuilder = matchBuilder; this.end = end; @@ -44,6 +46,14 @@ public class SpanFirstQueryBuilder extends BaseQueryBuilder implements SpanQuery return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public SpanFirstQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(SpanFirstQueryParser.NAME); @@ -53,6 +63,9 @@ public class SpanFirstQueryBuilder extends BaseQueryBuilder implements SpanQuery if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryParser.java index b30641bf44f..7af3c6e9fe8 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanFirstQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanFirstQueryParser.java @@ -52,6 +52,7 @@ public class SpanFirstQueryParser implements QueryParser { SpanQuery match = null; int end = -1; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -73,6 +74,8 @@ public class SpanFirstQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("end".equals(currentFieldName)) { end = parser.intValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[span_first] query does not support [" + currentFieldName + "]"); } @@ -87,6 +90,9 @@ public class SpanFirstQueryParser implements QueryParser { SpanFirstQuery query = new SpanFirstQuery(match, end); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java index c8b0a619333..3c89dfd6291 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java @@ -39,6 +39,8 @@ public class SpanNearQueryBuilder extends BaseQueryBuilder implements SpanQueryB private float boost = -1; + private String queryName; + public SpanNearQueryBuilder clause(SpanQueryBuilder clause) { clauses.add(clause); return this; @@ -64,6 +66,14 @@ public class SpanNearQueryBuilder extends BaseQueryBuilder implements SpanQueryB return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public SpanNearQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { if (clauses.isEmpty()) { @@ -88,6 +98,9 @@ public class SpanNearQueryBuilder extends BaseQueryBuilder implements SpanQueryB if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java index c0e69d32d55..81ecc400ac2 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java @@ -55,6 +55,7 @@ public class SpanNearQueryParser implements QueryParser { Integer slop = null; boolean inOrder = true; boolean collectPayloads = true; + String queryName = null; List clauses = newArrayList(); @@ -84,6 +85,8 @@ public class SpanNearQueryParser implements QueryParser { slop = Integer.valueOf(parser.intValue()); } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[span_near] query does not support [" + currentFieldName + "]"); } @@ -100,6 +103,9 @@ public class SpanNearQueryParser implements QueryParser { SpanNearQuery query = new SpanNearQuery(clauses.toArray(new SpanQuery[clauses.size()]), slop.intValue(), inOrder, collectPayloads); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java index c9357ba22a4..0c340296284 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java @@ -34,6 +34,8 @@ public class SpanNotQueryBuilder extends BaseQueryBuilder implements SpanQueryBu private float boost = -1; + private String queryName; + public SpanNotQueryBuilder include(SpanQueryBuilder include) { this.include = include; return this; @@ -49,6 +51,14 @@ public class SpanNotQueryBuilder extends BaseQueryBuilder implements SpanQueryBu return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public SpanNotQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { if (include == null) { @@ -65,6 +75,9 @@ public class SpanNotQueryBuilder extends BaseQueryBuilder implements SpanQueryBu if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/SpanNotQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanNotQueryParser.java index c767dfb0777..f77e6667c9a 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanNotQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanNotQueryParser.java @@ -52,6 +52,7 @@ public class SpanNotQueryParser implements QueryParser { SpanQuery include = null; SpanQuery exclude = null; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -77,6 +78,8 @@ public class SpanNotQueryParser implements QueryParser { } else { if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[span_not] query does not support [" + currentFieldName + "]"); } @@ -91,6 +94,9 @@ public class SpanNotQueryParser implements QueryParser { SpanNotQuery query = new SpanNotQuery(include, exclude); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java index b1ceb1b9c9b..cb30e2d07af 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java @@ -33,6 +33,8 @@ public class SpanOrQueryBuilder extends BaseQueryBuilder implements SpanQueryBui private float boost = -1; + private String queryName; + public SpanOrQueryBuilder clause(SpanQueryBuilder clause) { clauses.add(clause); return this; @@ -43,6 +45,14 @@ public class SpanOrQueryBuilder extends BaseQueryBuilder implements SpanQueryBui return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public SpanOrQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { if (clauses.isEmpty()) { @@ -57,6 +67,9 @@ public class SpanOrQueryBuilder extends BaseQueryBuilder implements SpanQueryBui if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/SpanOrQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanOrQueryParser.java index 91023d50bb7..af070055b11 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanOrQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanOrQueryParser.java @@ -52,6 +52,7 @@ public class SpanOrQueryParser implements QueryParser { XContentParser parser = parseContext.parser(); float boost = 1.0f; + String queryName = null; List clauses = newArrayList(); @@ -75,6 +76,8 @@ public class SpanOrQueryParser implements QueryParser { } else { if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[span_or] query does not support [" + currentFieldName + "]"); } @@ -86,6 +89,9 @@ public class SpanOrQueryParser implements QueryParser { SpanOrQuery query = new SpanOrQuery(clauses.toArray(new SpanQuery[clauses.size()])); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java index ba23fdb883a..ee4dd2eeb72 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java @@ -34,6 +34,8 @@ public class SpanTermQueryBuilder extends BaseQueryBuilder implements SpanQueryB private float boost = -1; + private String queryName; + public SpanTermQueryBuilder(String name, String value) { this(name, (Object) value); } @@ -64,15 +66,28 @@ public class SpanTermQueryBuilder extends BaseQueryBuilder implements SpanQueryB return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public SpanTermQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(SpanTermQueryParser.NAME); - if (boost == -1) { + if (boost == -1 && queryName != null) { builder.field(name, value); } else { builder.startObject(name); builder.field("value", value); - builder.field("boost", boost); + if (boost != -1) { + builder.field("boost", boost); + } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java index 7ace5138fac..e0519b43af0 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java @@ -30,8 +30,6 @@ import org.elasticsearch.index.mapper.MapperService; import java.io.IOException; -import static org.elasticsearch.index.query.support.QueryParsers.wrapSmartNameQuery; - /** * */ @@ -62,6 +60,7 @@ public class SpanTermQueryParser implements QueryParser { String value = null; float boost = 1.0f; + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { String currentFieldName = null; @@ -75,6 +74,8 @@ public class SpanTermQueryParser implements QueryParser { value = parser.text(); } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[span_term] query does not support [" + currentFieldName + "]"); } @@ -105,6 +106,9 @@ public class SpanTermQueryParser implements QueryParser { SpanTermQuery query = new SpanTermQuery(new Term(fieldName, valueBytes)); query.setBoost(boost); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java index 188c0901ad0..41b0534f1e1 100644 --- a/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/TermQueryBuilder.java @@ -36,6 +36,8 @@ public class TermQueryBuilder extends BaseQueryBuilder implements BoostableQuery private float boost = -1; + private String queryName; + /** * Constructs a new term query. * @@ -116,15 +118,28 @@ public class TermQueryBuilder extends BaseQueryBuilder implements BoostableQuery return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public TermQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(TermQueryParser.NAME); - if (boost == -1) { + if (boost == -1 && queryName == null) { builder.field(name, value); } else { builder.startObject(name); builder.field("value", value); - builder.field("boost", boost); + if (boost != -1) { + builder.field("boost", boost); + } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/TermQueryParser.java b/src/main/java/org/elasticsearch/index/query/TermQueryParser.java index 97845044a62..37ee028462b 100644 --- a/src/main/java/org/elasticsearch/index/query/TermQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/TermQueryParser.java @@ -57,6 +57,7 @@ public class TermQueryParser implements QueryParser { } String fieldName = parser.currentName(); + String queryName = null; Object value = null; float boost = 1.0f; token = parser.nextToken(); @@ -72,6 +73,8 @@ public class TermQueryParser implements QueryParser { value = parser.objectBytes(); } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[term] query does not support [" + currentFieldName + "]"); } @@ -106,6 +109,10 @@ public class TermQueryParser implements QueryParser { query = new TermQuery(new Term(fieldName, BytesRefs.toBytesRef(value))); } query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + query = wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } diff --git a/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java index 5153cf9846f..1a997e921d0 100644 --- a/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java @@ -39,6 +39,8 @@ public class TermsQueryBuilder extends BaseQueryBuilder implements BoostableQuer private float boost = -1; + private String queryName; + /** * A query for a field based on several terms matching on any of them. * @@ -156,6 +158,14 @@ public class TermsQueryBuilder extends BaseQueryBuilder implements BoostableQuer return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public TermsQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(TermsQueryParser.NAME); @@ -174,6 +184,9 @@ public class TermsQueryBuilder extends BaseQueryBuilder implements BoostableQuer if (boost != -1) { builder.field("boost", boost); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } diff --git a/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java b/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java index ee723df538e..b5d713b624b 100644 --- a/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java @@ -69,6 +69,7 @@ public class TermsQueryParser implements QueryParser { float boost = 1.0f; String minimumShouldMatch = null; List values = newArrayList(); + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -93,6 +94,8 @@ public class TermsQueryParser implements QueryParser { minimumShouldMatch = parser.textOrNull(); } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[terms] query does not support [" + currentFieldName + "]"); } @@ -116,17 +119,21 @@ public class TermsQueryParser implements QueryParser { } try { - BooleanQuery query = new BooleanQuery(disableCoord); + BooleanQuery booleanQuery = new BooleanQuery(disableCoord); for (Object value : values) { if (mapper != null) { - query.add(new BooleanClause(mapper.termQuery(value, parseContext), BooleanClause.Occur.SHOULD)); + booleanQuery.add(new BooleanClause(mapper.termQuery(value, parseContext), BooleanClause.Occur.SHOULD)); } else { - query.add(new TermQuery(new Term(fieldName, BytesRefs.toString(value))), BooleanClause.Occur.SHOULD); + booleanQuery.add(new TermQuery(new Term(fieldName, BytesRefs.toString(value))), BooleanClause.Occur.SHOULD); } } - query.setBoost(boost); - Queries.applyMinimumShouldMatch(query, minimumShouldMatch); - return wrapSmartNameQuery(optimizeQuery(fixNegativeQueryIfNeeded(query)), smartNameFieldMappers, parseContext); + booleanQuery.setBoost(boost); + Queries.applyMinimumShouldMatch(booleanQuery, minimumShouldMatch); + Query query = wrapSmartNameQuery(optimizeQuery(fixNegativeQueryIfNeeded(booleanQuery)), smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } finally { if (smartNameFieldMappers != null && smartNameFieldMappers.explicitTypeInNameWithDocMapper()) { QueryParseContext.setTypes(previousTypes); diff --git a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryBuilder.java index 65770f5de96..21c4ecde41e 100644 --- a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryBuilder.java @@ -40,6 +40,8 @@ public class TopChildrenQueryBuilder extends BaseQueryBuilder implements Boostab private int incrementalFactor = -1; + private String queryName; + public TopChildrenQueryBuilder(String type, QueryBuilder queryBuilder) { this.childType = type; this.queryBuilder = queryBuilder; @@ -80,6 +82,14 @@ public class TopChildrenQueryBuilder extends BaseQueryBuilder implements Boostab return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public TopChildrenQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(TopChildrenQueryParser.NAME); @@ -98,6 +108,9 @@ public class TopChildrenQueryBuilder extends BaseQueryBuilder implements Boostab if (incrementalFactor != -1) { builder.field("incremental_factor", incrementalFactor); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java index 610ab394ef0..5b4d40ac59e 100644 --- a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java @@ -59,6 +59,7 @@ public class TopChildrenQueryParser implements QueryParser { ScoreType scoreType = ScoreType.MAX; int factor = 5; int incrementalFactor = 2; + String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -94,6 +95,8 @@ public class TopChildrenQueryParser implements QueryParser { factor = parser.intValue(); } else if ("incremental_factor".equals(currentFieldName) || "incrementalFactor".equals(currentFieldName)) { incrementalFactor = parser.intValue(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[top_children] query does not support [" + currentFieldName + "]"); } @@ -129,6 +132,9 @@ public class TopChildrenQueryParser implements QueryParser { } TopChildrenQuery childQuery = new TopChildrenQuery(query, childType, parentType, scoreType, factor, incrementalFactor, parseContext.cacheRecycler()); searchContext.addRewrite(childQuery); + if (queryName != null) { + parseContext.addNamedQuery(queryName, childQuery); + } return childQuery; } } diff --git a/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java index 0205b542afa..4e13d85935e 100644 --- a/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java @@ -43,6 +43,8 @@ public class WildcardQueryBuilder extends BaseQueryBuilder implements MultiTermQ private String rewrite; + private String queryName; + /** * Implements the wildcard search query. Supported wildcards are *, which * matches any character sequence (including the empty one), and ?, @@ -73,10 +75,18 @@ public class WildcardQueryBuilder extends BaseQueryBuilder implements MultiTermQ return this; } + /** + * Sets the query name for the filter that can be used when searching for matched_filters per hit. + */ + public WildcardQueryBuilder queryName(String queryName) { + this.queryName = queryName; + return this; + } + @Override public void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(WildcardQueryParser.NAME); - if (boost == -1 && rewrite == null) { + if (boost == -1 && rewrite == null && queryName != null) { builder.field(name, wildcard); } else { builder.startObject(name); @@ -87,6 +97,9 @@ public class WildcardQueryBuilder extends BaseQueryBuilder implements MultiTermQ if (rewrite != null) { builder.field("rewrite", rewrite); } + if (queryName != null) { + builder.field("_name", queryName); + } builder.endObject(); } builder.endObject(); diff --git a/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java b/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java index 31d6a8e2d33..54caddbf5af 100644 --- a/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java @@ -61,6 +61,7 @@ public class WildcardQueryParser implements QueryParser { String value = null; float boost = 1.0f; + String queryName = null; token = parser.nextToken(); if (token == XContentParser.Token.START_OBJECT) { String currentFieldName = null; @@ -76,6 +77,8 @@ public class WildcardQueryParser implements QueryParser { boost = parser.floatValue(); } else if ("rewrite".equals(currentFieldName)) { rewriteMethod = parser.textOrNull(); + } else if ("_name".equals(currentFieldName)) { + queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[wildcard] query does not support [" + currentFieldName + "]"); } @@ -100,10 +103,14 @@ public class WildcardQueryParser implements QueryParser { valueBytes = new BytesRef(value); } - WildcardQuery query = new WildcardQuery(new Term(fieldName, valueBytes)); - QueryParsers.setRewriteMethod(query, rewriteMethod); - query.setRewriteMethod(QueryParsers.parseRewriteMethod(rewriteMethod)); - query.setBoost(boost); - return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); + WildcardQuery wildcardQuery = new WildcardQuery(new Term(fieldName, valueBytes)); + QueryParsers.setRewriteMethod(wildcardQuery, rewriteMethod); + wildcardQuery.setRewriteMethod(QueryParsers.parseRewriteMethod(rewriteMethod)); + wildcardQuery.setBoost(boost); + Query query = wrapSmartNameQuery(wildcardQuery, smartNameFieldMappers, parseContext); + if (queryName != null) { + parseContext.addNamedQuery(queryName, query); + } + return query; } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/search/fetch/matchedfilters/MatchedFiltersFetchSubPhase.java b/src/main/java/org/elasticsearch/search/fetch/matchedfilters/MatchedFiltersFetchSubPhase.java index 8ca68532da3..3109501ef9c 100644 --- a/src/main/java/org/elasticsearch/search/fetch/matchedfilters/MatchedFiltersFetchSubPhase.java +++ b/src/main/java/org/elasticsearch/search/fetch/matchedfilters/MatchedFiltersFetchSubPhase.java @@ -22,6 +22,7 @@ package org.elasticsearch.search.fetch.matchedfilters; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import org.apache.lucene.search.DocIdSet; +import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; import org.apache.lucene.util.Bits; import org.elasticsearch.ElasticSearchException; @@ -79,10 +80,19 @@ public class MatchedFiltersFetchSubPhase implements FetchSubPhase { Filter filter = entry.getValue(); try { DocIdSet docIdSet = filter.getDocIdSet(hitContext.readerContext(), null); // null is fine, since we filter by hitContext.docId() - if (docIdSet != null) { - Bits docSet = DocIdSets.toSafeBits(hitContext.reader(), docIdSet); - if (docSet.get(hitContext.docId())) { - matchedFilters.add(name); + if (!DocIdSets.isEmpty(docIdSet)) { + Bits bits = docIdSet.bits(); + if (bits != null) { + if (bits.get(hitContext.docId())) { + matchedFilters.add(name); + } + } else { + DocIdSetIterator iterator = docIdSet.iterator(); + if (iterator != null) { + if (iterator.advance(hitContext.docId()) == hitContext.docId()) { + matchedFilters.add(name); + } + } } } } catch (IOException e) { diff --git a/src/test/java/org/elasticsearch/test/integration/search/matchedfilters/MatchedFiltersTests.java b/src/test/java/org/elasticsearch/test/integration/search/matchedfilters/MatchedFiltersTests.java index 88ddae85dfc..b5a5cb263c2 100644 --- a/src/test/java/org/elasticsearch/test/integration/search/matchedfilters/MatchedFiltersTests.java +++ b/src/test/java/org/elasticsearch/test/integration/search/matchedfilters/MatchedFiltersTests.java @@ -27,8 +27,7 @@ import org.junit.Test; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.index.query.FilterBuilders.*; -import static org.elasticsearch.index.query.QueryBuilders.filteredQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.index.query.QueryBuilders.*; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItemInArray; @@ -66,6 +65,25 @@ public class MatchedFiltersTests extends AbstractSharedClusterTest { .execute().actionGet(); + assertNoFailures(searchResponse); + assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); + for (SearchHit hit : searchResponse.getHits()) { + if (hit.id().equals("1") || hit.id().equals("2")) { + assertThat(hit.matchedFilters().length, equalTo(1)); + assertThat(hit.matchedFilters(), hasItemInArray("test1")); + } else if (hit.id().equals("3")) { + assertThat(hit.matchedFilters().length, equalTo(1)); + assertThat(hit.matchedFilters(), hasItemInArray("test2")); + } else { + fail("Unexpected document returned with id " + hit.id()); + } + } + + searchResponse = client().prepareSearch() + .setQuery(boolQuery().should(rangeQuery("number").lte(2).queryName("test1")).should(rangeQuery("number").gt(2).queryName("test2"))) + .execute().actionGet(); + + assertNoFailures(searchResponse); assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); for (SearchHit hit : searchResponse.getHits()) { @@ -109,7 +127,30 @@ public class MatchedFiltersTests extends AbstractSharedClusterTest { termFilter("title", "title1").filterName("title"))) .execute().actionGet(); - assertThat(searchResponse.getShardFailures().length, equalTo(0)); + assertNoFailures(searchResponse); + assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); + + for (SearchHit hit : searchResponse.getHits()) { + if (hit.id().equals("1")) { + assertThat(hit.matchedFilters().length, equalTo(2)); + assertThat(hit.matchedFilters(), hasItemInArray("name")); + assertThat(hit.matchedFilters(), hasItemInArray("title")); + } else if (hit.id().equals("2") || hit.id().equals("3")) { + assertThat(hit.matchedFilters().length, equalTo(1)); + assertThat(hit.matchedFilters(), hasItemInArray("name")); + } else { + fail("Unexpected document returned with id " + hit.id()); + } + } + + searchResponse = client().prepareSearch() + .setQuery(matchAllQuery()) + .setFilter(queryFilter(boolQuery() + .should(termQuery("name", "test").queryName("name")) + .should(termQuery("title", "title1").queryName("title")))) + .execute().actionGet(); + + assertNoFailures(searchResponse); assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); for (SearchHit hit : searchResponse.getHits()) { @@ -154,7 +195,25 @@ public class MatchedFiltersTests extends AbstractSharedClusterTest { .setFilter(termFilter("name", "test").filterName("name")) .execute().actionGet(); - assertThat(searchResponse.getShardFailures().length, equalTo(0)); + assertNoFailures(searchResponse); + assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); + + for (SearchHit hit : searchResponse.getHits()) { + if (hit.id().equals("1") || hit.id().equals("2") || hit.id().equals("3")) { + assertThat(hit.matchedFilters().length, equalTo(2)); + assertThat(hit.matchedFilters(), hasItemInArray("name")); + assertThat(hit.matchedFilters(), hasItemInArray("title")); + } else { + fail("Unexpected document returned with id " + hit.id()); + } + } + + searchResponse = client().prepareSearch() + .setQuery(termsQuery("title", "title1", "title2", "title3").queryName("title")) + .setFilter(queryFilter(matchQuery("name", "test").queryName("name"))) + .execute().actionGet(); + + assertNoFailures(searchResponse); assertThat(searchResponse.getHits().totalHits(), equalTo(3l)); for (SearchHit hit : searchResponse.getHits()) {