Skip to content

Commit e502cd4

Browse files
ehsannasgcf-owl-bot[bot]meredithslota
authored
feat: Enable OR Query support. (#1007)
* Remove TODOs and add tests for OR Query support. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Address comments and backport a new test. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Target backend for integration tests. * Fix: uninitialized 'firestore' variable. * Add the docs. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Add test dependency. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Remove tests that require composite index and unsupported cases. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Remove the 'hide' annotation. * Rearrange/add tests. * remove duplicate test which is run only against emulator. --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: meredithslota <[email protected]>
1 parent 8b6ecd9 commit e502cd4

File tree

7 files changed

+624
-12
lines changed

7 files changed

+624
-12
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-firestore'
5656
If you are using Gradle without BOM, add this to your dependencies:
5757

5858
```Groovy
59-
implementation 'com.google.cloud:google-cloud-firestore:3.8.1'
59+
implementation 'com.google.cloud:google-cloud-firestore:3.8.2'
6060
```
6161

6262
If you are using SBT, add this to your dependencies:
6363

6464
```Scala
65-
libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.8.1"
65+
libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.8.2"
6666
```
6767

6868
## Authentication

google-cloud-firestore/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@
177177
<version>3.12.0</version>
178178
<scope>test</scope>
179179
</dependency>
180+
<dependency>
181+
<groupId>com.google.http-client</groupId>
182+
<artifactId>google-http-client</artifactId>
183+
<scope>test</scope>
184+
</dependency>
180185
</dependencies>
181186

182187
<reporting>

google-cloud-firestore/src/main/java/com/google/cloud/firestore/Filter.java

Lines changed: 159 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import javax.annotation.Nonnull;
2424
import javax.annotation.Nullable;
2525

26-
/** @hide */
2726
public class Filter {
2827
static class UnaryFilter extends Filter {
2928
private final FieldPath field;
@@ -69,113 +68,269 @@ public StructuredQuery.CompositeFilter.Operator getOperator() {
6968
}
7069
}
7170

71+
/**
72+
* Creates a new filter for checking that the given field is equal to the given value.
73+
*
74+
* @param field The field used for the filter.
75+
* @param value The value used for the filter.
76+
* @return The newly created filter.
77+
*/
7278
@Nonnull
7379
public static Filter equalTo(@Nonnull String field, @Nullable Object value) {
7480
return equalTo(FieldPath.fromDotSeparatedString(field), value);
7581
}
7682

83+
/**
84+
* Creates a new filter for checking that the given field is equal to the given value.
85+
*
86+
* @param fieldPath The field path used for the filter.
87+
* @param value The value used for the filter.
88+
* @return The newly created filter.
89+
*/
7790
@Nonnull
7891
public static Filter equalTo(@Nonnull FieldPath fieldPath, @Nullable Object value) {
7992
return new UnaryFilter(fieldPath, Operator.EQUAL, value);
8093
}
8194

95+
/**
96+
* Creates a new filter for checking that the given field is not equal to the given value.
97+
*
98+
* @param field The field used for the filter.
99+
* @param value The value used for the filter.
100+
* @return The newly created filter.
101+
*/
82102
@Nonnull
83103
public static Filter notEqualTo(@Nonnull String field, @Nullable Object value) {
84104
return notEqualTo(FieldPath.fromDotSeparatedString(field), value);
85105
}
86106

107+
/**
108+
* Creates a new filter for checking that the given field is not equal to the given value.
109+
*
110+
* @param fieldPath The field path used for the filter.
111+
* @param value The value used for the filter.
112+
* @return The newly created filter.
113+
*/
87114
@Nonnull
88115
public static Filter notEqualTo(@Nonnull FieldPath fieldPath, @Nullable Object value) {
89116
return new UnaryFilter(fieldPath, Operator.NOT_EQUAL, value);
90117
}
91118

119+
/**
120+
* Creates a new filter for checking that the given field is greater than the given value.
121+
*
122+
* @param field The field used for the filter.
123+
* @param value The value used for the filter.
124+
* @return The newly created filter.
125+
*/
92126
@Nonnull
93127
public static Filter greaterThan(@Nonnull String field, @Nullable Object value) {
94128
return greaterThan(FieldPath.fromDotSeparatedString(field), value);
95129
}
96130

131+
/**
132+
* Creates a new filter for checking that the given field is greater than the given value.
133+
*
134+
* @param fieldPath The field path used for the filter.
135+
* @param value The value used for the filter.
136+
* @return The newly created filter.
137+
*/
97138
@Nonnull
98139
public static Filter greaterThan(@Nonnull FieldPath fieldPath, @Nullable Object value) {
99140
return new UnaryFilter(fieldPath, Operator.GREATER_THAN, value);
100141
}
101142

143+
/**
144+
* Creates a new filter for checking that the given field is greater than or equal to the given
145+
* value.
146+
*
147+
* @param field The field used for the filter.
148+
* @param value The value used for the filter.
149+
* @return The newly created filter.
150+
*/
102151
@Nonnull
103152
public static Filter greaterThanOrEqualTo(@Nonnull String field, @Nullable Object value) {
104153
return greaterThanOrEqualTo(FieldPath.fromDotSeparatedString(field), value);
105154
}
106155

156+
/**
157+
* Creates a new filter for checking that the given field is greater than or equal to the given
158+
* value.
159+
*
160+
* @param fieldPath The field path used for the filter.
161+
* @param value The value used for the filter.
162+
* @return The newly created filter.
163+
*/
107164
@Nonnull
108165
public static Filter greaterThanOrEqualTo(@Nonnull FieldPath fieldPath, @Nullable Object value) {
109166
return new UnaryFilter(fieldPath, Operator.GREATER_THAN_OR_EQUAL, value);
110167
}
111168

169+
/**
170+
* Creates a new filter for checking that the given field is less than the given value.
171+
*
172+
* @param field The field used for the filter.
173+
* @param value The value used for the filter.
174+
* @return The newly created filter.
175+
*/
112176
@Nonnull
113177
public static Filter lessThan(@Nonnull String field, @Nullable Object value) {
114178
return lessThan(FieldPath.fromDotSeparatedString(field), value);
115179
}
116180

181+
/**
182+
* Creates a new filter for checking that the given field is less than the given value.
183+
*
184+
* @param fieldPath The field path used for the filter.
185+
* @param value The value used for the filter.
186+
* @return The newly created filter.
187+
*/
117188
@Nonnull
118189
public static Filter lessThan(@Nonnull FieldPath fieldPath, @Nullable Object value) {
119190
return new UnaryFilter(fieldPath, Operator.LESS_THAN, value);
120191
}
121192

193+
/**
194+
* Creates a new filter for checking that the given field is less than or equal to the given
195+
* value.
196+
*
197+
* @param field The field used for the filter.
198+
* @param value The value used for the filter.
199+
* @return The newly created filter.
200+
*/
122201
@Nonnull
123202
public static Filter lessThanOrEqualTo(@Nonnull String field, @Nullable Object value) {
124203
return lessThanOrEqualTo(FieldPath.fromDotSeparatedString(field), value);
125204
}
126205

206+
/**
207+
* Creates a new filter for checking that the given field is less than or equal to the given
208+
* value.
209+
*
210+
* @param fieldPath The field path used for the filter.
211+
* @param value The value used for the filter.
212+
* @return The newly created filter.
213+
*/
127214
@Nonnull
128215
public static Filter lessThanOrEqualTo(@Nonnull FieldPath fieldPath, @Nullable Object value) {
129216
return new UnaryFilter(fieldPath, Operator.LESS_THAN_OR_EQUAL, value);
130217
}
131218

219+
/**
220+
* Creates a new filter for checking that the given array field contains the given value.
221+
*
222+
* @param field The field used for the filter.
223+
* @param value The value used for the filter.
224+
* @return The newly created filter.
225+
*/
132226
@Nonnull
133227
public static Filter arrayContains(@Nonnull String field, @Nullable Object value) {
134228
return arrayContains(FieldPath.fromDotSeparatedString(field), value);
135229
}
136230

231+
/**
232+
* Creates a new filter for checking that the given array field contains the given value.
233+
*
234+
* @param fieldPath The field path used for the filter.
235+
* @param value The value used for the filter.
236+
* @return The newly created filter.
237+
*/
137238
@Nonnull
138239
public static Filter arrayContains(@Nonnull FieldPath fieldPath, @Nullable Object value) {
139240
return new UnaryFilter(fieldPath, Operator.ARRAY_CONTAINS, value);
140241
}
141242

243+
/**
244+
* Creates a new filter for checking that the given array field contains any of the given values.
245+
*
246+
* @param field The field used for the filter.
247+
* @param value The list of values used for the filter.
248+
* @return The newly created filter.
249+
*/
142250
@Nonnull
143251
public static Filter arrayContainsAny(@Nonnull String field, @Nullable Object value) {
144252
return arrayContainsAny(FieldPath.fromDotSeparatedString(field), value);
145253
}
146254

255+
/**
256+
* Creates a new filter for checking that the given array field contains any of the given values.
257+
*
258+
* @param fieldPath The field path used for the filter.
259+
* @param value The list of values used for the filter.
260+
* @return The newly created filter.
261+
*/
147262
@Nonnull
148263
public static Filter arrayContainsAny(@Nonnull FieldPath fieldPath, @Nullable Object value) {
149264
return new UnaryFilter(fieldPath, Operator.ARRAY_CONTAINS_ANY, value);
150265
}
151266

267+
/**
268+
* Creates a new filter for checking that the given field equals any of the given values.
269+
*
270+
* @param field The field used for the filter.
271+
* @param value The list of values used for the filter.
272+
* @return The newly created filter.
273+
*/
152274
@Nonnull
153275
public static Filter inArray(@Nonnull String field, @Nullable Object value) {
154276
return inArray(FieldPath.fromDotSeparatedString(field), value);
155277
}
156278

279+
/**
280+
* Creates a new filter for checking that the given field equals any of the given values.
281+
*
282+
* @param fieldPath The field path used for the filter.
283+
* @param value The list of values used for the filter.
284+
* @return The newly created filter.
285+
*/
157286
@Nonnull
158287
public static Filter inArray(@Nonnull FieldPath fieldPath, @Nullable Object value) {
159288
return new UnaryFilter(fieldPath, Operator.IN, value);
160289
}
161290

291+
/**
292+
* Creates a new filter for checking that the given field does not equal any of the given values.
293+
*
294+
* @param field The field path used for the filter.
295+
* @param value The list of values used for the filter.
296+
* @return The newly created filter.
297+
*/
162298
@Nonnull
163299
public static Filter notInArray(@Nonnull String field, @Nullable Object value) {
164300
return notInArray(FieldPath.fromDotSeparatedString(field), value);
165301
}
166302

303+
/**
304+
* Creates a new filter for checking that the given field does not equal any of the given values.
305+
*
306+
* @param fieldPath The field path used for the filter.
307+
* @param value The list of values used for the filter.
308+
* @return The newly created filter.
309+
*/
167310
@Nonnull
168311
public static Filter notInArray(@Nonnull FieldPath fieldPath, @Nullable Object value) {
169312
return new UnaryFilter(fieldPath, Operator.NOT_IN, value);
170313
}
171314

315+
/**
316+
* Creates a new filter that is a disjunction of the given filters. A disjunction filter includes
317+
* a document if it satisfies <em>any</em> of the given filters.
318+
*
319+
* @param filters The list of filters to perform a disjunction for.
320+
* @return The newly created filter.
321+
*/
172322
@Nonnull
173323
public static Filter or(Filter... filters) {
174-
// TODO(orquery): Change this to Operator.OR once it is available.
175-
return new CompositeFilter(
176-
Arrays.asList(filters), StructuredQuery.CompositeFilter.Operator.OPERATOR_UNSPECIFIED);
324+
return new CompositeFilter(Arrays.asList(filters), StructuredQuery.CompositeFilter.Operator.OR);
177325
}
178326

327+
/**
328+
* Creates a new filter that is a conjunction of the given filters. A conjunction filter includes
329+
* a document if it satisfies <em>all</em> of the given filters.
330+
*
331+
* @param filters The list of filters to perform a conjunction for.
332+
* @return The newly created filter.
333+
*/
179334
@Nonnull
180335
public static Filter and(Filter... filters) {
181336
return new CompositeFilter(

google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,13 @@ public Query whereNotIn(@Nonnull FieldPath fieldPath, @Nonnull List<? extends Ob
888888
return where(new com.google.cloud.firestore.Filter.UnaryFilter(fieldPath, NOT_IN, values));
889889
}
890890

891-
// TODO(orquery): This method will become public API. Change visibility and add documentation.
892-
Query where(com.google.cloud.firestore.Filter filter) {
891+
/**
892+
* Creates and returns a new Query with the additional filter.
893+
*
894+
* @param filter The new filter to apply to the existing query.
895+
* @return The newly created Query.
896+
*/
897+
public Query where(com.google.cloud.firestore.Filter filter) {
893898
Preconditions.checkState(
894899
options.getStartCursor() == null && options.getEndCursor() == null,
895900
"Cannot call a where() clause after defining a boundary with startAt(), "

google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,7 @@ public static StructuredQuery.Filter andFilters(StructuredQuery.Filter... filter
651651
}
652652

653653
public static StructuredQuery.Filter orFilters(StructuredQuery.Filter... filters) {
654-
// TODO(orquery): Replace this with Operator.OR once it's available.
655-
return compositeFilter(CompositeFilter.Operator.OPERATOR_UNSPECIFIED, Arrays.asList(filters));
654+
return compositeFilter(CompositeFilter.Operator.OR, Arrays.asList(filters));
656655
}
657656

658657
private static StructuredQuery.Filter compositeFilter(

google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,12 +1331,12 @@ public void serializationTestWithSingleFilterCompositeFilters() {
13311331
}
13321332

13331333
@Test
1334-
public void serializationTestWithNestedCompositeFilters() {
1334+
public void serializationTestWithNestedCompositeFiltersOuterAnd() {
13351335
assertSerialization(query);
13361336
// a IN [1,2]
13371337
query.where(inArray("a", Arrays.asList(1, 2)));
13381338
assertSerialization(query);
1339-
// a IN [1,2] && (b==20 || c==30 || (d==40 && e>50)) || f==60
1339+
// a IN [1,2] && (b==20 || c==30 || (d==40 && e>50) || f==60)
13401340
query.where(
13411341
or(
13421342
equalTo("b", 20),
@@ -1361,6 +1361,36 @@ public void serializationTestWithNestedCompositeFilters() {
13611361
assertSerialization(query);
13621362
}
13631363

1364+
@Test
1365+
public void serializationTestWithNestedCompositeFiltersOuterOr() {
1366+
assertSerialization(query);
1367+
// a IN [1,2] || (b==20 && c==30 && (d==40 || e>50) && f==60)
1368+
query.where(
1369+
or(
1370+
inArray("a", Arrays.asList(1, 2)),
1371+
and(
1372+
equalTo("b", 20),
1373+
equalTo("c", 30),
1374+
or(equalTo("d", 40), greaterThan("e", 50)),
1375+
and(equalTo("f", 60)),
1376+
or(and()))));
1377+
assertSerialization(query);
1378+
query = query.orderBy("l");
1379+
assertSerialization(query);
1380+
query = query.startAt("o");
1381+
assertSerialization(query);
1382+
query = query.startAfter("p");
1383+
assertSerialization(query);
1384+
query = query.endBefore("q");
1385+
assertSerialization(query);
1386+
query = query.endAt("r");
1387+
assertSerialization(query);
1388+
query = query.limit(8);
1389+
assertSerialization(query);
1390+
query = query.offset(9);
1391+
assertSerialization(query);
1392+
}
1393+
13641394
private void assertSerialization(Query query) {
13651395
RunQueryRequest runQueryRequest = query.toProto();
13661396
Query deserializedQuery = Query.fromProto(firestoreMock, runQueryRequest);

0 commit comments

Comments
 (0)