-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* WIP: OR Query with unit tests. No OR operator. * Updating documentation and member visibility. * Formatting * Skipping OR Query system test. * Updated copyright holder for new files. * PR fixes. * feat: OR Query support (#1801) * OR operator support and integration tests. * Updating documentation and member visibility. * Remove usage of OPERATOR_UNSPECIFIED standing in for OR. * Removing private and internal tags from OR query public API members. * Ensure that new OR Query features are in firestore.d.ts and are exported from the main entry point. * Update documentation for OR query features to match android PR 4274. * Removing CompositeFilter and UnaryFilter from the type definitions and JS doc. * Corrected the descending order test for OR queries. * fix: update generated proto types; fix the update script (#1825) * Adding OR enum value for composit filter operator. --------- Co-authored-by: Alexander Fenster <fenster@google.com> * Updating header copyright to 2023 * Tests that require an index are configured to only run against the emulator. * Test cleanup based on PR comments. --------- Co-authored-by: Alexander Fenster <fenster@google.com>
- Loading branch information
1 parent
3737696
commit 983a477
Showing
13 changed files
with
1,231 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3212,4 +3212,4 @@ | |
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
/*! | ||
* Copyright 2023 Google LLC. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import * as firestore from '@google-cloud/firestore'; | ||
|
||
/** | ||
* A `Filter` represents a restriction on one or more field values and can | ||
* be used to refine the results of a {@link Query}. | ||
* `Filters`s are created by invoking {@link Filter#where}, {@link Filter#or}, | ||
* or {@link Filter#and} and can then be passed to {@link Query#where} | ||
* to create a new {@link Query} instance that also contains this `Filter`. | ||
*/ | ||
export abstract class Filter { | ||
/** | ||
* Creates and returns a new [Filter]{@link Filter}, which can be | ||
* applied to [Query.where()]{@link Query#where}, [Filter.or()]{@link Filter#or}, | ||
* or [Filter.and()]{@link Filter#and}. When applied to a [Query]{@link Query} | ||
* it requires that documents must contain the specified field and that its value should | ||
* satisfy the relation constraint provided. | ||
* | ||
* @param {string|FieldPath} fieldPath The name of a property value to compare. | ||
* @param {string} opStr A comparison operation in the form of a string. | ||
* Acceptable operator strings are "<", "<=", "==", "!=", ">=", ">", "array-contains", | ||
* "in", "not-in", and "array-contains-any". | ||
* @param {*} value The value to which to compare the field for inclusion in | ||
* a query. | ||
* @returns {Filter} The created Filter. | ||
* | ||
* @example | ||
* ``` | ||
* let collectionRef = firestore.collection('col'); | ||
* | ||
* collectionRef.where(Filter.where('foo', '==', 'bar')).get().then(querySnapshot => { | ||
* querySnapshot.forEach(documentSnapshot => { | ||
* console.log(`Found document at ${documentSnapshot.ref.path}`); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
public static where( | ||
fieldPath: string | firestore.FieldPath, | ||
opStr: firestore.WhereFilterOp, | ||
value: unknown | ||
): Filter { | ||
return new UnaryFilter(fieldPath, opStr, value); | ||
} | ||
|
||
/** | ||
* Creates and returns a new [Filter]{@link Filter} that is a | ||
* disjunction of the given {@link Filter}s. A disjunction filter includes | ||
* a document if it satisfies any of the given {@link Filter}s. | ||
* | ||
* The returned Filter can be applied to [Query.where()]{@link Query#where}, | ||
* [Filter.or()]{@link Filter#or}, or [Filter.and()]{@link Filter#and}. When | ||
* applied to a [Query]{@link Query} it requires that documents must satisfy | ||
* one of the provided {@link Filter}s. | ||
* | ||
* @param {...Filter} filters Optional. The {@link Filter}s | ||
* for OR operation. These must be created with calls to {@link Filter#where}, | ||
* {@link Filter#or}, or {@link Filter#and}. | ||
* @returns {Filter} The created {@link Filter}. | ||
* | ||
* @example | ||
* ``` | ||
* let collectionRef = firestore.collection('col'); | ||
* | ||
* // doc.foo == 'bar' || doc.baz > 0 | ||
* let orFilter = Filter.or(Filter.where('foo', '==', 'bar'), Filter.where('baz', '>', 0)); | ||
* | ||
* collectionRef.where(orFilter).get().then(querySnapshot => { | ||
* querySnapshot.forEach(documentSnapshot => { | ||
* console.log(`Found document at ${documentSnapshot.ref.path}`); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
public static or(...filters: Filter[]): Filter { | ||
return new CompositeFilter(filters, 'OR'); | ||
} | ||
|
||
/** | ||
* Creates and returns a new [Filter]{@link Filter} that is a | ||
* conjunction of the given {@link Filter}s. A conjunction filter includes | ||
* a document if it satisfies any of the given {@link Filter}s. | ||
* | ||
* The returned Filter can be applied to [Query.where()]{@link Query#where}, | ||
* [Filter.or()]{@link Filter#or}, or [Filter.and()]{@link Filter#and}. When | ||
* applied to a [Query]{@link Query} it requires that documents must satisfy | ||
* one of the provided {@link Filter}s. | ||
* | ||
* @param {...Filter} filters Optional. The {@link Filter}s | ||
* for AND operation. These must be created with calls to {@link Filter#where}, | ||
* {@link Filter#or}, or {@link Filter#and}. | ||
* @returns {Filter} The created {@link Filter}. | ||
* | ||
* @example | ||
* ``` | ||
* let collectionRef = firestore.collection('col'); | ||
* | ||
* // doc.foo == 'bar' && doc.baz > 0 | ||
* let andFilter = Filter.and(Filter.where('foo', '==', 'bar'), Filter.where('baz', '>', 0)); | ||
* | ||
* collectionRef.where(andFilter).get().then(querySnapshot => { | ||
* querySnapshot.forEach(documentSnapshot => { | ||
* console.log(`Found document at ${documentSnapshot.ref.path}`); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
public static and(...filters: Filter[]): Filter { | ||
return new CompositeFilter(filters, 'AND'); | ||
} | ||
} | ||
|
||
/** | ||
* A `UnaryFilter` represents a restriction on one field value and can | ||
* be used to refine the results of a {@link Query}. | ||
* `UnaryFilter`s are created by invoking {@link Filter#where} and can then | ||
* be passed to {@link Query#where} to create a new {@link Query} instance | ||
* that also contains this `UnaryFilter`. | ||
* | ||
* @private | ||
* @internal | ||
*/ | ||
export class UnaryFilter extends Filter { | ||
/** | ||
@private | ||
@internal | ||
*/ | ||
public constructor( | ||
private field: string | firestore.FieldPath, | ||
private operator: firestore.WhereFilterOp, | ||
private value: unknown | ||
) { | ||
super(); | ||
} | ||
|
||
/** | ||
@private | ||
@internal | ||
*/ | ||
public _getField(): string | firestore.FieldPath { | ||
return this.field; | ||
} | ||
|
||
/** | ||
@private | ||
@internal | ||
*/ | ||
public _getOperator(): firestore.WhereFilterOp { | ||
return this.operator; | ||
} | ||
|
||
/** | ||
@private | ||
@internal | ||
*/ | ||
public _getValue(): unknown { | ||
return this.value; | ||
} | ||
} | ||
|
||
/** | ||
* A `CompositeFilter` is used to narrow the set of documents returned | ||
* by a Firestore query by performing the logical OR or AND of multiple | ||
* {@link Filters}s. `CompositeFilters`s are created by invoking {@link Filter#or} | ||
* or {@link Filter#and} and can then be passed to {@link Query#where} | ||
* to create a new query instance that also contains the `CompositeFilter`. | ||
* | ||
* @private | ||
* @internal | ||
*/ | ||
export class CompositeFilter extends Filter { | ||
/** | ||
@private | ||
@internal | ||
*/ | ||
public constructor( | ||
private filters: Filter[], | ||
private operator: CompositeOperator | ||
) { | ||
super(); | ||
} | ||
|
||
/** | ||
@private | ||
@internal | ||
*/ | ||
public _getFilters(): Filter[] { | ||
return this.filters; | ||
} | ||
|
||
/** | ||
@private | ||
@internal | ||
*/ | ||
public _getOperator(): CompositeOperator { | ||
return this.operator; | ||
} | ||
} | ||
|
||
/** | ||
* Composition operator of a `CompositeFilter`. This operator specifies the | ||
* behavior of the `CompositeFilter`. | ||
* | ||
* @private | ||
* @internal | ||
*/ | ||
export type CompositeOperator = 'AND' | 'OR'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.