20
20
import androidx .annotation .Nullable ;
21
21
import com .google .firebase .firestore .model .DocumentKey ;
22
22
import com .google .firebase .firestore .model .FieldIndex ;
23
+ import com .google .firebase .firestore .model .FieldPath ;
23
24
import com .google .firebase .firestore .model .ResourcePath ;
24
25
import com .google .firebase .firestore .model .Values ;
25
26
import com .google .firestore .v1 .ArrayValue ;
@@ -115,6 +116,17 @@ public boolean hasLimit() {
115
116
return endAt ;
116
117
}
117
118
119
+ /** Returns the field filters from the given list that target the given field path. */
120
+ private List <FieldFilter > getFieldFiltersForPath (List <Filter > filters , FieldPath path ) {
121
+ List <FieldFilter > result = new ArrayList <>();
122
+ for (Filter filter : filters ) {
123
+ if ((filter instanceof FieldFilter ) && (((FieldFilter ) filter ).getField ()).equals (path )) {
124
+ result .add ((FieldFilter ) filter );
125
+ }
126
+ }
127
+ return result ;
128
+ }
129
+
118
130
/**
119
131
* Returns the values that are used in ARRAY_CONTAINS or ARRAY_CONTAINS_ANY filters. Returns
120
132
* {@code null} if there are no such filters.
@@ -123,16 +135,12 @@ public boolean hasLimit() {
123
135
@ Nullable FieldIndex .Segment segment = fieldIndex .getArraySegment ();
124
136
if (segment == null ) return null ;
125
137
126
- for (Filter filter : filters ) {
127
- if ((filter instanceof FieldFilter )
128
- && (((FieldFilter ) filter ).getField ()).equals (segment .getFieldPath ())) {
129
- FieldFilter fieldFilter = (FieldFilter ) filter ;
130
- switch (fieldFilter .getOperator ()) {
131
- case ARRAY_CONTAINS_ANY :
132
- return fieldFilter .getValue ().getArrayValue ().getValuesList ();
133
- case ARRAY_CONTAINS :
134
- return Collections .singletonList (fieldFilter .getValue ());
135
- }
138
+ for (FieldFilter fieldFilter : getFieldFiltersForPath (filters , segment .getFieldPath ())) {
139
+ switch (fieldFilter .getOperator ()) {
140
+ case ARRAY_CONTAINS_ANY :
141
+ return fieldFilter .getValue ().getArrayValue ().getValuesList ();
142
+ case ARRAY_CONTAINS :
143
+ return Collections .singletonList (fieldFilter .getValue ());
136
144
}
137
145
}
138
146
@@ -147,23 +155,19 @@ public boolean hasLimit() {
147
155
List <Value > values = new ArrayList <>();
148
156
149
157
for (FieldIndex .Segment segment : fieldIndex .getDirectionalSegments ()) {
150
- for (Filter filter : filters ) {
151
- if ((filter instanceof FieldFilter )
152
- && ((FieldFilter ) filter ).getField ().equals (segment .getFieldPath ())) {
153
- FieldFilter fieldFilter = (FieldFilter ) filter ;
154
- switch (fieldFilter .getOperator ()) {
155
- case EQUAL :
156
- case IN :
157
- // Encode equality prefix, which is encoded in the index value before the inequality
158
- // (e.g. `a == 'a' && b != 'b' is encoded to 'value != ab').
159
- values .add (fieldFilter .getValue ());
160
- break ;
161
- case NOT_IN :
162
- case NOT_EQUAL :
163
- // NotIn/NotEqual is always a suffix
164
- values .add (fieldFilter .getValue ());
165
- return values ;
166
- }
158
+ for (FieldFilter fieldFilter : getFieldFiltersForPath (filters , segment .getFieldPath ())) {
159
+ switch (fieldFilter .getOperator ()) {
160
+ case EQUAL :
161
+ case IN :
162
+ // Encode equality prefix, which is encoded in the index value before the inequality
163
+ // (e.g. `a == 'a' && b != 'b' is encoded to 'value != ab').
164
+ values .add (fieldFilter .getValue ());
165
+ break ;
166
+ case NOT_IN :
167
+ case NOT_EQUAL :
168
+ // NotIn/NotEqual is always a suffix
169
+ values .add (fieldFilter .getValue ());
170
+ return values ;
167
171
}
168
172
}
169
173
}
@@ -186,47 +190,43 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
186
190
boolean segmentInclusive = true ;
187
191
188
192
// Process all filters to find a value for the current field segment
189
- for (Filter filter : filters ) {
190
- if ((filter instanceof FieldFilter )
191
- && ((FieldFilter ) filter ).getField ().equals (segment .getFieldPath ())) {
192
- FieldFilter fieldFilter = (FieldFilter ) filter ;
193
- Value filterValue = null ;
194
- boolean filterInclusive = true ;
195
-
196
- switch (fieldFilter .getOperator ()) {
197
- case LESS_THAN :
198
- case LESS_THAN_OR_EQUAL :
199
- filterValue = Values .getLowerBound (fieldFilter .getValue ().getValueTypeCase ());
200
- break ;
201
- case EQUAL :
202
- case IN :
203
- case GREATER_THAN_OR_EQUAL :
204
- filterValue = fieldFilter .getValue ();
205
- break ;
206
- case GREATER_THAN :
207
- filterValue = fieldFilter .getValue ();
208
- filterInclusive = false ;
209
- break ;
210
- case NOT_EQUAL :
211
- filterValue = Values .MIN_VALUE ;
212
- break ;
213
- case NOT_IN :
214
- {
215
- ArrayValue .Builder arrayValue = ArrayValue .newBuilder ();
216
- for (int i = 0 ; i < fieldFilter .getValue ().getArrayValue ().getValuesCount (); ++i ) {
217
- arrayValue .addValues (Values .MIN_VALUE );
218
- }
219
- filterValue = Value .newBuilder ().setArrayValue (arrayValue ).build ();
220
- break ;
193
+ for (FieldFilter fieldFilter : getFieldFiltersForPath (filters , segment .getFieldPath ())) {
194
+ Value filterValue = null ;
195
+ boolean filterInclusive = true ;
196
+
197
+ switch (fieldFilter .getOperator ()) {
198
+ case LESS_THAN :
199
+ case LESS_THAN_OR_EQUAL :
200
+ filterValue = Values .getLowerBound (fieldFilter .getValue ().getValueTypeCase ());
201
+ break ;
202
+ case EQUAL :
203
+ case IN :
204
+ case GREATER_THAN_OR_EQUAL :
205
+ filterValue = fieldFilter .getValue ();
206
+ break ;
207
+ case GREATER_THAN :
208
+ filterValue = fieldFilter .getValue ();
209
+ filterInclusive = false ;
210
+ break ;
211
+ case NOT_EQUAL :
212
+ filterValue = Values .MIN_VALUE ;
213
+ break ;
214
+ case NOT_IN :
215
+ {
216
+ ArrayValue .Builder arrayValue = ArrayValue .newBuilder ();
217
+ for (int i = 0 ; i < fieldFilter .getValue ().getArrayValue ().getValuesCount (); ++i ) {
218
+ arrayValue .addValues (Values .MIN_VALUE );
221
219
}
222
- default :
223
- // Remaining filters cannot be used as lower bounds.
224
- }
220
+ filterValue = Value .newBuilder ().setArrayValue (arrayValue ).build ();
221
+ break ;
222
+ }
223
+ default :
224
+ // Remaining filters cannot be used as lower bounds.
225
+ }
225
226
226
- if (max (segmentValue , filterValue ) == filterValue ) {
227
- segmentValue = filterValue ;
228
- segmentInclusive = filterInclusive ;
229
- }
227
+ if (max (segmentValue , filterValue ) == filterValue ) {
228
+ segmentValue = filterValue ;
229
+ segmentInclusive = filterInclusive ;
230
230
}
231
231
}
232
232
@@ -272,48 +272,44 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
272
272
boolean segmentInclusive = true ;
273
273
274
274
// Process all filters to find a value for the current field segment
275
- for (Filter filter : filters ) {
276
- if ((filter instanceof FieldFilter )
277
- && ((FieldFilter ) filter ).getField ().equals (segment .getFieldPath ())) {
278
- FieldFilter fieldFilter = (FieldFilter ) filter ;
279
- Value filterValue = null ;
280
- boolean filterInclusive = true ;
281
-
282
- switch (fieldFilter .getOperator ()) {
283
- case GREATER_THAN_OR_EQUAL :
284
- case GREATER_THAN :
285
- filterValue = Values .getUpperBound (fieldFilter .getValue ().getValueTypeCase ());
286
- filterInclusive = false ;
287
- break ;
288
- case EQUAL :
289
- case IN :
290
- case LESS_THAN_OR_EQUAL :
291
- filterValue = fieldFilter .getValue ();
292
- break ;
293
- case LESS_THAN :
294
- filterValue = fieldFilter .getValue ();
295
- filterInclusive = false ;
296
- break ;
297
- case NOT_EQUAL :
298
- filterValue = Values .MAX_VALUE ;
299
- break ;
300
- case NOT_IN :
301
- {
302
- ArrayValue .Builder arrayValue = ArrayValue .newBuilder ();
303
- for (int i = 0 ; i < fieldFilter .getValue ().getArrayValue ().getValuesCount (); ++i ) {
304
- arrayValue .addValues (Values .MAX_VALUE );
305
- }
306
- filterValue = Value .newBuilder ().setArrayValue (arrayValue ).build ();
307
- break ;
275
+ for (FieldFilter fieldFilter : getFieldFiltersForPath (filters , segment .getFieldPath ())) {
276
+ Value filterValue = null ;
277
+ boolean filterInclusive = true ;
278
+
279
+ switch (fieldFilter .getOperator ()) {
280
+ case GREATER_THAN_OR_EQUAL :
281
+ case GREATER_THAN :
282
+ filterValue = Values .getUpperBound (fieldFilter .getValue ().getValueTypeCase ());
283
+ filterInclusive = false ;
284
+ break ;
285
+ case EQUAL :
286
+ case IN :
287
+ case LESS_THAN_OR_EQUAL :
288
+ filterValue = fieldFilter .getValue ();
289
+ break ;
290
+ case LESS_THAN :
291
+ filterValue = fieldFilter .getValue ();
292
+ filterInclusive = false ;
293
+ break ;
294
+ case NOT_EQUAL :
295
+ filterValue = Values .MAX_VALUE ;
296
+ break ;
297
+ case NOT_IN :
298
+ {
299
+ ArrayValue .Builder arrayValue = ArrayValue .newBuilder ();
300
+ for (int i = 0 ; i < fieldFilter .getValue ().getArrayValue ().getValuesCount (); ++i ) {
301
+ arrayValue .addValues (Values .MAX_VALUE );
308
302
}
309
- default :
310
- // Remaining filters cannot be used as upper bounds.
311
- }
303
+ filterValue = Value .newBuilder ().setArrayValue (arrayValue ).build ();
304
+ break ;
305
+ }
306
+ default :
307
+ // Remaining filters cannot be used as upper bounds.
308
+ }
312
309
313
- if (min (segmentValue , filterValue ) == filterValue ) {
314
- segmentValue = filterValue ;
315
- segmentInclusive = filterInclusive ;
316
- }
310
+ if (min (segmentValue , filterValue ) == filterValue ) {
311
+ segmentValue = filterValue ;
312
+ segmentInclusive = filterInclusive ;
317
313
}
318
314
}
319
315
0 commit comments