Operators
This section describes the FQL operators. See Operator precedence for the operator precedence and associativity table.
Assignment
Operator | Syntax | Description |
---|---|---|
|
variable [:type] |
Simple assignment operator assigns the value to the declared variable. The optional :type notation constrains a value to the given type, where
type is one of the supported Types. For example, You can use an |
Arithmetic
The arithmetic operators perform arithmetic operations on numeric operands.
Operator | Syntax | Description |
---|---|---|
|
operand1 |
Addition, sums the operands. |
|
operand1 |
Subtraction, subtracts operand2 from operand1. |
|
operand1 |
Multiplication, multiplies the operands. |
|
operand1 |
Division, divides operand1 by operand2. |
|
operand1 |
Modulo, returns the remainder of operand1 divided by operand2 and takes the sign of the dividend. |
|
operand1 |
Exponentiation, returns the result of raising operand1 to the power of operand2. |
Concatenation
The plus operator performs concatenation on sting operands.
Operator | Syntax | Description |
---|---|---|
|
operand1 |
For String operands, concatenates the operands, left-to-right. |
Comparison
Comparison operators return a Boolean value.
For the <
, >
, ⇐
, and >=
operators, comparison across types always
returns false
and comparing non-comparable objects always returns false
.
Operator | Syntax | Description |
---|---|---|
|
expression1 |
Equal to. Returns
|
|
expression1 |
Not equal to. Returns |
|
expression1 |
Greater than. Returns
|
|
expression1 |
Greater than or equal to. Returns
|
|
expression1 |
Less than. Returns
|
|
expression1 |
Less than or equal to. Returns
|
expression1 |
Evaluate if expression1 is of type <type>, which can be any of the
supported runtime Types. The <type> must
be a module object. |
Check a value’s type with isa
Use the isa
operator to check if
a value is of a specific FQL type. For example:
"foo" isa String // true
123 isa String // false
123 isa Int // true
0.123 isa Double // true
123 isa Number // true
0.123 isa Number // true
{ a: "foo", b: "bar" } isa Object // true
[ 1, 2, 3 ] isa Array // true
Product.all() isa Set // true
// For documents, the type is the name
// of the collection. For example, `Product`
//collection documents have a type of `Product.`
Product.byName('limes').first() isa Product // true
// Document references also resolve to the
// document type.
Product.byId('111') isa Product // true
// Dangling references, which point to documents
// that don't exist, still resolve to the
// document type. For example, the following
// document doesn't exist.
Product.byId('999') isa Product // true
isa
doesn’t support
parameterized generic
types, such as Ref<A>
or Array<String>
. Queries that attempt to use isa
with such types return an invalid_query
error:
// NOT SUPPORTED:
[ 1, 2, 3 ] isa Array<Number>
// NOT SUPPORTED:
Product.all() isa Set<Product>
// NOT SUPPORTED:
Product.byId('111') isa Ref<Product>
Logical
Logical operators return a Boolean value.
Operator | Syntax | Description |
---|---|---|
|
operand1 |
Logical OR. Returns |
|
operand1 |
Logical AND. Returns |
Bitwise operators
Operator | Syntax | Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
expression1 | expression2 |
Bitwise inclusive OR:
|
|||||||||||||||
|
expression1 ^ expression2 |
Bitwise exclusive OR (XOR):
|
|||||||||||||||
|
expression1 & expression2 |
Bitwise AND:
|
Unary
Operator | Syntax | Description |
---|---|---|
|
|
Unary negation. Negates the operand it precedes. |
|
|
Logical negation (NOT). Inverts the value of the Boolean operand and returns a Boolean value. |
Examples:
Unary negation variations:
-5 // -5. A negative literal, not unary negation.
- 5 // -5. Unary negation applied to a literal.
let num = 5
-num // -5. Unary negation of a variable.
Insert a space between -
and operand if operand is a literal
Number.
Logical NOT:
!false // true
Optional chaining
Operator | Syntax | Description |
---|---|---|
|
object object |
Optional chaining. When accessing a field or invoking a method, if the
left side of the expression evaluates to If chained to other methods, the `null` value is passed to the method. For example, `{a: null}.a?.toString()` passes `null` to xref:reference:fql-api/string/tostring.adoc[], which returns `"null"`, a type:string[] representation of type:null[]. |
Examples:
let customer = {
name: "Alice Appleseed",
address: {
state: "DC"
}
}
customer.address?.state
The optional chaining operator can also be used with methods:
let customer = {
name: "Alice Appleseed",
address: {
state: "DC"
}
}
customer.name?.toLowerCase()
Null coalescing
Operator | Syntax | Description |
---|---|---|
|
expression1 |
Null coalescing. If expression1 evaluates to |
Example:
// Gets a `Customer` collection document.
let customer = Customer.byEmail("carol.clark@example.com").first()
// This customer's `cart` field is `null`.
customer?.cart ?? "Not found" // returns "Not found"
Non-null assertion postfix
Operator | Syntax | Description |
---|---|---|
|
expression |
Non-null assertion postfix. Runtime validation: if expression evaluates to
|
Example:
let customer = {
name: "Alice Appleseed",
address: {
state: "DC"
}
}
customer.date! // Returns an error.
Ternary operator
FQL doesn’t have a ternary (conditional) operator. You can get the same result
using an if … else
statement. For
example, to perform an upsert:
// Customer email to look up
let email = "alice.appleseed@example.com"
// Customer data to upsert
let data = {
name: "Alice Appleseed",
email: "alice.appleseed@example.com",
address: {
street: "87856 Mendota Court",
city: "Washington",
state: "DC",
postalCode: "20220",
country: "US"
}
}
// Try to find the existing customer by email.
// If the customer doesn't exist, returns `null`.
let customer = Customer.byEmail(email).first()
// Create or update the customer based on existence.
// If customer is null, create a new customer.
// Otherwise, update the existing one.
if (customer == null) {
Customer.create(data)
} else {
customer!.update(data)
}
Null checking
If you’re checking for a null value, you can use the
null coalescing (??
)
operator to return a default value when an expression is null
. For example:
// Try to find the existing customer by email.
// If the customer doesn't exist, return `null`.
let customer = Customer.byEmail("carol.clark@example.com")?.first()
// Use the null coalescing (??) operator to return the customer's
// cart. If the customer or their cart is `null`, return `"Not found"`.
// In this case, the customer's cart is `null`.
customer?.cart ?? "Not found" // returns "Not found"