1919
2020package org .elasticsearch .index .query ;
2121
22- import org .elasticsearch .common .Nullable ;
22+ import org .apache .lucene .search .ConstantScoreQuery ;
23+ import org .apache .lucene .search .Query ;
24+ import org .elasticsearch .common .io .stream .StreamInput ;
25+ import org .elasticsearch .common .io .stream .StreamOutput ;
26+ import org .elasticsearch .common .lucene .search .Queries ;
2327import org .elasticsearch .common .xcontent .XContentBuilder ;
2428
2529import java .io .IOException ;
30+ import java .util .Objects ;
2631
2732/**
2833 * A query that applies a filter to the results of another query.
3136@ Deprecated
3237public class FilteredQueryBuilder extends AbstractQueryBuilder <FilteredQueryBuilder > {
3338
39+ /** Name of the query in the REST API. */
3440 public static final String NAME = "filtered" ;
35-
41+ /** The query to filter. */
3642 private final QueryBuilder queryBuilder ;
37-
43+ /** The filter to apply to the query. */
3844 private final QueryBuilder filterBuilder ;
3945
4046 static final FilteredQueryBuilder PROTOTYPE = new FilteredQueryBuilder (null , null );
4147
48+ /**
49+ * Returns a {@link MatchAllQueryBuilder} instance that will be used as
50+ * default queryBuilder if none is supplied by the user. Feel free to
51+ * set queryName and boost on that instance - it's always a new one.
52+ * */
53+ private static QueryBuilder generateDefaultQuery () {
54+ return new MatchAllQueryBuilder ();
55+ }
56+
57+ /**
58+ * A query that applies a filter to the results of a match_all query.
59+ * @param filterBuilder The filter to apply on the query (Can be null)
60+ * */
61+ public FilteredQueryBuilder (QueryBuilder filterBuilder ) {
62+ this (generateDefaultQuery (), filterBuilder );
63+ }
64+
4265 /**
4366 * A query that applies a filter to the results of another query.
4467 *
45- * @param queryBuilder The query to apply the filter to (Can be null)
68+ * @param queryBuilder The query to apply the filter to
4669 * @param filterBuilder The filter to apply on the query (Can be null)
4770 */
48- public FilteredQueryBuilder (@ Nullable QueryBuilder queryBuilder , @ Nullable QueryBuilder filterBuilder ) {
49- this .queryBuilder = queryBuilder ;
50- this .filterBuilder = filterBuilder ;
71+ public FilteredQueryBuilder (QueryBuilder queryBuilder , QueryBuilder filterBuilder ) {
72+ this .queryBuilder = (queryBuilder != null ) ? queryBuilder : generateDefaultQuery ();
73+ this .filterBuilder = (filterBuilder != null ) ? filterBuilder : EmptyQueryBuilder .PROTOTYPE ;
74+ }
75+
76+ /** Returns the query to apply the filter to. */
77+ public QueryBuilder query () {
78+ return queryBuilder ;
79+ }
80+
81+ /** Returns the filter to apply to the query results. */
82+ public QueryBuilder filter () {
83+ return filterBuilder ;
5184 }
5285
5386 @ Override
54- protected void doXContent (XContentBuilder builder , Params params ) throws IOException {
55- builder .startObject (NAME );
56- if (queryBuilder != null ) {
57- builder .field ("query" );
58- queryBuilder .toXContent (builder , params );
87+ protected boolean doEquals (FilteredQueryBuilder other ) {
88+ return Objects .equals (queryBuilder , other .queryBuilder ) &&
89+ Objects .equals (filterBuilder , other .filterBuilder );
90+ }
91+
92+ @ Override
93+ public int doHashCode () {
94+ return Objects .hash (queryBuilder , filterBuilder );
95+ }
96+
97+ @ Override
98+ public Query doToQuery (QueryParseContext parseContext ) throws QueryParsingException , IOException {
99+ Query query = queryBuilder .toQuery (parseContext );
100+ Query filter = filterBuilder .toQuery (parseContext );
101+
102+ if (query == null ) {
103+ // Most likely this query was generated from the JSON query DSL - it parsed to an EmptyQueryBuilder so we ignore
104+ // the whole filtered query as there is nothing to filter on. See FilteredQueryParser for an example.
105+ return null ;
59106 }
60- if (filterBuilder != null ) {
61- builder .field ("filter" );
62- filterBuilder .toXContent (builder , params );
107+
108+ if (filter == null || Queries .isConstantMatchAllQuery (filter )) {
109+ // no filter, or match all filter
110+ return query ;
111+ } else if (Queries .isConstantMatchAllQuery (query )) {
112+ // if its a match_all query, use constant_score
113+ return new ConstantScoreQuery (filter );
63114 }
115+
116+ // use a BooleanQuery
117+ return Queries .filtered (query , filter );
118+ }
119+
120+ @ Override
121+ public QueryValidationException validate () {
122+ QueryValidationException validationException = null ;
123+ validationException = validateInnerQuery (queryBuilder , validationException );
124+ validationException = validateInnerQuery (filterBuilder , validationException );
125+ return validationException ;
126+
127+ }
128+
129+ @ Override
130+ protected void doXContent (XContentBuilder builder , Params params ) throws IOException {
131+ builder .startObject (NAME );
132+ builder .field ("query" );
133+ queryBuilder .toXContent (builder , params );
134+ builder .field ("filter" );
135+ filterBuilder .toXContent (builder , params );
64136 printBoostAndQueryName (builder );
65137 builder .endObject ();
66138 }
@@ -69,4 +141,18 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
69141 public String getName () {
70142 return NAME ;
71143 }
144+
145+ @ Override
146+ public FilteredQueryBuilder doReadFrom (StreamInput in ) throws IOException {
147+ QueryBuilder query = in .readNamedWriteable ();
148+ QueryBuilder filter = in .readNamedWriteable ();
149+ FilteredQueryBuilder qb = new FilteredQueryBuilder (query , filter );
150+ return qb ;
151+ }
152+
153+ @ Override
154+ public void doWriteTo (StreamOutput out ) throws IOException {
155+ out .writeNamedWriteable (queryBuilder );
156+ out .writeNamedWriteable (filterBuilder );
157+ }
72158}
0 commit comments