19
19
20
20
package org .elasticsearch .index .query ;
21
21
22
+ import com .google .common .collect .Iterables ;
23
+
24
+ import org .apache .lucene .queries .TermsQuery ;
25
+ import org .apache .lucene .search .Query ;
26
+ import org .apache .lucene .util .BytesRef ;
27
+ import org .elasticsearch .common .io .stream .StreamInput ;
28
+ import org .elasticsearch .common .io .stream .StreamOutput ;
29
+ import org .elasticsearch .common .io .stream .Streamable ;
30
+ import org .elasticsearch .common .lucene .search .Queries ;
22
31
import org .elasticsearch .common .xcontent .XContentBuilder ;
32
+ import org .elasticsearch .index .mapper .Uid ;
33
+ import org .elasticsearch .index .mapper .internal .UidFieldMapper ;
23
34
24
35
import java .io .IOException ;
25
36
import java .util .ArrayList ;
26
37
import java .util .Arrays ;
27
- import java .util .List ;
38
+ import java .util .Collection ;
39
+ import java .util .Objects ;
28
40
29
41
/**
30
42
* A query that will return only documents matching specific ids (and a type).
31
43
*/
32
- public class IdsQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder <IdsQueryBuilder > {
44
+ public class IdsQueryBuilder extends BaseQueryBuilder implements Streamable , BoostableQueryBuilder <IdsQueryBuilder > {
33
45
34
- private final List <String > types ;
46
+ private Collection <String > types = new ArrayList <>() ;
35
47
36
- private List <String > values = new ArrayList <>();
48
+ private Collection <String > ids = new ArrayList <>();
37
49
38
- private float boost = - 1 ;
50
+ private float boost = 1.0f ;
39
51
40
52
private String queryName ;
41
53
42
54
public IdsQueryBuilder (String ... types ) {
43
- this .types = types == null ? null : Arrays .asList (types );
55
+ this .types = ( types == null || types . length == 0 ) ? new ArrayList < String >() : Arrays .asList (types );
44
56
}
45
57
46
58
/**
47
- * Adds ids to the filter.
59
+ * Get the types used in this query
60
+ * @return the types
61
+ */
62
+ public Collection <String > types () {
63
+ return this .types ;
64
+ }
65
+
66
+ /**
67
+ * Adds ids to the query.
48
68
*/
49
69
public IdsQueryBuilder addIds (String ... ids ) {
50
- values .addAll (Arrays .asList (ids ));
70
+ this . ids .addAll (Arrays .asList (ids ));
51
71
return this ;
52
72
}
53
73
54
74
/**
55
- * Adds ids to the filter .
75
+ * Adds ids to the query .
56
76
*/
57
77
public IdsQueryBuilder ids (String ... ids ) {
58
78
return addIds (ids );
59
79
}
60
80
81
+ /**
82
+ * Gets the ids for the query.
83
+ */
84
+ public Collection <String > ids () {
85
+ return this .ids ;
86
+ }
87
+
61
88
/**
62
89
* Sets the boost for this query. Documents matching this query will (in addition to the normal
63
90
* weightings) have their score multiplied by the boost provided.
@@ -69,29 +96,43 @@ public IdsQueryBuilder boost(float boost) {
69
96
}
70
97
71
98
/**
72
- * Sets the query name for the filter that can be used when searching for matched_filters per hit.
99
+ * Gets the boost for this query.
100
+ */
101
+ public float boost () {
102
+ return this .boost ;
103
+ }
104
+
105
+ /**
106
+ * Sets the query name for the query that can be used when searching for matched_filters per hit.
73
107
*/
74
108
public IdsQueryBuilder queryName (String queryName ) {
75
109
this .queryName = queryName ;
76
110
return this ;
77
111
}
78
112
113
+ /**
114
+ * Gets the query name for the query.
115
+ */
116
+ public String queryName () {
117
+ return this .queryName ;
118
+ }
119
+
79
120
@ Override
80
121
protected void doXContent (XContentBuilder builder , Params params ) throws IOException {
81
122
builder .startObject (IdsQueryParser .NAME );
82
123
if (types != null ) {
83
124
if (types .size () == 1 ) {
84
- builder .field ("type" , types .get ( 0 ));
125
+ builder .field ("type" , types .iterator (). next ( ));
85
126
} else {
86
127
builder .startArray ("types" );
87
- for (Object type : types ) {
128
+ for (String type : types ) {
88
129
builder .value (type );
89
130
}
90
131
builder .endArray ();
91
132
}
92
133
}
93
134
builder .startArray ("values" );
94
- for (Object value : values ) {
135
+ for (String value : ids ) {
95
136
builder .value (value );
96
137
}
97
138
builder .endArray ();
@@ -108,4 +149,84 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
108
149
protected String parserName () {
109
150
return IdsQueryParser .NAME ;
110
151
}
152
+
153
+ public Query toQuery (QueryParseContext parseContext ) throws IOException , QueryParsingException {
154
+ ArrayList <BytesRef > ids = new ArrayList <>();
155
+
156
+ for (String value : this .ids ) {
157
+ BytesRef ref = new BytesRef (value );
158
+ ids .add (ref );
159
+ }
160
+
161
+ if (ids .isEmpty ()) {
162
+ return Queries .newMatchNoDocsQuery ();
163
+ }
164
+
165
+ if (types == null || types .isEmpty ()) {
166
+ types = parseContext .queryTypes ();
167
+ } else if (types .size () == 1 && Iterables .getFirst (types , null ).equals ("_all" )) {
168
+ types = parseContext .mapperService ().types ();
169
+ }
170
+
171
+ TermsQuery query = new TermsQuery (UidFieldMapper .NAME , Uid .createTypeUids (types , ids ));
172
+ query .setBoost (boost );
173
+ if (queryName != null ) {
174
+ parseContext .addNamedQuery (queryName , query );
175
+ }
176
+ return query ;
177
+ }
178
+
179
+ @ Override
180
+ public QueryValidationException validate () {
181
+ // all fields can be empty or null
182
+ return null ;
183
+ }
184
+
185
+ @ Override
186
+ public void readFrom (StreamInput in ) throws IOException {
187
+ int typeSize = in .readInt ();
188
+ for (int i = 0 ; i < typeSize ; i ++) {
189
+ types .add (in .readString ());
190
+ }
191
+ int valueSize = in .readInt ();
192
+ for (int i = 0 ; i < valueSize ; i ++) {
193
+ ids .add (in .readString ());
194
+ }
195
+ queryName = in .readOptionalString ();
196
+ boost = in .readFloat ();
197
+ }
198
+
199
+ @ Override
200
+ public void writeTo (StreamOutput out ) throws IOException {
201
+ out .writeInt (types .size ());
202
+ for (String type : types ) {
203
+ out .writeString (type );
204
+ }
205
+ out .writeInt (ids .size ());
206
+ for (String value : ids ) {
207
+ out .writeString (value );
208
+ }
209
+ out .writeOptionalString (queryName );
210
+ out .writeFloat (boost );
211
+ }
212
+
213
+ @ Override
214
+ public int hashCode () {
215
+ return Objects .hash (ids , types , boost , queryName );
216
+ }
217
+
218
+ @ Override
219
+ public boolean equals (Object obj ) {
220
+ if (this == obj ) {
221
+ return true ;
222
+ }
223
+ if (obj == null || getClass () != obj .getClass ()) {
224
+ return false ;
225
+ }
226
+ IdsQueryBuilder other = (IdsQueryBuilder ) obj ;
227
+ return Objects .equals (ids , other .ids ) &&
228
+ Objects .equals (types , other .types ) &&
229
+ Objects .equals (boost , other .boost ) &&
230
+ Objects .equals (queryName , other .queryName );
231
+ }
111
232
}
0 commit comments