Skip to content

Commit 44ad4cc

Browse files
authored
feat(firestore): Add logical expressions (#9702)
1 parent f4e0086 commit 44ad4cc

10 files changed

Lines changed: 521 additions & 1 deletion

File tree

.changeset/orange-worms-juggle.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'firebase': minor
3+
'@firebase/firestore': minor
4+
---
5+
6+
Add support for logical expressions `nor` and `switchOn`.

common/api-review/firestore-lite-pipelines.api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,9 @@ export function multiply(first: Expression, second: Expression | unknown): Funct
11031103
// @beta
11041104
export function multiply(fieldName: string, second: Expression | unknown): FunctionExpression;
11051105

1106+
// @beta
1107+
export function nor(first: BooleanExpression, second: BooleanExpression, ...more: BooleanExpression[]): BooleanExpression;
1108+
11061109
// @beta
11071110
export function not(booleanExpr: BooleanExpression): BooleanExpression;
11081111

@@ -1472,6 +1475,9 @@ export function sum(expression: Expression): AggregateFunction;
14721475
// @beta
14731476
export function sum(fieldName: string): AggregateFunction;
14741477

1478+
// @beta
1479+
export function switchOn(condition: BooleanExpression, result: Expression, ...others: Array<BooleanExpression | Expression>): FunctionExpression;
1480+
14751481
// @beta
14761482
export type TimeGranularity = 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'week(monday)' | 'week(tuesday)' | 'week(wednesday)' | 'week(thursday)' | 'week(friday)' | 'week(saturday)' | 'week(sunday)' | 'isoWeek' | 'month' | 'quarter' | 'year' | 'isoYear';
14771483

common/api-review/firestore-pipelines.api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,9 @@ export function multiply(first: Expression, second: Expression | unknown): Funct
11061106
// @beta
11071107
export function multiply(fieldName: string, second: Expression | unknown): FunctionExpression;
11081108

1109+
// @beta
1110+
export function nor(first: BooleanExpression, second: BooleanExpression, ...more: BooleanExpression[]): BooleanExpression;
1111+
11091112
// @beta
11101113
export function not(booleanExpr: BooleanExpression): BooleanExpression;
11111114

@@ -1514,6 +1517,9 @@ export function sum(expression: Expression): AggregateFunction;
15141517
// @beta
15151518
export function sum(fieldName: string): AggregateFunction;
15161519

1520+
// @beta
1521+
export function switchOn(condition: BooleanExpression, result: Expression, ...others: Array<BooleanExpression | Expression>): FunctionExpression;
1522+
15171523
// @beta
15181524
export type TimeGranularity = 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'week(monday)' | 'week(tuesday)' | 'week(wednesday)' | 'week(thursday)' | 'week(friday)' | 'week(saturday)' | 'week(sunday)' | 'isoWeek' | 'month' | 'quarter' | 'year' | 'isoYear';
15191525

docs-devsite/firestore_lite_pipelines.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ https://github.com/firebase/firebase-js-sdk
6363
| [not(booleanExpr)](./firestore_lite_pipelines.md#not_c5b8fb1) | <b><i>(Public Preview)</i></b> Creates an expression that negates a filter condition. |
6464
| <b>function(condition, ...)</b> |
6565
| [conditional(condition, thenExpr, elseExpr)](./firestore_lite_pipelines.md#conditional_07a206d) | <b><i>(Public Preview)</i></b> Creates a conditional expression that evaluates to a 'then' expression if a condition is true and an 'else' expression if the condition is false. |
66+
| [switchOn(condition, result, others)](./firestore_lite_pipelines.md#switchon_02b8caf) | <b><i>(Public Preview)</i></b> Creates an expression that evaluates to the result corresponding to the first true condition. |
6667
| <b>function(documentPath, ...)</b> |
6768
| [documentId(documentPath)](./firestore_lite_pipelines.md#documentid_cef293c) | <b><i>(Public Preview)</i></b> Creates an expression that returns the document ID from a path. |
6869
| <b>function(documentPathExpr, ...)</b> |
@@ -272,6 +273,7 @@ https://github.com/firebase/firebase-js-sdk
272273
| [logicalMaximum(first, second, others)](./firestore_lite_pipelines.md#logicalmaximum_83be015) | <b><i>(Public Preview)</i></b> Creates an expression that returns the largest value between multiple input expressions or literal values. Based on Firestore's value type ordering. |
273274
| [logicalMinimum(first, second, others)](./firestore_lite_pipelines.md#logicalminimum_83be015) | <b><i>(Public Preview)</i></b> Creates an expression that returns the smallest value between multiple input expressions and literal values. Based on Firestore's value type ordering. |
274275
| [multiply(first, second)](./firestore_lite_pipelines.md#multiply_846ca1b) | <b><i>(Public Preview)</i></b> Creates an expression that multiplies two expressions together. |
276+
| [nor(first, second, more)](./firestore_lite_pipelines.md#nor_e0c48bd) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'NOR' operation on multiple filter conditions. |
275277
| [or(first, second, more)](./firestore_lite_pipelines.md#or_e0c48bd) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'OR' operation on multiple filter conditions. |
276278
| [xor(first, second, additionalConditions)](./firestore_lite_pipelines.md#xor_8197113) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'XOR' (exclusive OR) operation on multiple BooleanExpressions. |
277279
| <b>function(firstArray, ...)</b> |
@@ -1848,6 +1850,49 @@ conditional(
18481850

18491851
```
18501852

1853+
### switchOn(condition, result, others) {:#switchon_02b8caf}
1854+
1855+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
1856+
>
1857+
1858+
Creates an expression that evaluates to the result corresponding to the first true condition.
1859+
1860+
This function behaves like a `switch` statement. It accepts an alternating sequence of conditions and their corresponding results. If an odd number of arguments is provided, the final argument serves as a default fallback result. If no default is provided and no condition evaluates to true, it throws an error.
1861+
1862+
<b>Signature:</b>
1863+
1864+
```typescript
1865+
export declare function switchOn(condition: BooleanExpression, result: Expression, ...others: Array<BooleanExpression | Expression>): FunctionExpression;
1866+
```
1867+
1868+
#### Parameters
1869+
1870+
| Parameter | Type | Description |
1871+
| --- | --- | --- |
1872+
| condition | [BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class) | The first condition to check. |
1873+
| result | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The result if the first condition is true. |
1874+
| others | Array&lt;[BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class) \| [Expression](./firestore_lite_pipelines.expression.md#expression_class)<!-- -->&gt; | Additional conditions and results, and optionally a default value. |
1875+
1876+
<b>Returns:</b>
1877+
1878+
[FunctionExpression](./firestore_lite_pipelines.functionexpression.md#functionexpression_class)
1879+
1880+
A new Expression representing the switch operation.
1881+
1882+
### Example
1883+
1884+
1885+
```typescript
1886+
// Return "Active" if field "status" is 1, "Pending" if field "status" is 2,
1887+
// and default to "Unknown" if none of the conditions are true.
1888+
switchOn(
1889+
equal(field("status"), 1), constant("Active"),
1890+
equal(field("status"), 2), constant("Pending"),
1891+
constant("Unknown")
1892+
)
1893+
1894+
```
1895+
18511896
## function(documentPath, ...)
18521897

18531898
### documentId(documentPath) {:#documentid_cef293c}
@@ -8799,6 +8844,45 @@ multiply(field("quantity"), field("price"));
87998844

88008845
```
88018846

8847+
### nor(first, second, more) {:#nor_e0c48bd}
8848+
8849+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
8850+
>
8851+
8852+
Creates an expression that performs a logical 'NOR' operation on multiple filter conditions.
8853+
8854+
<b>Signature:</b>
8855+
8856+
```typescript
8857+
export declare function nor(first: BooleanExpression, second: BooleanExpression, ...more: BooleanExpression[]): BooleanExpression;
8858+
```
8859+
8860+
#### Parameters
8861+
8862+
| Parameter | Type | Description |
8863+
| --- | --- | --- |
8864+
| first | [BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class) | The first filter condition. |
8865+
| second | [BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class) | The second filter condition. |
8866+
| more | [BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class)<!-- -->\[\] | Additional filter conditions to 'NOR' together. |
8867+
8868+
<b>Returns:</b>
8869+
8870+
[BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class)
8871+
8872+
A new [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) representing the logical 'NOR' operation.
8873+
8874+
### Example
8875+
8876+
8877+
```typescript
8878+
// Check if neither the 'age' field is greater than 18 nor the 'city' field is "London"
8879+
const condition = nor(
8880+
greaterThan("age", 18),
8881+
equal("city", "London")
8882+
);
8883+
8884+
```
8885+
88028886
### or(first, second, more) {:#or_e0c48bd}
88038887

88048888
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.

docs-devsite/firestore_pipelines.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ https://github.com/firebase/firebase-js-sdk
6363
| [not(booleanExpr)](./firestore_pipelines.md#not_c5b8fb1) | <b><i>(Public Preview)</i></b> Creates an expression that negates a filter condition. |
6464
| <b>function(condition, ...)</b> |
6565
| [conditional(condition, thenExpr, elseExpr)](./firestore_pipelines.md#conditional_07a206d) | <b><i>(Public Preview)</i></b> Creates a conditional expression that evaluates to a 'then' expression if a condition is true and an 'else' expression if the condition is false. |
66+
| [switchOn(condition, result, others)](./firestore_pipelines.md#switchon_02b8caf) | <b><i>(Public Preview)</i></b> Creates an expression that evaluates to the result corresponding to the first true condition. |
6667
| <b>function(documentPath, ...)</b> |
6768
| [documentId(documentPath)](./firestore_pipelines.md#documentid_cef293c) | <b><i>(Public Preview)</i></b> Creates an expression that returns the document ID from a path. |
6869
| <b>function(documentPathExpr, ...)</b> |
@@ -272,6 +273,7 @@ https://github.com/firebase/firebase-js-sdk
272273
| [logicalMaximum(first, second, others)](./firestore_pipelines.md#logicalmaximum_83be015) | <b><i>(Public Preview)</i></b> Creates an expression that returns the largest value between multiple input expressions or literal values. Based on Firestore's value type ordering. |
273274
| [logicalMinimum(first, second, others)](./firestore_pipelines.md#logicalminimum_83be015) | <b><i>(Public Preview)</i></b> Creates an expression that returns the smallest value between multiple input expressions and literal values. Based on Firestore's value type ordering. |
274275
| [multiply(first, second)](./firestore_pipelines.md#multiply_846ca1b) | <b><i>(Public Preview)</i></b> Creates an expression that multiplies two expressions together. |
276+
| [nor(first, second, more)](./firestore_pipelines.md#nor_e0c48bd) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'NOR' operation on multiple filter conditions. |
275277
| [or(first, second, more)](./firestore_pipelines.md#or_e0c48bd) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'OR' operation on multiple filter conditions. |
276278
| [xor(first, second, additionalConditions)](./firestore_pipelines.md#xor_8197113) | <b><i>(Public Preview)</i></b> Creates an expression that performs a logical 'XOR' (exclusive OR) operation on multiple BooleanExpressions. |
277279
| <b>function(firstArray, ...)</b> |
@@ -1854,6 +1856,49 @@ conditional(
18541856

18551857
```
18561858

1859+
### switchOn(condition, result, others) {:#switchon_02b8caf}
1860+
1861+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
1862+
>
1863+
1864+
Creates an expression that evaluates to the result corresponding to the first true condition.
1865+
1866+
This function behaves like a `switch` statement. It accepts an alternating sequence of conditions and their corresponding results. If an odd number of arguments is provided, the final argument serves as a default fallback result. If no default is provided and no condition evaluates to true, it throws an error.
1867+
1868+
<b>Signature:</b>
1869+
1870+
```typescript
1871+
export declare function switchOn(condition: BooleanExpression, result: Expression, ...others: Array<BooleanExpression | Expression>): FunctionExpression;
1872+
```
1873+
1874+
#### Parameters
1875+
1876+
| Parameter | Type | Description |
1877+
| --- | --- | --- |
1878+
| condition | [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) | The first condition to check. |
1879+
| result | [Expression](./firestore_pipelines.expression.md#expression_class) | The result if the first condition is true. |
1880+
| others | Array&lt;[BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) \| [Expression](./firestore_pipelines.expression.md#expression_class)<!-- -->&gt; | Additional conditions and results, and optionally a default value. |
1881+
1882+
<b>Returns:</b>
1883+
1884+
[FunctionExpression](./firestore_pipelines.functionexpression.md#functionexpression_class)
1885+
1886+
A new Expression representing the switch operation.
1887+
1888+
### Example
1889+
1890+
1891+
```typescript
1892+
// Return "Active" if field "status" is 1, "Pending" if field "status" is 2,
1893+
// and default to "Unknown" if none of the conditions are true.
1894+
switchOn(
1895+
equal(field("status"), 1), constant("Active"),
1896+
equal(field("status"), 2), constant("Pending"),
1897+
constant("Unknown")
1898+
)
1899+
1900+
```
1901+
18571902
## function(documentPath, ...)
18581903

18591904
### documentId(documentPath) {:#documentid_cef293c}
@@ -8805,6 +8850,45 @@ multiply(field("quantity"), field("price"));
88058850

88068851
```
88078852

8853+
### nor(first, second, more) {:#nor_e0c48bd}
8854+
8855+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
8856+
>
8857+
8858+
Creates an expression that performs a logical 'NOR' operation on multiple filter conditions.
8859+
8860+
<b>Signature:</b>
8861+
8862+
```typescript
8863+
export declare function nor(first: BooleanExpression, second: BooleanExpression, ...more: BooleanExpression[]): BooleanExpression;
8864+
```
8865+
8866+
#### Parameters
8867+
8868+
| Parameter | Type | Description |
8869+
| --- | --- | --- |
8870+
| first | [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) | The first filter condition. |
8871+
| second | [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) | The second filter condition. |
8872+
| more | [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class)<!-- -->\[\] | Additional filter conditions to 'NOR' together. |
8873+
8874+
<b>Returns:</b>
8875+
8876+
[BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class)
8877+
8878+
A new [BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class) representing the logical 'NOR' operation.
8879+
8880+
### Example
8881+
8882+
8883+
```typescript
8884+
// Check if neither the 'age' field is greater than 18 nor the 'city' field is "London"
8885+
const condition = nor(
8886+
greaterThan("age", 18),
8887+
equal("city", "London")
8888+
);
8889+
8890+
```
8891+
88088892
### or(first, second, more) {:#or_e0c48bd}
88098893

88108894
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.

packages/firestore/lite/pipelines/pipelines.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ export {
132132
equalAny,
133133
notEqualAny,
134134
xor,
135+
nor,
136+
switchOn,
135137
conditional,
136138
not,
137139
logicalMaximum,

packages/firestore/src/api_pipelines.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ export {
5454
} from './lite-api/stage_options';
5555

5656
export {
57-
field,
5857
constant,
5958
add,
6059
subtract,
6160
multiply,
6261
divide,
62+
field,
6363
mod,
6464
equal,
6565
notEqual,
@@ -88,6 +88,8 @@ export {
8888
equalAny,
8989
notEqualAny,
9090
xor,
91+
nor,
92+
switchOn,
9193
conditional,
9294
not,
9395
logicalMaximum,

packages/firestore/src/lite-api/expressions.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9879,6 +9879,37 @@ export function or(
98799879
).asBoolean();
98809880
}
98819881

9882+
/**
9883+
* @beta
9884+
*
9885+
* Creates an expression that performs a logical 'NOR' operation on multiple filter conditions.
9886+
*
9887+
* @example
9888+
* ```typescript
9889+
* // Check if neither the 'age' field is greater than 18 nor the 'city' field is "London"
9890+
* const condition = nor(
9891+
* greaterThan("age", 18),
9892+
* equal("city", "London")
9893+
* );
9894+
* ```
9895+
*
9896+
* @param first - The first filter condition.
9897+
* @param second - The second filter condition.
9898+
* @param more - Additional filter conditions to 'NOR' together.
9899+
* @returns A new {@link @firebase/firestore/pipelines#BooleanExpression} representing the logical 'NOR' operation.
9900+
*/
9901+
export function nor(
9902+
first: BooleanExpression,
9903+
second: BooleanExpression,
9904+
...more: BooleanExpression[]
9905+
): BooleanExpression {
9906+
return new FunctionExpression(
9907+
'nor',
9908+
[first, second, ...more],
9909+
'nor'
9910+
).asBoolean();
9911+
}
9912+
98829913
/**
98839914
* @beta
98849915
* Creates an expression that returns the value of the base expression raised to the power of the exponent expression.
@@ -10524,6 +10555,48 @@ export function ifAbsent(
1052410555
);
1052510556
}
1052610557

10558+
/**
10559+
* @beta
10560+
* Creates an expression that evaluates to the result corresponding to the first true condition.
10561+
*
10562+
* @remarks
10563+
* This function behaves like a `switch` statement. It accepts an alternating sequence of conditions
10564+
* and their corresponding results.
10565+
* If an odd number of arguments is provided, the final argument serves as a default fallback result.
10566+
* If no default is provided and no condition evaluates to true, it throws an error.
10567+
*
10568+
* @example
10569+
* ```typescript
10570+
* // Return "Active" if field "status" is 1, "Pending" if field "status" is 2,
10571+
* // and default to "Unknown" if none of the conditions are true.
10572+
* switchOn(
10573+
* equal(field("status"), 1), constant("Active"),
10574+
* equal(field("status"), 2), constant("Pending"),
10575+
* constant("Unknown")
10576+
* )
10577+
* ```
10578+
*
10579+
* @param condition - The first condition to check.
10580+
* @param result - The result if the first condition is true.
10581+
* @param others - Additional conditions and results, and optionally a default value.
10582+
* @returns A new Expression representing the switch operation.
10583+
*/
10584+
export function switchOn(
10585+
condition: BooleanExpression,
10586+
result: Expression,
10587+
...others: Array<BooleanExpression | Expression>
10588+
): FunctionExpression {
10589+
return new FunctionExpression(
10590+
'switch_on',
10591+
[
10592+
valueToDefaultExpr(condition),
10593+
valueToDefaultExpr(result),
10594+
...others.map(valueToDefaultExpr)
10595+
],
10596+
'switchOn'
10597+
);
10598+
}
10599+
1052710600
/**
1052810601
* @beta
1052910602
* Creates an expression that joins the elements of an array into a string.

0 commit comments

Comments
 (0)