# FQL language reference The FQL language reference document describes the FQL syntax and the fundamentals of using the language to query Fauna. FQL features a TypeScript-inspired syntax, which is extended to support concise relational queries and is, optionally, statically typed. This gives you a developer language that empowers you to write clear, concise queries and transactional code. A TypeScript-inspired database language is purpose-fit for Fauna. The resulting FQL syntax is familiar and easy to learn and scales to handle complex business logic, making it easy to realize the power of the Fauna operational database architecture. Unlike well-known relational query languages, which are keyword-heavy and require learning a new syntax for every feature, FQL has a small core syntax with dedicated shorthand for common query concepts, such as record predicates and projection. Occasionally, you might want to port a query from one context to another, such as interactively developing the query in the dashboard shell and copying it to your application code or applying your FQL knowledge in a different host programming environment. FQL has a dedicated syntax that applies to all contexts in which it exists, with drivers that implement a secure, string-based template system for embedded queries. This means that you can apply the same query syntax everywhere. # FQL syntax quick look This gives you a quick look at the Fauna Query Language (FQL) syntax. FQL is similar to JavaScript with influences from TypeScript and GraphQL, differing from those languages in that it is optimized for database operations. ## [](#basic-syntax)Basic syntax ```fql // Single-line comments start with double-slash. /* Block comments start with slash-asterisk and end with asterisk-slash. */ // Statements don't have to be terminated by ; ... (1 + 3) * 2 // ... but can be. (1 + 3) * 2; ///////////////////////////////////////////// // Numbers, Strings, and Operators // FQL has integer, decimal, and exponential values stored as // Int, Long, or Double types, which are all Number types. // An Int is a signed 32-bit integer type. // A Long is a signed 64-bit integer type. // Doubles are double-precision, 64-bit binary type, IEEE 754-2019. 3 // 3 1.5 // 1.5 3.14e5 // 314000.0 // Some basic arithmetic works as you'd expect. 1 + 1 // 2 0.1 + 0.2 // 0.30000000000000004 8 - 1 // 7 10 * 2 // 20 35 / 5 // 7 // Including uneven division. 5 / 2 // 2 // Precedence is enforced with parentheses. (1 + 3) * 2 // 8 // There's also a boolean type. true false // Strings are created with ' or ". 'abc' // "abc" "Hello, world" // "Hello, world" // Negation uses the ! symbol !true // false !false // true // Equality is == 1 == 1 // true 2 == 1 // false // Inequality is != 1 != 1 // false 2 != 1 // true // More comparisons 1 < 10 // true 1 > 10 // false 2 <= 2 // true 2 >= 2 // true // Strings are concatenated with + "Hello " + "world!" // "Hello world!" // and are compared with < and > "a" < "b" // true // Type coercion isn't performed for comparisons with double equals... "5" == 5 // false // You can access characters in a string with at() built-in string method. "This is a string".at(0) // "T" // ...or use an index. "Hello world"[0] // "H" // "length" is a property so don't use (). "Hello".length // 5 // There's also "null". null; // used to indicate a deliberate non-value // false, null, 0, and "" are falsy; everything else is truthy. ///////////////////////////////////////////// // Arrays, and Objects // Arrays are ordered lists containing values, of any type. let myArray = ["Hello", 45, true] myArray // ["Hello", 45, true] // Their members can be accessed using the square-brackets subscript syntax. // Array indices start at zero. You can also use the `at()` built-in method. myArray[1] // 45 myArray.at(1) // 45 // Arrays are of variable length. myArray.length // 3 // Accessing an Array index greater than or equal to the Array length: myArray[3] // results in an error. // Create an Array from elements in the range index 1 (include) to // index 4 (exclude). myArray.slice(1, 4) // [45, true] // FQL objects are equivalent to "dictionaries" or "maps" in other // languages: an unordered collection of key:value pairs. You can use // the dot syntax provided the key is a valid identifier. let myObj = {key1: "Hello", key2: "World"} myObj.key1 // "Hello" // Keys are strings but quotes aren't required if they're a valid // JavaScript identifier. Values can be any type. let myObj = {myKey: "myValue", "myOtherKey": 4} // Object attributes can also be accessed using the subscript syntax. myObj.myKey // "myValue" myObj.myOtherKey // 4 // If you try to access a value not yet set, you'll get an error. myObj.myThirdKey // results in an error. ///////////////////////////////////////////// // Variables // Use the "let" keyword to declare variables in a lexical scope and // assign a value to the variable. FQL is dynamically typed, so you don't // need to specify type. Assignment uses a single = character. Also, "let" // can't be the last statement, because it isn't an expression. let someVar = 5 someVar // 5 // A variable in the same scope can be assigned a new value: let someVar = 5 let someVar = 6 someVar // 6 // You can declare only one variable in the same `let` statement. ///////////////////////////////////////////// // Control structures, logic // The `if ... else` structure works as you'd expect. let count = 1 if (count == 3) { // evaluated if count is 3 } else if (count == 4) { // evaluated if count is 4 } else { // evaluated if not 3 or 4 } // `&&` is logical AND, `||` is logical OR let house = {size: "big", color: "blue"} if (house.size == "big" && house.color == "blue") { "big blue house" } if (house.color == "red" || house.color == "blue") { "red or blue" } ///////////////////////////////////////////// // Block scope // A block is defined with `{ }` and variables are scoped to the block. // Variables outside of the block are global. // The last statement in a block must be an expression. let greeting = "hi" { let greeting = "hello" greeting } // "hello" let greeting = "hi" { let greeting = "hello" greeting } greeting // "hi" ///////////////////////////////////////////// // Anonymous functions // FQL anonymous functions are declared using the short-form // arrow syntax. An anonymous function can't be called before the definition. (x) => { let greeting = "hello" greeting } // Objects can contain functions. let myFunc = { (x) => { let double = x + x double } } myFunc(3) // 6 // Some built-in methods accept single-argument functions. Customer.all().where(c => c.address.zipCode == "20002") // Which is equivalent to: let myFunc = { (c) => { c.address.zipCode == "20002" } } Customer.all().where(myFunc) ``` # Lexical elements Fauna Query Language (FQL) supports UTF-8 encoded [Unicode](https://home.unicode.org/) text. This section covers the basic character set, whitespace, line termination, and comments syntax elements. ## [](#char-set)Character set FQL supports the following character set: a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 $ ! % & ( ) \* + , - . / : ; < = > ? @ \[ \] ^ \_ { | } ~ \` Schema entity naming might impose added restrictions on the allowed character set. ## [](#whitespace)Whitespace Whitespace may be used between FQL tokens and are ignored by the parse. Whitespace is a nonempty sequence of any of the following characters, as listed in the [ECMAScript Language Specification](https://tc39.es/ecma262/#sec-white-space): | Unicode code point | Description | Escape sequence | | --- | --- | --- | --- | --- | | U+0009 | Character tab | \t | | U+000B | Line tab | \v | | U+000C | Form feed | \f | | U+0020 | Space | | | U+00A0 | No-break space | | | U+FEFF | Zero-width no-break space | | Line termination and block-style comments are also treated as whitespace and can be used anywhere whitespace can be used. ## [](#line-terminators)Line terminators Line terminators can be used where permitted by the syntactic grammar, which is wherever whitespace is allowed. The following table lists the recognized line termination characters: | Unicode code point | Description | Escape sequence | | --- | --- | --- | --- | --- | | U+000A | Line feed | \n | | U+000D | Carriage return | \r | | U+2028 | Line separator | | | U+2029 | Paragraph separator | | ## [](#escape-char)Escaped characters Use a backslash (`\`) to escape a character in a [String](../types/#string): | Escape sequence | Escaped character | | --- | --- | --- | --- | | \0 | null | | \' | single quote | | \" | double quote | | \` | backtick | | \# | number symbol | | \b | backspace | | \t | horizontal tab | | \n | line feed, new line | | \v | vertical tab | | \f | form feed | | \r | carriage return | | \\ | backslash | | \xhh | character represented by the hexadecimal value hh | | \uhhhh | character represented by the Unicode code point hhhh | | \u{hh…​} | character represented by the arbitrary Unicode code point hh…​ | ## [](#comments)Comments FQL supports single-line and block comments. * Single-line Comments The `//` character sequence starts a single-line comment. A line feed terminates the comment. ```fql // This is a single-line comment "String" // This comment annotates a line ``` * Block Comments A block comment can be used where whitespace is permitted. The `/*` character sequence starts a block comment. The comment is terminated by the matching `*/` character sequence. A block comment can span multiple lines and block comments can be nested. ```fql /* This block comment is on one line */ "String" /* This comment annotates a line */ /* This comment spans multiple lines */ /* This comment spans multiple lines. /* This block comment is nested within a block comment. */ */ ``` # Literals Fauna Query Language (FQL) supports literal syntax for [Number](../types/#number)s, [Boolean](../types/#boolean) values, [Null](../types/#null), [String](../types/#string)s, [Array](../types/#array)s, [Object](../types/#object)s, and [Function](../types/#function)s. ## [](#boolean)Boolean A [Boolean](../types/#boolean) is a logical expression that evaluates to true or false. The [Boolean](../types/#boolean) literals are `true` and `false`. ## [](#null)Null The [Null](../types/#null) literal represents the absence of a value. In [Boolean](../types/#boolean) expressions, `null` evaluates to `false`. The [Null](../types/#null) literal is `null`. ## [](#literal-num)Number A [Number](../types/#number) is a base 10 [Int](../types/#int), decimal, or exponential. Underscores can be used as separators instead of commas to improve readability but aren’t significant otherwise. ### [](#integer)Integer An [Int](../types/#integer) literal starts with a nonzero digit and don’t include a fractional or exponential part. A negative integer literal is preceded by the `-` character. 10 \-250 1\_000\_000 Integer literals can have the following base representation: | Base | Example | | --- | --- | --- | --- | | 2 | 0b1001 | | 8 | 0o123 | | 10 | 12345 | | 16 | 0x12a3 | ### [](#decimal)Decimal A decimal literal includes a fractional part. Internally, these are handled as [Double](../types/#double)s. 1.0 0.1 ### [](#exponential)Exponential E-notation is used for a decimal exponential literal: __e | E__: 1.2e23 3.4e-15 where, * __ is the base integer. * `e` or `E` separator indicates an exponential literal. * __ is the signed integer exponent. ## [](#string)String A [String](../types/#string) literal is a sequence of single-quoted string values or double-quoted interpolated string values from the FQL-supported [character set](../lexical/#char-set), and terminated by `null`. Single-quoted [String](../types/#string)s can include the `"` and `#` characters. Double-quoted [String](../types/#string)s can include the `'` character. ### [](#interpolated-strings)Interpolated string Double-quoted [String](../types/#string)s support expression interpolation using the `#{}` character sequence, where __ is an FQL expression: ```fql "Alice is #{3 + 2} years old." ``` ``` "Alice is 5 years old." ``` See the [escaped characters](../lexical/#escape-char) section for a list of escaped characters. ### [](#heredoc)Heredoc string A heredoc [String](../types/#string) is a way to write a string that spans multiple lines, enclosing the string with a beginning and ending user-defined token: ```fql <<+TOKEN A multiline string with leading whitespaces TOKEN ``` ``` <<-END A multiline string with leading whitespaces END ``` The token, on a line by itself, terminates the [String](../types/#string). On rendering, whitespace is removed from form each line, maintaining the same relative indentation for each line. Heredoc strings support interpolation: ```fql let weather = "overcast with occasional showers" <<+EOS Hello. Today is #{weather} EOS ``` ``` <<-END Hello. Today is overcast with occasional showers END ``` To declare a [String](../types/#string) with variables but without doing interpolation, precede the [String](../types/#string) with a token in the format `<<-TOKEN`: ```fql <<-ASIS str => "Hello #{str}" ASIS ``` ``` <<-END str => "Hello #{str}" END ``` You might want to avoid interpolation when defining a Function body, for example. The `#{str}` variable executes in the context of the function instead of when the string is rendered. ## [](#array)Array [Array](../types/#array)s group items and are represented as a comma-separated list of literals or expressions enclosed by `[ ]`: ```fql ["a", 1 + 1, if (true) "true" else "false", null] ``` ``` [ "a", 2, "true", null ] ``` [Array](../types/#array) members can be accessed individually using a single variable. Members are indexed left to right, starting with 0. In the example, the `"a"` member is Array element 0 and the `null` member is array element 3: ```fql let array = ["a", 1 + 1, if (true) "true" else "false", null] [ array[0], array[3]] ``` ``` [ "a", null ] ``` ## [](#object)Object An [Object](../types/#object) is represented as a key:value pair enclosed by `{ }`, or field:value pair when referring to schema entities. ```fql { "a": 1 } ``` An object can hold multiple, comma-separated key:value pairs: ```fql { "a": 1, b: 2 } ``` Key or field names can be identifiers or [String](../types/#string) literals: ## [](#anonymous-function)Anonymous function An anonymous function is represented using the short-form, JavaScript-like arrow function syntax: (\[parameter\[, parameter\]\]) => {\[statement \[statement …​ \]\] expression \[expression …​ \]} Or, simplified: (parameter) => { expression } If the function has only one parameter, `()` can be omitted around the parameter. If the function body has only a single expression, the `{}` block delimiter can be omitted. # Reserved words ## [](#reserved-fql-keywords-and-type-names)Reserved FQL keywords and type names The following FQL keywords and types names are reserved and may not be used as a variable, parameter, or top-level entity name. Keywords: | at | false | if | let | null | true | | --- | --- | --- | --- | --- | --- | --- | --- | Types: | Array | Boolean | Bytes | Date | Double | | --- | --- | --- | --- | --- | --- | --- | | Function | Long | Null | Number | Object | | String | Timestamp | Tuple | Union | Uuid | ## [](#reserved-schema)Reserved schema names The following schema entity, method, and metadata names may not be used as top-level, user-defined entity names. The acronym `FQL`, itself, is reserved. This means `FQL.Collection` can be called to get the Collection module if needed. Schema entities: | AccessProvider | Collection | Credential | Database | Doc | | --- | --- | --- | --- | --- | --- | --- | | Function | Index | Key | Query | Role | | Token | View | | | | Schema methods: | delete | replace | update | updateData | replaceData | | --- | --- | --- | --- | --- | --- | --- | Schema metadata fields: | coll | id | ts | ttl | | --- | --- | --- | --- | --- | --- | Schema data field: | data | | | | | --- | --- | --- | --- | --- | --- | ## [](#reserved-index-names)Reserved index names The following names can’t be used as [Collection](../../fql-api/collection/) names: | documents | events | self | sets | | --- | --- | --- | --- | --- | --- | ## [](#see-also)See also [Aliasing](../naming/#aliasing) [Document field name collision](../naming/#collision) # Types This section lists the FQL data types. FQL supports [static typing](../static-typing/). Not all types are representable in JSON. FQL handles values similar to GraphQL where non-JSON types are _downcast_ to a JSON equivalent, which can then be used as-is or recast client-side to a richer type. Type representation summary: * JSON representable values are rendered verbatim. * Non-JSON scalar values are reduced to a JSON-compatible representation. * Document objects are reduced to JSON objects that include all the fields. * Nested documents aren’t expanded. * Sets are reduced to the first page of the set, which is equivalent to calling `.paginate()` without arguments. The query response includes `before` and `after` page references as applicable. * Singleton objects are reduced to string descriptions. ## [](#persistable)Persistable types Persistable types have values that can be reliably stored, retrieved, and updated in a Fauna database. Documents can only store persistable values. [FSL collection schema: Field definitions](../../fsl/field-definitions/) only allow persistable types. Persistable types are: * [Boolean](#boolean) * [Date](#date) * [Ref](#ref) (document references), excluding references to [named system collection](../../../learn/data-model/collections/#named-coll) documents * [Null](#null) * [Number](#number), including [Double](#double), [Int](#int), and [Long](#long) * [String](#string) * [Time](#time) * [Array](#array) of other persistable types * [Object](#object) of other persistable types * [Tuple](#tuple) of other persistable types * [Union](#union) of other persistable types ## [](#scalar)Scalar types The scalar types are JSON serializable types that hold a single value. Types, including [String](#string), [Date](#date), and [Time](#time), are objects that have built-in methods and properties. ### [](#boolean)Boolean A boolean data type has a boolean literal value of `true` or `false`. Boolean variables and expressions can be compared explicitly or implicitly against a boolean literal. In the following example, the `if` statements are equivalent: ```fql let a = true if (a == true) { // expression } if (a) { // expression } ``` Comparison operators return a boolean value: ```fql let a = 10 let b = 20 a > b ``` ``` false ``` ### [](#bytes)Bytes A Base64-encoded string representing a byte array. ### [](#date)Date | Reference: Date | | --- | --- | --- | A date in the `YYYY-MM-DD` format, such as `2099-11-03`. A [Date](#date) value is encoded as a string in responses. ### [](#double)Double See [Number](#number). ### [](#id)ID A 64-bit integer represented as a decimal number that uniquely identifies a resource. ### [](#int)Int See [Number](#number). ### [](#long)Long See [Number](#number). ### [](#null)Null The Null type has the single value `null`. Null is a marker used to indicate that a data value doesn’t exist. It is a representation of missing information, indicating a lack of a value, which differs from a value of zero. ### [](#nulldoc)NullDoc A marker used to indicate that a document doesn’t exist or is inaccessible. The data type is taken from the collection’s name with the `Null` prefix. For example, a `NullDoc` for the `Product` collection has the `NullProduct` type. Testing a `NullDoc` against a value of `null` returns `true`. `NullDoc` is returned by the `byId()` or `byName()` queries and by links from another doc (`id` or `coll`) when the linked document doesn’t exist or is inaccessible. The following lists `NullDoc` types for system collections: | NullDoc type | Description | Value | | --- | --- | --- | --- | --- | | NullAccessProvider | Returned type when an AccessProvider document doesn’t exist. | null | | NullCollectionDef | Returned type when a Collection document, which has the CollectionDef type, doesn’t exist. | null | | NullCredential | Returned type when a Credential document doesn’t exist. | null | | NullDatabaseDef | Returned type when a Database document, which has the DatabaseDef type, doesn’t exist. | null | | NullFunctionDef | Returned type when a Function document, which has the FunctionDef type, doesn’t exist. | null | | NullKey | Returned type when a Key document doesn’t exist. | null | | NullRole | Returned type when a Role document doesn’t exist. | null | | NullToken | Returned type when a Token document doesn’t exist. | null | ### [](#number)Number FQL has built-in types that represent numbers, which are summarized in the following table: | Type | Size, bits | Description | Range | Examples | | --- | --- | --- | --- | --- | --- | --- | | Double | 64 | double-precision IEEE-754 floating point | | 1.12341.2e23 | | Int | 32 | Signed two’s complement integer | -231 to 231-1 | 10-2501_000_000 | | Long | 64 | Signed two’s complement integer | -263 to 263-1 | 922337036854775808-9223372036854775808 | Underscores are permitted in numeric [literals](../literals/#literal-num) as separators to aid readability but have no other significance. ### [](#string)String | Reference: String | | --- | --- | --- | String literals are single-quoted string values or double-quoted interpolated string values from the FQL-supported [character set](../lexical/#char-set). Single-quoted strings can also include the `"` and `#` characters. Double-quoted strings can also include the `'` character. Use `\` to escape a character in a string. #### [](#interpolated-strings)Interpolated strings Double-quoted strings support the interpolation of expressions in a string. Encode the interpolation string using the `#{}` character sequence, where __ is an FQL expression: ```fql "Alice is #{3 + 2} years old." ``` evaluates to: ``` "Alice is 5 years old." ``` #### [](#heredoc-strings)Heredoc strings You can use heredoc strings for multiple lines of text that behave similarly to double-quoted strings. A heredoc string is delimited by tokens that start with the `<<` character sequence followed by a user-defined character and a line break. Conventionally, the token is uppercase characters. The same token terminates a heredoc string and is on a line by itself: ```fql <<+STR A multiline string STR ``` A heredoc string removes leading whitespace at the beginning of each line, removing the same number of characters in each line: ```fql <<+STR A multiline string with leading whitespaces STR ``` evaluates to: ``` <<-END A multiline string with leading whitespaces END ``` ### [](#time)Time | Reference: Time | | --- | --- | --- | The Time type is an instant in time expressed as a calendar date and time of day in UTC, in the range `-999999999-01-01T00:00:00Z` to `9999-12-31T23:59:59.999999999Z` A [Time](#time) value can store nanosecond precision. Times can be inserted with offsets but are converted to UTC and the offset component is lost. A [Time](#time) value is encoded as a string in responses. ### [](#transactiontime)TransactionTime | Reference: TransactionTime | | --- | --- | --- | The TransactionTime type is the query transaction expressed as a calendar date and time of day in UTC, in the range `-999999999-01-01T00:00:00Z` to `9999-12-31T23:59:59.999999999Z` A [TransactionTime](#transactiontime) value can store nanosecond precision. A [Time](#time) value is encoded as a string in responses. ### [](#uuid)Uuid Universally Unique IDentifier (UUID) uniquely identifies a resource. ## [](#special)Data reference types The data reference types represent Fauna resources and have built-in methods and properties. ### [](#collection)Collection | Reference: Collection | | --- | --- | --- | A Collection groups documents in a database. ### [](#collectiondef)CollectionDef | Reference: Collection | | --- | --- | --- | A Collection definition, represented as a [`Collection` document](../../fql-api/collection/#collection). A collection definition is the FQL equivalent of an FSL [collection schema](../../../learn/schema/#collection-schema). ### [](#database)Database A database can have Collections, Documents, User-defined functions, security elements such as Keys, Tokens, Credentials, Access Providers, and child databases. ### [](#databasedef)DatabaseDef | Reference: Database | | --- | --- | --- | A database definition, represented as a [`Database` document](../../fql-api/database/#collection). ### [](#document)Document | Reference: Document | | --- | --- | --- | A record in a [Collection](#collection). You add documents to a collection as JSON-like objects. The document type is taken from the name of the collection of which the document is a member. For example, a document in the `Product` collection is of type `Product`, and if the requested document isn’t a member of the collection, the response type is `NullProduct`. All documents have [metadata fields](../../../learn/data-model/documents/#meta). ### [](#ref)Ref (Document reference) | Learn: Model relationships using document references | | --- | --- | --- | A reference to a [Document](#document). Can resolve to an existing document or a [NullDoc](#nulldoc). Document references contain the document’s [collection](../../../learn/data-model/collections/) and [document ID](../../../learn/data-model/documents/). You can use document references to [model relational data](../../../learn/data-model/relationships/) and create [relationships between documents](../../../learn/data-model/relationships/). ### [](#namedref)NamedRef A [reference](../../../learn/data-model/relationships/) to a [Document](#document) in a [named system collection](../../../learn/data-model/collections/). Can resolve to an existing document or a [NullDoc](#nulldoc). In named collections, each document is uniquely identified by its name instead of a [document ID](../../../learn/data-model/documents/). Named references contain the document’s [collection](../../../learn/data-model/collections/) and `name`. ### [](#function)Function | Reference: Function | | --- | --- | --- | A function is an FQL expression stored in a database. ### [](#functiondef)FunctionDef | Reference: Function | | --- | --- | --- | A [user-defined function (UDF)](../../../learn/schema/user-defined-functions/) definition, represented as a [`Function` document](../../fql-api/function/#collection). A function definition is the FQL equivalent of an FSL [function schema](../../fsl/function/). ## [](#advanced)Advanced types The advanced types represent complex objects or types that can hold multiple values. The iterable [Array](#array) and [Set](#set) types have built-in properties and methods. ### [](#any)Any The Any type denotes a field that can be of any other type or might be not present. ### [](#array)Array | Reference: Array | | --- | --- | --- | The [Array](#array) type is a comma-separated list of expressions enclosed by `[]`. An Array can hold mixed types, including functions: ```fql ["a", 1 + 1, if (true) "true" else "false", null] ``` evaluates to: ``` [ "a", 2, "true", null ] ``` For [`array.map()`](../../fql-api/array/map/), [`array.forEach()`](../../fql-api/array/foreach/), and similar methods, Array literals are evaluated left to right. The Array type is an iterable data structure that has an ordered collection of typed values. An Array: * can hold values of different types. * can be accessed only using positive integers. * is zero-indexed. * can’t contain more than 16,000 elements. ### [](#event-source)Event Source | Reference: Event Feeds and Event Streams | | --- | --- | --- | A string-encoded token representing an [event source](../../../learn/cdc/): ``` "g9WD1YPG..." ``` When tracked changes occur in a database, the event source emits a related event. To create an event source, use an FQL query that calls [`set.eventSource()`](../../fql-api/set/eventsource/) or [`set.eventsOn()`](../../fql-api/set/eventson/) to a [supported Set](../../../learn/cdc/#sets). You can use the token to consume the source’s events as an [Event Feed or Event Stream](../../../learn/cdc/). For supported event source methods, see [EventSource instance methods](../../fql-api/event-source/#instance-methods). ### [](#iterable)Iterable The type of all iterable types: * Array type * Set type ### [](#never)Never FQL method signatures use the Never type to represent a value that never occurs or the return value of a function that never returns. See [`abort()`](../../fql-api/globals/abort/) for an example. ### [](#module)Module The Module type is a singleton object that represents a grouping of functionality. Examples include [Math](../../fql-api/math/), [Query](../../fql-api/query/), and [Function](../../fql-api/function/), and [Collection](../../fql-api/collection/)s. A module gets serialized as an `@mod` value in the tagged format. Use the [isa](../operators/#comparison) operator for testing a module type. ### [](#object)Object The Object type is the type of all objects and represents a JSON-like object whose contents are a collection of key:value pairs. The keys must be strings and the values must be valid FQL data types. The value expressions are evaluated sequentially in the order defined, left to right. Objects evaluate to their contents. Objects can be combined to emulate abstract data types found in other functional languages. Object subtypes: * [Struct](#struct) * [Document](#document) Object types may have zero or more field types and an optional wildcard field type. Examples: ```fql { x: Number, y: Number } // object with two fields { kind: "dog" | "cat" | "bird", age: long } ``` The wildcard field type opens an object to arbitrary fields that correspond to the wildcard type: ```fql // An object with one `long` field and any number of `string` fields { count: Long, *: String } // An object with any number of arbitrary fields { *: Any } ``` ### [](#set)Set | Reference: Set | | --- | --- | --- | A Set is an iterable group of values, typically representing documents in a collection. ### [](#singleton)Singleton Every primitive value is also a Singleton type. * Strings: `"foo" "bar"` * Integers: `1 2 3 -99` * Booleans: `true` or `false` * `null` Singletons can be combined to emulate abstract data types found in other functional languages. ### [](#struct)Struct A Struct is a plain [Object](#object) that isn’t a [Document](#document). The value returned from projection on a document is a [Struct](#struct). ### [](#tuple)Tuple Tuples are sequences of zero or more typed values: ```fql-sig [] // The empty tuple + [string, string] // tuple of two string values + [boolean] // tuple of one boolean value + [string, long, boolean] // tuple of a string, long, and boolean + [string[], long[]] // tuple of an Array of strings and an Array of longs ``` Tuple values are subtypes of Arrays of the union of the tuple slot types: ```fql-sig [string, string] // `string[]` + [boolean] // `boolean[]` + [string, long, boolean] // `(string | long | boolean)[]` ``` ### [](#union)Union Union type allows values of any constituent types: ```fql-sig boolean | number // all booleans and numbers + { x: number } | string // all the object types and strings ``` Unions can be combined to emulate abstract data types found in other functional languages: ```fql-sig { type: "point", x: long, y: long } | { type: "circle", x: long x: long, radius: long } ``` Unlike TypeScript, FQL unions that include [Any](#any) preserve both [Any](#any) and the original types. [Any](#any) does not subsume the other types. This allows for more precise type checking and errors. For example: ```fql let foo: Any | Number = 2 foo // Returns `2` with a type of `Any | Number` ``` The stricter typechecking can impact behavior at runtime. For example, the following TypeScript compiles but would return an error at runtime: ```typescript const foo: any = null; const bar = (true) ? foo : 2; // Attempts to access a property of // null. TypeScript allows this. bar.baz; ``` An equivalent FQL query returns an `invalid_query` error during typechecking: ```fql let foo: Any = null let bar = if (true) foo else 2 // Attempts to access a property of // null. FQL returns an error. bar.baz ``` ## [](#security)Security-related types The security data types are used with Fauna authentication and authorization APIs. ### [](#accessprovider)AccessProvider | Reference: Access providers | | --- | --- | --- | An [`AccessProvider` document](../../fql-api/accessprovider/). `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](#accessprovider) type. See [Access providers](../../../learn/security/access-providers/). ### [](#credential)Credential | Reference: Credential | | --- | --- | --- | A Credential object represents a Credential in a Fauna database. ### [](#key)Key | Reference: Key | | --- | --- | --- | A Key is a JSON object document subtype stored in a database Key collection that represents an [Key](../../fql-api/key/). A key ensures anonymous access to a database to execute operations permitted by the role associated with the key. ### [](#role)Role | Reference: Role | | --- | --- | --- | A Role is a JSON object document subtype stored in a database Role collection that represents an [Role](../../fql-api/role/). ### [](#token)Token | Reference: Token | | --- | --- | --- | Tokens are defined as documents in the Token collection, and are used to control identity-based access to a database. # Variables and identifiers This section describes the syntax for variable declaration and the rules for associating named identifiers with variables. ## [](#variables)Variables Variables are used to store values that are one of the FQL [Types](../types/). You assign a value to the variable using the [`let`](../statements/#let) statement: ```fql let foo = 5 ``` By default, variables are immutable so you can’t assign a new value to the variable. Assigning a new value to the variable `x` gives an error: ```fql let x = 5 x = 6 ``` ``` invalid_query: The query failed 1 validation check error: Expected end-of-input at *query*:2:3 | 2 | x = 6 | ^ | ``` But you can redeclare a variable: ```fql let a = 2 let a = 4 a ``` ``` 4 ``` You can also use a previous definition of the variable to redeclare the variable: ```fql let x = 1 let x = x + 1 x ``` ``` 2 ``` Here is a more complex redefinition example using an anonymous function, which shows the effect of the order of declaration: ```fql let x = "foo" let fn = () => x let x = "bar" let y = fn() [y, x] ``` ``` [ "foo", "bar" ] ``` Variables are scoped to the block in which they’re declared as shown in this example: ```fql let x = "foo" let y = { let x = "bar" x // a block must end with an expression } [x, y] ``` ``` [ "foo", "bar" ] ``` ## [](#identifier)Identifiers An identifier associates a name with a value. The name can be used to refer to a variable, property, field, or resource. * An identifier must start with a character from the set `[a-zA-Z_]` and be followed by zero or more characters from the set `[a-zA-Z0-9_]`. An identifier defined with the [let](../statements/#let) statement can’t be a single underscore (`_`) character. The single underscore is allowed as an anonymous function parameter and can be repeated in an anonymous function parameter list. * Identifiers are case-sensitive. * An identifier can’t be a [reserved](../reserved/) word except as described in [Naming and aliasing](../naming/). ## [](#see-also)See also [Naming and aliasing](../naming/) [Blocks and lexical scoping](../blocks/) # Blocks and lexical scoping ## [](#blocks)Blocks A block is an expression that encapsulates one or more statements or expressions, and is enclosed by `{ }`: ```fql { let a = 1 let b = 2 a + b } ``` ``` 3 ``` The last statement in a block must be an [expression](../statements/). A block is itself an expression, and has the type and result of the last expression of the block: ```fql let x = { let a = 1 let b = 2 a + b } x ``` ``` 3 ``` ## [](#scope)Scope A block defines variable scope. Variables declared in a block are scoped to the block and can’t be referenced outside of the block. ```fql let x = "foo" let y = { let x = "bar" x } [x, y] ``` ``` [ "foo", "bar" ] ``` In the example, two `x` variables are declared. One with local scope and one with global scope. Variable `y` has global scope and is the value of the block. # Field accessors and method chaining This section covers field accessors and method chaining. ## [](#field-accessor)Field access Accessors can be viewed as keys for referencing fields or properties in an associative array, dictionary, or lookup table. In Fauna documents, fields can be accessed using dot notation or bracket notation. ### [](#dot-notation-field-accessor)Dot notation field accessor The dot prefix (`.`) preceding the field name is used to access a field or property, as shown by the `.aKey` notation in this example: ```fql let object = { aKey: "one", bKey: "two" } object.aKey ``` ``` "one" ``` Providing a field that doesn’t exist returns an error. ### [](#bracket-notation-field-accessor)Bracket notation field accessor The following example uses bracket notation (`[ ]`), passing the field name as a string to access the field or property: ```fql let object = { aKey: "one", bKey: "two" } object["aKey"] ``` ``` "one" ``` Providing a field that doesn’t exist returns `null`. Using bracket notation allows you to dynamically access document fields as shown in this example: ```fql let object = { aKey: "one", bKey: "two" } let x = "aKey" object[x] ``` ``` "one" ``` ## [](#method-chaining)Method chaining Methods can be chained using dot notation to compose complex queries where the output of the previous method is the input of the next method. In this example, the query returns up to ten documents from all the documents in the `Product` collection: ```fql Product.all().take(10) ``` ## [](#anonymous-field-and-method-access)Anonymous field and method access A variant of dot notation, the [optional chaining](../operators/#optional-chaining) operator can be used to access a field or invoking a method, returning `null` instead of an error if the left side of the expression evaluates to `null`. Access an anonymous field example: ```fql let customer = { name: "Alice Appleseed", address: { state: "DC" } } customer.address?.state // Returns "DC" ``` # Operators This section describes the FQL operators. See [Operator precedence](../precedence/) for the operator precedence and associativity table. ## [](#assignment)Assignment | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | = | variable [:type] = value | 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,let x:String = "5"is a valid statement, whereaslet x:String = 5results in an invalid_query error. | ## [](#arithmetic)Arithmetic The arithmetic operators perform arithmetic operations on numeric operands. | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | + | operand1 + operand2 | Addition, sums the operands. | | - | operand1 - operand2 | Subtraction, subtracts operand2 from operand1. | | * | operand1 * operand2 | Multiplication, multiplies the operands. | | / | operand1 / operand2 | Division, divides operand1 by operand2. | | % | operand1 % operand2 | Modulo, returns the remainder of operand1 divided by operand2 and takes the sign of the dividend. | | ** | operand1 ** operand2 | Exponentiation, returns the result of raising operand1 to the power of operand2. | ## [](#concatenation)Concatenation The plus operator performs concatenation on sting operands. | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | + | operand1 + operand2 | For String operands, concatenates the operands, left-to-right. | ## [](#comparison)Comparison Comparison operators return a [Boolean](../types/#boolean) value. For the `<`, `>`, `⇐`, and `>=` operators, comparison across types always returns `false` and comparing non-comparable objects always returns `false`. | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | == | expression1 == expression2 | Equal to. Returns true if expression1 and expression2 have the same value. Otherwise, returns false.When comparing documents, only the document id metadata fields are compared and all other fields are ignored.Sets are equal if they have the same elements and the elements are in the same order. | | != | expression1 != expression2 | Not equal to. Returns true if expression1 and expression2 do not have the same value. Otherwise, returns false. | | > | expression1 > expression2 | Greater than. Returns true if expression1 is greater than expression2.Comparison across types returns false.Comparison of non-comparable objects, such as anonymous functions and Set cursors, returns false.Comparing Sets isn’t supported but a Set can be converted to an Array and then compared. See set.toArray(). | | >= | expression1 >= expression2 | Greater than or equal to. Returns true if expression1 is greater than or equal to expression2.Comparison across types returns false.Comparison of non-comparable objects, such as anonymous functions and Set cursors, returns false.Comparing Sets isn’t supported but a Set can be converted to an Array and then compared. See set.toArray(). | | < | expression1 < expression2 | Less than. Returns true if expression1 is less than expression2.Comparison across types returns false.Comparison of non-comparable objects, such as anonymous functions and Set cursors, returns false.Comparing Sets isn’t supported but a Set can be converted to an Array and then compared. See set.toArray(). | | <= | expression1 <= expression2 | Less than or equal to. Returns true if expression1 is less than or equal to expression2.Comparison across types returns false.Comparison of non-comparable objects, such as anonymous functions and Set cursors, returns false.Comparing Sets isn’t supported but a Set can be converted to an Array and then compared. See set.toArray(). | | isa | expression1 isa | Evaluate if expression1 is of type , which can be any of the supported runtime Types. The must be a module object.Example: "1" isa String returns true | ## [](#logical)Logical Logical operators return a [Boolean](../types/#boolean) value. | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | || | operand1 || operand2 | Logical OR. Returns true if one of the operands is true. Otherwise, returns false. | | && | operand1 && operand2 | Logical AND. Returns true if the operands are true. Otherwise, returns false. | ## [](#bitwise-operators)Bitwise operators | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | | | expression1 | expression2 | Bitwise inclusive OR: expression1expression2expression1 | expression2000011101111 | expression1 | expression2 | expression1 | expression2 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | | expression1 | expression2 | expression1 | expression2 | | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | | 1 | 1 | 1 | | ^ | expression1 ^ expression2 | Bitwise exclusive OR (XOR): expression1expression2expression1 ^ expression2000011101110 | expression1 | expression2 | expression1 ^ expression2 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | | expression1 | expression2 | expression1 ^ expression2 | | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | | 1 | 1 | 0 | | & | expression1 & expression2 | Bitwise AND: expression1expression2expression1 & expression2000010100111 | expression1 | expression2 | expression1 & expression2 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | | expression1 | expression2 | expression1 & expression2 | | 0 | 0 | 0 | | 0 | 1 | 0 | | 1 | 0 | 0 | | 1 | 1 | 1 | ## [](#unary)Unary | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | - | -operand- operand | Unary negation. Negates the operand it precedes. | | ! | !operand | Logical negation (NOT). Inverts the value of the Boolean operand and returns a Boolean value. | Examples: Unary negation variations: ```fql -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](../types/#number). Logical NOT: ```fql !false // true ``` ## [](#optional-chaining)Optional chaining | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | ?. | object.value?.fieldobject.method?.(args) | Optional chaining. When accessing a field or invoking a method, if the left side of the expression evaluates to null, return null. | Examples: ```fql let customer = { name: "Alice Appleseed", address: { state: "DC" } } customer.address?.state ``` The optional chaining operator can also be used with methods: ```fql let customer = { name: "Alice Appleseed", address: { state: "DC" } } customer.name?.toLowerCase() ``` ## [](#null-coalescing)Null coalescing | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | ?? | expression1 ?? expression2 | Null coalescing. If expression1 evaluates to null, return the expression2 result. Otherwise, return the expression1 result. | Example: ```fql // 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)Non-null assertion postfix | Operator | Syntax | Description | | --- | --- | --- | --- | --- | | ! | expression! | Non-null assertion postfix. Runtime validation: if expression evaluates to null, return an error. Otherwise, return the result. | Example: ```fql let customer = { name: "Alice Appleseed", address: { state: "DC" } } customer.date! // Returns an error. ``` ## [](#ternary-operator)Ternary operator FQL doesn’t have a ternary (conditional) operator. You can get the same result using an [`if …​ else`](../statements/#if) statement. For example, to perform an upsert: ```fql // 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 == null) { Customer.create(data) } else { customer!.update(data) } ``` # Operator precedence An expression is evaluated in the order determined by operator precedence, and precedence is meaningful only if the expression includes multiple operators. The higher precedence operator is evaluated first. Operand grouping can be enforced by using parentheses. Associativity rules are applied to the order of operation for operators that have the same precedence. Precedence order, from highest to lowest, and associative are listed here: | Description | Operators and syntactic elements | Associativity | | --- | --- | --- | --- | --- | | field access, optional chaining, non-null assertion,function call | ., =>, (), ?., ! | left-to-right,function call: n/a | | unary, logical NOT | -, ! | n/a | | exponentiation | ** | right-to-left | | multiplication, division, modulo | *, /, % | left-to-right | | addition, subtraction | +, - | left-to-right | | bitwise AND | & | left-to-right | | bitwise XOR | ^ | left-to-right | | bitwise OR | | | left-to-right | | is-a comparison | isa | left-to-right | | comparison | >, <, >=, <= | left-to-right | | equality | ==, != | left-to-right | | logical AND | && | left-to-right | | logical OR | || | left-to-right | | Null coalescing | ?? | left-to-right | # Expressions and statements A query is a series of zero or more statements and expressions separated by newlines or semicolons. Multiple statements and expressions in a [block](../blocks/) must end with an expression. Statements and expressions can span multiple lines, and there is no line continuation character. ## [](#at)`at` Get the result of an expression at a given time. ### [](#syntax)Syntax at (_expression1_) _expression2_ ### [](#description)Description The `at` expression gets the result of _expression2_ at the _expression1_ time snapshot of the data. The _expression1_ operand is a [Time](../../fql-api/time/) or [TransactionTime](../../fql-api/transactiontime/). The `at` expression returns `null` if the requested document doesn’t exist. This changes the time when [`collection.byId()`](../../fql-api/collection/instance-byid/) is evaluated. Fauna stores document history up to the limit defined by [`history_days`](../../fql-api/collection/static-create/#parameters). The default number of days stored is zero so `history_days` must be increased for `at` to be meaningful. See [Document history](../../../learn/doc-history/). ### [](#examples)Examples The following example gets the current document and a snapshot of the document from yesterday. 1. After running this query yesterday to create a document, ```fql Product.create({ id: "9780547928227", name: "lemon", state: "yesterday state" }) ``` ``` { id: "9780547928227", coll: Product, ts: Time("2099-04-10T16:22:32.420Z"), name: "lemon", state: "yesterday state" } ``` 2. And running this query today to update the document, ```fql Product.byId("9780547928227")?.updateData({ state: "today state" }) ``` ``` { id: "9780547928227", coll: Product, ts: Time("2099-04-10T16:23:03.520Z"), name: "lemon", state: "today state" } ``` 3. The following query returns the current data, ```fql Product.byId("9780547928227")?.state ``` ``` "today state" ``` 4. And the following query returns the data from yesterday, ```fql let yesterday = Time.now().subtract(1, "day") at (yesterday) { Product.byId("9780547928227")?.state } ``` ``` "yesterday state" ``` The following examples show that when comparing documents using the `==` operator, only the document `id` field is compared, ignoring all other fields. Compare the `state` fields of different versions of the same document, which differ because of the state change between yesterday and today: ```fql let yesterday = Time.now().subtract(1, "day") let product1 = at(yesterday) { Product.byId('9780547928227') } let product2 = Product.byId('9780547928227') product1?.state == product2?.state ``` ``` false ``` Compare versions of the full document. The documents are identical because the document `id` fields are the same: ```fql let yesterday = Time.now().subtract(1, "day") let product1 = at(yesterday) { Product.byId('9780547928227') } let product2 = Product.byId('9780547928227') product1 == product2 ``` ``` true ``` ## [](#if)`if …​ else` Use conditional branching for execution control flow. ### [](#syntax-2)Syntax if (_expression1_) _expression2_ \[else _expression3_\] ### [](#description-2)Description The `if` and `if …​ else` expressions conditionally execute a block depending on the [Boolean](../types/#boolean) value of _expression1_. If _expression1_ evaluates to `true`, _expression2_ executes. Otherwise, _expression3_ executes. The last expression in the `if` or `else` block that satisfies the condition is the value returned for the block. The result of the `if` expression is a value that can be assigned to a variable. If the expression evaluates to `false` and `else` isn’t included, the expression returns `null`. ### [](#examples-2)Examples Change the query result when the `if` condition evaluates to `true`: ```fql if (5 > 3) "higher" ``` ``` "higher" ``` Use an `else` block if the condition evaluates to `false`: ```fql if (5 > 6) { "higher" } else { "lower" } ``` ``` "lower" ``` Assign the result of the `if` expression to a variable: ```fql let state = if (5 > 6) { "higher" } else { "lower" } state ``` ``` "lower" ``` ### [](#ternary-operator)Ternary operator FQL doesn’t have a ternary (conditional) operator. You can get the same result using an [`if …​ else`](#if) statement. For example, to perform an upsert: ```fql // 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 == null) { Customer.create(data) } else { customer!.update(data) } ``` ## [](#let)`let` Assign a value to a variable. ### [](#syntax-3)Syntax let _name_ \[: _type_\] = _value_ ### [](#description-3)Description A `let` statement declares a variable with a _name_ identifier and assigns a _value_ to the variable. Optionally, you can type the variable as any of the supported [types](../types/). The _name_ can be any valid [identifier](../variables/#identifier) but can’t be a single underscore (\_) character. The variable is scoped to the [block](../blocks/) in which it is declared. A variable can be referenced in a nested block, but a variable declared in a nested block can’t be referenced outside of the block. Assigning a value to a variable can be done only using the `let` statement. You can’t assign a value to _name_ directly: ```fql let x = 100 // valid assignment x = 1000 // invalid assignment ``` A variable of the same _name_ can be declared again in the same block and assigned a new value. It is a new variable declaration, and the previously declared variable can no longer be referenced: ```fql let x = 100 // (A) valid assignment let x = 1000 // (B) valid assignment and (A) can no longer be referenced x // returns 1000 ``` ### [](#examples-3)Examples Declare and assign [Int](../types/#int), [String](../types/#string), and [Array](../types/#array) values to variables: ```fql let xInt = 5 let yString = "hello" let zArray = [xInt, yString] [xInt, yString, zArray] ``` ``` [ 5, "hello", [ 5, "hello" ] ] ``` Variable scoping example where the declared `x` variable has global scope, while the scope of variables `a` and `b` is limited to the block: ```fql let x = { // a and b are only accessible in this block let a = 1 let b = 2 a + b } x ``` ``` 3 ``` Assign a new value to the variable: ```fql let x = "foo" let fn = () => x let x = "bar" let y = fn() [x, y] ``` ``` [ "bar", "foo" ] ``` Use a previous definition of the variable when redefining the variable: ```fql let x = 1 let x = x + 1 x ``` ``` 2 ``` Type a variable: ```fql let x: Int = 2 x ``` ``` 2 ``` Incorrectly typing a variable results in an error: ```fql let x: Int = "2" x ``` ``` invalid_query: The query failed 1 validation check error: Type `"2"` is not a subtype of `Int` at *query*:1:5 | 1 | let x: Int = "2" | ^ | cause: Type `String` is not a subtype of `Int` | 1 | let x: Int = "2" | ^^^ | ``` # Anonymous functions An anonymous function is a function that doesn’t have a name, and is typically used as an argument to another function. Functions are defined and managed using the [Function](../../fql-api/function/) API. ## [](#declaration-and-scope)Declaration and scope Fauna Query Language (FQL) uses the JavaScript-style short-form arrow syntax to declare an anonymous function. Function declaration has the generalized form: (\[param\[, param\]\]) => {\[statement\[ statement …​\] expression\]} The _param_ can be any valid [identifier](../variables/#identifier) including a single underscore (\_), which can be repeated in the _param_ list. An anonymous function block can include field access constructs, operators, function arguments, and nested blocks. Variables declared in an anonymous function block are scoped to the anonymous function, but the function can access the variables in the parent block. The last expression is the return value of the function. There is no explicit `return` keyword. ## [](#simplified-syntax)Simplified syntax For a function with one parameter, the `()` enclosing the parameter can be omitted. If the function body consists of a single-line expression, the `{}` block can also be omitted. These examples are equivalent and return a value of `6`: ```fql let Double = (x) => {x + x} Double(3) ``` ```fql let Double = x => x + x Double(3) ``` ## [](#predicates)Predicates A predicate is an anonymous, read-only FQL function that evaluates to `true`, `false`, or `null` (which is interpreted as `false`). It acts as a test to determine if one or more conditions are met. Some FQL methods and FSL schema properties accept predicates. For example, [`set.where()`](../../fql-api/set/where/) accepts a predicate as its argument: ```fql Customer.all().where(c => c.address.postalCode == "20220" && c.name == "Alice Appleseed") ``` ## [](#shorthand-syntax)Shorthand syntax Some contexts support a shorthand syntax that lets you omit the parameter name and arrow (`=>`). For example, the following query is equivalent to the previous one: ```fql Customer.all().where(.address.postalCode == "20220" && .name == "Alice Appleseed") ``` The syntax supports dot notation and bracket notation. The following query is equivalent to the previous one: ```fql Customer.all().where(.["address"]["postalCode"] == "20220" && .["name"] == "Alice Appleseed") ``` ## [](#variadic)Variadic arguments Use the `...` syntax to create a variadic function that accepts an indefinite number of arguments, including zero. ```fql let getLength = (...args) => args.length getLength(1, 2, 3) ``` ``` 3 ``` A function can only accept one variadic argument. It must be the last argument. Variadic arguments are collected into an [Array](../types/#array). You can define a type signature to limit the types of values accepted and held in the Array. For example, the following function accepts a single [String](../types/#string) argument followed by a variadic argument of zero or more [Number](../types/#number)s: ```fql let formatCurrency: (String, ...Number) => String = (symbol, ...amounts) => { symbol + amounts.reduce((prev, cur) => prev + cur).toString() } formatCurrency("$", 2, 3) ``` ``` "$5" ``` # Naming and aliasing This section covers guidelines for naming resources. ## [](#collision)Resolving document field name collisions The document metadata `id`, `coll`, and `ts` fields are reserved. If a document must use a reserved word as a field name, it can be nested in the document `data` field to avoid colliding with a reserved name. In the following example, the reserved word `id` is nested in the `data` field to avoid collision: ``` { id: "777", coll: Product, ts: Time("2099-06-25T21:16:36.610Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("789"), data: { id: "limes" } } ``` ## [](#global-namespace-prefix)Global namespace prefix The `FQL` prefix is reserved to disambiguate global Fauna schema entities and native API names from user-defined entities. For example, if you define a UDF named `log()`, you can access the built-in [`log()`](../../fql-api/globals/log/) method using the `FQL` prefix: ```fql FQL.log("hello world") ``` The `FQL` prefix isn’t required if user-defined names don’t conflict with the global Fauna names. ## [](#aliasing)Schema aliasing Collections and UDFs accept an _alias_ field that can then be used to reference a resource with a name that conflicts with a [reserved schema name](../reserved/#reserved-schema). By creating and using an alias, the resource doesn’t have to be renamed. This example shows how to use a schema alias to rename a Collection: ```fsl @alias(myLegacyCollection) collection "my-legacy-collection" { } ``` Using the _alias_ keyword to define an alias name allows you to refer to the aliased entity using the alias name in subsequent requests: ```fql MyLegacyCollection.firstWhere(.name < "Z") ``` If the original name doesn’t conflict with an existing name, the entity is available using its name or the alias. If the name does conflict, the entity is available only by the alias. ## [](#see-also)See also [Reserved words](../reserved/) # Projection and field aliasing Projection allows you to select the fields to be returned and is supported for [Struct](../types/#struct), [Array](../types/#array), [Set](../types/#set), and [Document](../types/#document) types. If you apply projection to a type that doesn’t support projection, the result is an object with the same shape as the projection request but all field values are set to `null`. If a requested field doesn’t exist in the projected object, the returned field value is set to `null`. Fields are returned in the order listed in the query. ## [](#struct-projection)Struct projection The result of projection on a [Struct](../types/#struct) returns a struct with only the requested fields extracted. ```fql let customer = { name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } } customer { name, email, address { street } } ``` ``` { name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St" } } ``` ## [](#array-projection)Array projection The result of projection on an Array is an Array with the projection applied to each element of the Array: ```fql let stores = [ { name: "DC Fruits", address: { street: "13 Pierstorff Drive", city: "Washington", state: "DC", zipCode: "20220" } }, { name: "Party Supplies", address: { street: "7529 Capitalsaurus Court", city: "Washington", state: "DC", zipCode: "20002" } }, { name: "Foggy Bottom Market", address: { street: "4 Florida Ave", city: "Washington", state: "DC", zipCode: "20037" } } ] stores { name } ``` ``` [ { name: "DC Fruits" }, { name: "Party Supplies" }, { name: "Foggy Bottom Market" } ] ``` ## [](#set)Set projection The result of projection on a [Set](../types/#set) is a new Set where the field selections are applied to each element in the original Set. The result type on a Set is a Set. For example: ```fql Category.all() { name } ``` ``` { data: [ { name: "party" }, { name: "frozen" }, { name: "produce" } ] } ``` You can also use the FQL [`set.map()`](../../fql-api/set/map/) method to project Sets. For example, the following projection query: ```fql Product.sortedByPriceLowToHigh() { name, description, price } ``` Is equivalent to the following [`set.map()`](../../fql-api/set/map/) query: ```fql Product.sortedByPriceLowToHigh().map(prod => { name: prod.name, description: prod.description, price: prod.price, }) ``` ## [](#document-projection)Document projection Applying projection to a document, the projected fields are extracted directly from the document. The value returned from projection on a document is a [Struct](../types/#struct). For example: ```fql Category.byName("produce").first() { name } ``` ``` { name: "produce" } ``` ## [](#traverse-document-references)Traverse document references You can use [document references](../../../learn/data-model/relationships/) to create relationships between documents. The reference acts as a pointer to a document. The reference contains the document’s collection and document ID. For example, the following query updates a `Product` collection document to add a `category` field. The `category` field contains a reference to a `Category` collection document. ```fql let produce = Category.byName("produce").first() Product.byName("limes").first() ?.update({ category: produce }) ``` ``` // An example `Product` collection document. { id: "777", coll: Product, ts: Time("2099-04-10T16:07:02.515Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, // A `Category` document reference. // The reference contains the document's // collection and document ID. category: Category("789") } ``` When the `category` field is projected, the reference is resolved and the full `Category` collection document is returned: ```fql // Gets a `Product` document and projects the // `name` and `category` fields. Product.byName("limes").first() { name, category} ``` ``` { name: "limes", // The projection resolves the `Category` document // reference in the `category` field. category: { id: "789", coll: Category, ts: Time("2099-07-30T22:17:39.945Z"), products: "hdW...", name: "produce", description: "Fresh Produce" } } ``` ## [](#traverse-set-references)Traverse Set references [Sets](../../../learn/data-model/sets/) are not [persistable](../types/#persistable). You can’t store a Set as a field value or create a [field definition](../../../learn/schema/#field-definitions) that accepts a Set. Instead, you can use a [computed field](../../fsl/computed/) to define a read-only function that dynamically fetches a Set: ```fsl collection Customer { ... // Computed field definition for the `orders` field. // `orders` contains a reference to a Set of `Order` collection documents. // The value is computed using the `Order` collection's // `byCustomer()` index to get the customer's orders. compute orders: Set = ( customer => Order.byCustomer(customer)) ... } ``` If the field isn’t [projected](./), it contains an [`after` pagination cursor](../../../learn/query/pagination/#cursor) that references the Set: ```fql // Get a `Customer` document. Customer.byEmail("alice.appleseed@example.com").first() ``` ``` { id: "111", coll: Customer, ts: Time("2099-10-22T21:56:31.260Z"), cart: Order("412483941752112205"), // `orders` contains an `after` cursor that // references the Set of `Order` documents. orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } } ``` To materialize the Set, [project](./) the computed field: ```fql let customer = Customer .where(.email == "alice.appleseed@example.com") .first() // Project the `name`, `email`, and `orders` fields. customer { name, email, orders } ``` ``` { name: "Alice Appleseed", email: "alice.appleseed@example.com", orders: { data: [ { id: "412483941752112205", coll: Order, ts: Time("2099-10-22T21:56:31.260Z"), items: "hdW...", total: 5392, status: "cart", customer: Customer("111"), createdAt: Time("2099-10-22T21:56:31.104083Z"), payment: {} }, ... ] } } ``` Alternatively, you can pass the `after` cursor to [`Set.paginate()`](../../fql-api/set/static-paginate/): ```fql Set.paginate("hdW...", 2) ``` ``` { // Returns a materialized Set of `Order` documents. data: [ { id: "412483941752112205", coll: Order, ts: Time("2099-10-22T21:56:31.260Z"), items: "hdW...", total: 5392, status: "cart", customer: Customer("111"), createdAt: Time("2099-10-22T21:56:31.104083Z"), payment: {} }, ... ] } ``` ## [](#field-aliasing)Field aliasing Referencing fields can be simplified when working with projected fields, including nested fields, by defining an alias using [field accessors](../dot-notation/#field-accessor). A field alias gives you a shortcut for referencing fields and field combinations. Example projecting a nested field: 1. Given the following document: ```fql Customer.byEmail("alice.appleseed@example.com").first() ``` ``` { id: "111", coll: Customer, ts: Time("2099-06-25T12:14:29.440Z"), cart: Order("412653216549831168"), orders: "hdW...", name: 'Alice Appleseed', email: 'alice.appleseed@example.com', address: { street: '87856 Mendota Court', city: 'Washington', state: 'DC', postalCode: '20220', country: 'US' } } ``` 2. Define an alias using dot notation to get the value of the projected field: ```fql Customer.byEmail("alice.appleseed@example.com").first() { myCity: .address.city } ``` ``` { myCity: "Washington" } ``` Example projecting multiple fields: 1. Given the following document: ```fql Customer.byEmail("alice.appleseed@example.com").first() ``` ``` { id: "111", coll: Customer, ts: Time("2099-06-25T12:14:29.440Z"), cart: Order("412653216549831168"), orders: "hdW...", name: 'Alice Appleseed', email: 'alice.appleseed@example.com', address: { street: '87856 Mendota Court', city: 'Washington', state: 'DC', postalCode: '20220', country: 'US' } } ``` 2. Define an alias that references multiple fields to get the value of the projected field: ```fql Customer.byEmail("alice.appleseed@example.com").first() { cityState: .address.city + ", " + .address.state } ``` ``` { cityState: "Washington, DC" } ``` # Static typing FQL supports static typing of queries and user-defined functions. Static typing identifies potential query errors before execution by validating the query _shape_ before running the query to rule out runtime errors. FQL verifies that the query is correct for the kinds of values that it can accept and runs the query after type checking passes. Types are inferred by usage. After a type is determined, usage must be consistent. ## [](#types)Types A _type_ is the type of a [signature](#signatures) value and can be any of the following: | Type | Description | Syntax | Examples | | --- | --- | --- | --- | --- | --- | | named | A named type has a name. Types, such as Boolean or String, are named types. | name | See a partial list of named types. | | literal | A literal value has its own type. For example, 3 has the type 3. | literal value | 1, true, { a: 3 }, "foo" | | function | A function type doesn’t have a name. It has a list of arguments and a return type. For example, the function concat() has the type (other: string) => string. These types are used for anonymous functions. For example, the where() method accepts a function type as a parameter. | (arg_name: arg_type) => return_type | () => String, (start: Int, end: Int) => String | | union | A union represents an OR between any number of types. For example, if a function accepts an integer or a string, it accepts the type Int | String. | type1 | type2 | type3 | Int | String, Document | Null | | intersection | An intersection represents an AND between any number of types, combining multiple types into a single type. For example, the types { name: string } and { address: string } can be combined into a single { name: string, address: string } type by using the { name: string } & { address: string } notation. | type1 & type2 & type3 | Int & Number, { name: string } & { address: string } | The following is a partial list of named types. | Type | Example value | Notes | | --- | --- | --- | --- | --- | | Boolean | true, false | | | String | "hello world", "" | | | Number | 3, 9223372036854775807, 2.5 | | | Int | 3 | Int is a Number type. | | Long | 9223372036854775807 | Long is a Number type. | | Double | 2.5 | Double is a Number type. | | Array | [1, 2, "hi", true] | The type parameter A is the type of the values in the Array. | | Set | Collection.all() | The type parameter A is the type of the values in the Set. | | Time | Time.now() | | | Date | Date("2099-04-05") | | ## [](#generic)Generic types A _type_ can be a _concrete_ or _generic_ type. A _generic type_ is a type that has type parameters. A _type parameter_ is similar to a named type but isn’t known in a function signature and is, effectively, a placeholder type. The type parameter signature is a single capital letter in sequence, such as `A`, `B`, and `C`. These types resolve to a _concrete type_ after the value is used. For example, the elements in an Array have the type `A` in signatures because an array can store any type. The type parameter `A` resolves to a concrete type after the Array is constructed. ## [](#signatures)Signatures A _signature_ is the definition of a field or function in the static environment. FQL method signatures are a simplified form of TypeScript and can be in one of the two following formats: * Function signatures have the form name(arg\_name: arg\_type) => return\_type. For example, concat has the signature `concat(other: String) => String`. Function signatures are similar to function types, but include a name on the left. * Field signatures have the form name: type. For example, the field year on Date has the signature `year: Int`. _Type parameters_ act like placeholders in a signature. This means that `Array` isn’t a static type because it has a type parameter. When you construct an Array, for example, with the query `[1, 2]`, the concrete type of that Array is `Array<1 | 2>`, because the value of the Array is determined to have the type `1 | 2`. The type parameter `A` is then substituted on calling functions on that array. For example, the function `first()` on an Array has the signature `first() => A | Null`. This means that it returns a value that is the same type as the elements of the Array, `A`, or a null value. After `first()` is called, for example, in `[1, 2].first()`, the type `A` is resolved. In this case, `first()` has the concrete type `() => 1 | 2 | Null` because the type `A` resolves to `1 | 2`. Type parameters on functions are defined implicitly, in alphabetical order. For example, `dbg()` accepts a value and returns that same value. So, the signature is `dbg(value: A) => A`. The type parameter `A` is local to the `dbg()` function and is defined implicitly. The `dbg()` function is called a generic function because it has type parameters. ### [](#generic-type-signature)Generic type signature For types that include parameters, new type parameters start at `B`, followed by `C`, and continue. For example, `concat()` on Arrays has the signature `concat(other: Array) => Array`. The type parameter `A` is the type of the Array this is called on, and the type parameter `B` is a new type parameter local to this function. The type `Array` is a [generic type](#generic) because it has type parameters. ### [](#concrete-type-signature)Concrete type signature A concrete type is the type of a query value. Here are some examples: | Query value | Type signature | | --- | --- | --- | --- | | [1, 2] | Array<1 | 2> | | Collection.all() | Set | | Time.now | () ⇒ Time | | "hello".slice(2, 4) | String | | (num) ⇒ "hello".slice(num) | (num: Int) ⇒ String | ### [](#udf-signature)UDF signature The user-defined function (UDF) signature field can be used to define an explicitly typed signature for a UDF. For example, ```fsl function TypeTest(x: Number, y: Number): Number { x + y } ``` ## [](#enable-and-disable-type-checking)Enable and disable type checking | Scope | Property | Description | | --- | --- | --- | --- | --- | | Database | typechecked | Enable or disable type checking for the database:true = Enable type checking.false = (default) Disable type checking. | | Query | typecheck | Enable or disable type checking per query:true = Enable type checking.false = (default) Disable type checking. | If type checking is enabled for the driver or per query, type checking must also be enabled in the database. Setting the _typechecked_ property in the driver, query, or Dashboard overrides the database setting. Type checking is performed on user-defined function (UDF) definitions and can’t be disabled. If a UDF definition fails type checking it results in a `QueryRuntimeError`. This differs from the compile-time `TypeCheckError` returned by a query type error. Disabling type checking can reduce the query time, and the number of query check phase compute operations but can allow errors to present as runtime errors. ### [](#enable-database-type-checking)Enable database type checking Enabled type checking for a _child database_ by updating the database definition using the [`document.update()`](../../fql-api/document/update/) method: ```fql Database.byName( "childDB" )!.update( { typechecked: true } ) ``` Setting the `typecheck` property using the Dashboard, [driver](#enable-for-query), or [query](#enable-for-query) option overrides the database setting. ### [](#enable-for-query)Enable query type checking Drivers for the [supported languages](../../../build/drivers/) can be configured to enable type checking at two levels: * Enable type checking of all queries sent by the driver by setting the `typecheck` property to `true` in the driver client configuration. * Enable type checking per-query by setting the `typecheck` property to `true` in the query options field. # FQL API reference The API reference documentation gives you detailed syntactic information for working with FQL database entities. Querying, data manipulation, and other capabilities are exposed as APIs on top of the core syntax. This gives you an easy-to-learn language with a rich feature set that remains discoverable over time. Collections expose an ORM-like API for creating declarative queries, with composable methods for filtering, ordering, and transforming sets of documents as part of core FQL. The core API is enhanced with dedicated syntax to optimize the readability of predicates and projection/transformation. Working with documents is as simple as reading fields off objects. FQL support for first-class foreign keys simplifies them by dereferencing documents through associated fields. For example, if a book document has an author stored in an `author` field, the author document is retrieved transparently through field access. FQL includes a powerful indexing system that enables an iterative approach to developer-driven query optimization. These capabilities mean that it is easy to build sophisticated join-like queries that remain easy to work with as they scale in complexity, and queries can be tailored to return the exact data the application requires. By convention, the method and field signatures described in this reference have the following notation conventions. Method signature: ```fql-sig ([: [, ...]]) => ``` Field signature: ```fql-sig : ``` For more information on typing, see: [Types](../fql/types/) [Static typing](../fql/static-typing/) # FQL cheat sheet This page provides a quick reference of FQL properties and methods, grouped by functionality. | Access providerAccessProvider.all()Get a Set of all access providers.AccessProvider.byName()Get an access provider by its name.AccessProvider.create()Create an access provider.AccessProvider.firstWhere()Get the first access provider that matches a provided predicate.AccessProvider.toString()Get "AccessProvider" as a String.AccessProvider.where()Get a Set of access providers that match a provided predicate.accessProvider.delete()Delete an access provider.accessProvider.exists()Test if an access provider exists.accessProvider.replace()Replace an access provider.accessProvider.update()Update an access provider.ArrayArray.sequence()Create an ordered Array of Numbers given start and end values.array.lengthThe number of elements in the Array.array.aggregate()Aggregate all elements of an Array.array.any()Test if any element of an Array matches a provided predicate.array.append()Append a provided element to an Array.array.at()Get the Array element at a provided index.array.concat()Concatenate two Arrays.array.distinct()Get the unique elements of an Array.array.drop()Drop the first N elements of an Array.array.entries()Add the index to each element of an Array.array.every()Test if every element of an Array matches a provided predicate.array.filter()Filter an Array using a provided predicate.array.first()Get the first element of an Array.array.firstWhere()Get the first element of an Array that matches a provided predicate.array.flatMap()Apply a provided function to each Array element and flatten the resulting Array by one level.array.flatten()Flatten an Array by one level.array.fold()Reduce the Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value.array.foldRight()Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value.array.forEach()Run a provided function on each element of an Array. Can perform writes.array.includes()Test if the Array includes a provided element.array.indexOf()Get the index of the first Array element that matches a provided value.array.indexWhere()Get the index of the first Array element that matches a provided predicate.array.isEmpty()Test if an Array is empty.array.last()Get the last element of an Array.array.lastIndexOf()Get the index of the last Array element that matches a provided value.array.lastIndexWhere()Get the index of the last Array element that matches a provided predicate.array.lastWhere()Get the last element of an Array that matches a provided predicate.array.map()Apply a provided function to each element of an Array. Can’t perform writes.array.nonEmpty()Test if an Array is not empty.array.order()Sort an Array's elements.array.prepend()Prepend an element to an Array.array.reduce()Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value.array.reduceRight()Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value.array.reverse()Reverse the order of an Array's elements.array.slice()Get a subset of an Array's elements based on provided indexes.array.take()Get the first N elements of an Array.array.toSet()Convert an Array to a Set.array.toString()Convert an Array to a String.array.where()Get the elements of an Array that match a provided predicate.Collectioncollection.definitionGet a collection definition, represented as a Collection document with the CollectionDef type.Collection()Access a collection by its name.Collection.all()Get a Set of all collection definitions.Collection.byName()Get a collection definitions by its name.Collection.create()Create a collection.Collection.firstWhere()Get the first collection definition that matches a provided predicate.Collection.toString()Get "Collection" as a String.Collection.where()Get a Set of collection definitions that match a provided predicate.collectionDef.delete()Delete a collection.collectionDef.exists()Test if a collection exists.collectionDef.replace()Replaces a collection definition.collectionDef.update()Update a collection definition.collection.all()Get a Set of all documents in a collection.collection.byId()Get a collection document by its document id.collection.create()Create a collection document.collection.firstWhere()Get the first collection document that matches a provided predicate.collection.indexName()Call an index as a method to get a Set of matching collection documents.collection.where()Get a Set of collection documents that match a provided predicate.CredentialCredential.all()Get a Set of all credentials.Credential.byDocument()Get a credential by its identity document.Credential.byId()Get a credential by its document id.Credential.create()Create a credential.Credential.firstWhere()Get the first credential that matches a provided predicate.Credential.toString()Get "Credential" as a String.Credential.where()Get a Set of credentials that match a provided predicate.credential.delete()Delete a credential.credential.exists()Test if a credential exists.credential.login()Create a token for a provided credential and its password.credential.replace()Replace a credential.credential.update()Update a credential.credential.verify()Test whether a provided password is valid for a credential.DatabaseDatabase.all()Get a Set of all child databases nested directly under the database.Database.byName()Get a child database by its name.Database.create()Create a child database.Database.firstWhere()Get the first child database document that matches a provided predicate.Database.toString()Get "Database" as a String.Database.where()Get a Set of child databases that match a provided predicate.database.delete()Deletes a child database.database.exists()Test if a child database exists.database.replace()Replace a child database's metadata and settings.database.update()Update a child database's metadata and settings.DatedayOfMonthGet the day of the month from a Date.dayOfWeekGet the day of the week from a Date.dayOfYearGet the day of the year from a Date.monthGet the month of a Date.yearGet the year of a Date.Date()Construct a Date from a ISO 8601 date String.Date.fromString()Construct a Date from a date String.Date.today()Get the current UTC Date.date.add()Add number of days to a Date.date.difference()Get the difference between two Dates.date.subtract()Subtract number of days from a Date.date.toString()Convert a Date to a String.Documentdocument.delete()Delete a collection document.document.exists()Test if a collection document exists.document.replace()Replace all fields in a collection document.document.update()Update a collection document's fields.EventSourceeventSource.map()Apply an anonymous function to each element of an event source's tracked Set.eventSource.toString()Get "[event source]" as a string.eventSource.where()Create an event source that emits events for a subset of another event source’s tracked Set.Functionfunction.definitionGet or update a user-defined function (UDF)'s definition, represented as a Function document.Function()Call a user-defined function (UDF) by its name.Function.all()Get a Set of all user-defined functions (UDFs).Function.byName()Get a user-defined function (UDF) by its name.Function.create()Create a user-defined function (UDF).Function.firstWhere()Get the first user-defined function (UDF) that matches a provided predicate.Function.toString()Get "Function" as a String.Function.where()Get a Set of user-defined functions (UDFs) that match a provided predicate.functionDef.delete()Delete a user-defined function (UDF).functionDef.exists()Test if a user-defined function (UDF) exists.functionDef.replace()Replace a user-defined function (UDF).functionDef.update()Update a user-defined function (UDF).Global functionsabort()End the current query and return an abort error with a user-defined abort value.dbg()Output a debug message in the query summary and return the message in the query results.ID()Create a valid IDlog()Output a log message in the query summary and return null.newId()Get a unique string-encoded 64-bit integer.KeyKey.all()Get a Set of all keys.Key.byId()Get a key by its document id.Key.create()Create a key.Key.firstWhere()Get the first key that matches a provided predicate.Key.toString()Get "Key" as a String.Key.where()Get a Set of keys that match a provided predicate.key.delete()Delete a key.key.exists()Test if a key exists.key.replace()Replace a key.key.update()Update a key. | AccessProvider.all() | Get a Set of all access providers. | AccessProvider.byName() | Get an access provider by its name. | AccessProvider.create() | Create an access provider. | AccessProvider.firstWhere() | Get the first access provider that matches a provided predicate. | AccessProvider.toString() | Get "AccessProvider" as a String. | AccessProvider.where() | Get a Set of access providers that match a provided predicate. | accessProvider.delete() | Delete an access provider. | accessProvider.exists() | Test if an access provider exists. | accessProvider.replace() | Replace an access provider. | accessProvider.update() | Update an access provider. | Array.sequence() | Create an ordered Array of Numbers given start and end values. | array.length | The number of elements in the Array. | array.aggregate() | Aggregate all elements of an Array. | array.any() | Test if any element of an Array matches a provided predicate. | array.append() | Append a provided element to an Array. | array.at() | Get the Array element at a provided index. | array.concat() | Concatenate two Arrays. | array.distinct() | Get the unique elements of an Array. | array.drop() | Drop the first N elements of an Array. | array.entries() | Add the index to each element of an Array. | array.every() | Test if every element of an Array matches a provided predicate. | array.filter() | Filter an Array using a provided predicate. | array.first() | Get the first element of an Array. | array.firstWhere() | Get the first element of an Array that matches a provided predicate. | array.flatMap() | Apply a provided function to each Array element and flatten the resulting Array by one level. | array.flatten() | Flatten an Array by one level. | array.fold() | Reduce the Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | array.foldRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | array.forEach() | Run a provided function on each element of an Array. Can perform writes. | array.includes() | Test if the Array includes a provided element. | array.indexOf() | Get the index of the first Array element that matches a provided value. | array.indexWhere() | Get the index of the first Array element that matches a provided predicate. | array.isEmpty() | Test if an Array is empty. | array.last() | Get the last element of an Array. | array.lastIndexOf() | Get the index of the last Array element that matches a provided value. | array.lastIndexWhere() | Get the index of the last Array element that matches a provided predicate. | array.lastWhere() | Get the last element of an Array that matches a provided predicate. | array.map() | Apply a provided function to each element of an Array. Can’t perform writes. | array.nonEmpty() | Test if an Array is not empty. | array.order() | Sort an Array's elements. | array.prepend() | Prepend an element to an Array. | array.reduce() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | array.reduceRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | array.reverse() | Reverse the order of an Array's elements. | array.slice() | Get a subset of an Array's elements based on provided indexes. | array.take() | Get the first N elements of an Array. | array.toSet() | Convert an Array to a Set. | array.toString() | Convert an Array to a String. | array.where() | Get the elements of an Array that match a provided predicate. | collection.definition | Get a collection definition, represented as a Collection document with the CollectionDef type. | Collection() | Access a collection by its name. | Collection.all() | Get a Set of all collection definitions. | Collection.byName() | Get a collection definitions by its name. | Collection.create() | Create a collection. | Collection.firstWhere() | Get the first collection definition that matches a provided predicate. | Collection.toString() | Get "Collection" as a String. | Collection.where() | Get a Set of collection definitions that match a provided predicate. | collectionDef.delete() | Delete a collection. | collectionDef.exists() | Test if a collection exists. | collectionDef.replace() | Replaces a collection definition. | collectionDef.update() | Update a collection definition. | collection.all() | Get a Set of all documents in a collection. | collection.byId() | Get a collection document by its document id. | collection.create() | Create a collection document. | collection.firstWhere() | Get the first collection document that matches a provided predicate. | collection.indexName() | Call an index as a method to get a Set of matching collection documents. | collection.where() | Get a Set of collection documents that match a provided predicate. | Credential.all() | Get a Set of all credentials. | Credential.byDocument() | Get a credential by its identity document. | Credential.byId() | Get a credential by its document id. | Credential.create() | Create a credential. | Credential.firstWhere() | Get the first credential that matches a provided predicate. | Credential.toString() | Get "Credential" as a String. | Credential.where() | Get a Set of credentials that match a provided predicate. | credential.delete() | Delete a credential. | credential.exists() | Test if a credential exists. | credential.login() | Create a token for a provided credential and its password. | credential.replace() | Replace a credential. | credential.update() | Update a credential. | credential.verify() | Test whether a provided password is valid for a credential. | Database.all() | Get a Set of all child databases nested directly under the database. | Database.byName() | Get a child database by its name. | Database.create() | Create a child database. | Database.firstWhere() | Get the first child database document that matches a provided predicate. | Database.toString() | Get "Database" as a String. | Database.where() | Get a Set of child databases that match a provided predicate. | database.delete() | Deletes a child database. | database.exists() | Test if a child database exists. | database.replace() | Replace a child database's metadata and settings. | database.update() | Update a child database's metadata and settings. | dayOfMonth | Get the day of the month from a Date. | dayOfWeek | Get the day of the week from a Date. | dayOfYear | Get the day of the year from a Date. | month | Get the month of a Date. | year | Get the year of a Date. | Date() | Construct a Date from a ISO 8601 date String. | Date.fromString() | Construct a Date from a date String. | Date.today() | Get the current UTC Date. | date.add() | Add number of days to a Date. | date.difference() | Get the difference between two Dates. | date.subtract() | Subtract number of days from a Date. | date.toString() | Convert a Date to a String. | document.delete() | Delete a collection document. | document.exists() | Test if a collection document exists. | document.replace() | Replace all fields in a collection document. | document.update() | Update a collection document's fields. | eventSource.map() | Apply an anonymous function to each element of an event source's tracked Set. | eventSource.toString() | Get "[event source]" as a string. | eventSource.where() | Create an event source that emits events for a subset of another event source’s tracked Set. | function.definition | Get or update a user-defined function (UDF)'s definition, represented as a Function document. | Function() | Call a user-defined function (UDF) by its name. | Function.all() | Get a Set of all user-defined functions (UDFs). | Function.byName() | Get a user-defined function (UDF) by its name. | Function.create() | Create a user-defined function (UDF). | Function.firstWhere() | Get the first user-defined function (UDF) that matches a provided predicate. | Function.toString() | Get "Function" as a String. | Function.where() | Get a Set of user-defined functions (UDFs) that match a provided predicate. | functionDef.delete() | Delete a user-defined function (UDF). | functionDef.exists() | Test if a user-defined function (UDF) exists. | functionDef.replace() | Replace a user-defined function (UDF). | functionDef.update() | Update a user-defined function (UDF). | abort() | End the current query and return an abort error with a user-defined abort value. | dbg() | Output a debug message in the query summary and return the message in the query results. | ID() | Create a valid ID | log() | Output a log message in the query summary and return null. | newId() | Get a unique string-encoded 64-bit integer. | Key.all() | Get a Set of all keys. | Key.byId() | Get a key by its document id. | Key.create() | Create a key. | Key.firstWhere() | Get the first key that matches a provided predicate. | Key.toString() | Get "Key" as a String. | Key.where() | Get a Set of keys that match a provided predicate. | key.delete() | Delete a key. | key.exists() | Test if a key exists. | key.replace() | Replace a key. | key.update() | Update a key. | MathMath.EGet the Euler’s number mathematical constant (℮).Math.InfinityString value representing infinity.Math.NaNValue representing Not-a-Number.Math.PIGet the mathematical constant pi (π).Math.abs()Get the absolute value of a Number.Math.acos()Get the inverse cosine in radians of a Number.Math.asin()Get the inverse sine in radians of a Number.Math.atan()Get the inverse tangent in radians of a Number.Math.ceil()Round up a Number.Math.cos()Get the cosine of a Number in radians.Math.cosh()Get the hyperbolic cosine of a Number.Math.degrees()Convert radians to degrees.Math.exp()Get the value of ℮ raised to the power of a Number.Math.floor()Round down a Number.Math.hypot()Get the hypotenuse of a right triangle.Math.log()Get the natural logarithm, base e, of a Number.Math.log10()Get the base 10 logarithm of a Number.Math.max()Get the larger of two Numbers.Math.mean()Get the arithmetic mean of an Array or Set of Numbers.Math.min()Get the smaller of the input parameter Numbers.Math.pow()Get the value of a base raised to a power.Math.radians()Convert the value of a Number in degrees to radians.Math.round()Get the value of a Number rounded to the nearest integer.Math.sign()Get the sign of a Number.Math.sin()Get the sine of a Number in radians.Math.sinh()Get the hyperbolic sine of a Number.Math.sqrt()Get the square root of a Number.Math.sum()Get the sum of an Array or Set of Numbers.Math.tan()Get the tangent of a Number in radians.Math.tanh()Get the hyperbolic tangent of a Number.Math.trunc()Truncate a Number to a given precision.ObjectObject.assign()Copies properties from a source Object to a destination Object.Object.entries()Convert an Object to an Array of key-value pairs.Object.fromEntries()Convert an Array of key-value pairs to an Object.Object.hasPath()Test if an Object has a property.Object.keys()Get an Object's top-level property keys as an Array.Object.select()Get an Object property’s value by its path.Object.toString()Convert an Object to a String.Object.values()Get an Object's property values as an Array.QueryQuery.identity()Get the identity document for the query’s authentication token.Query.isEnvProtected()Test if the queried database is in protected mode.Query.isEnvTypechecked()Test if the queried database is typechecked.Query.token()Get the Token document or JWT payload for the query’s authentication secret.RoleRole.all()Get a Set of all user-defined roles.Role.byName()Get a user-defined role by its name.Role.create()Create a user-defined role.Role.firstWhere()Get the first user-defined role matching a provided predicate.Role.toString()Get "Role" as a String.Role.where()Get a Set of user-defined roles that match a provided predicate.role.delete()Delete a user-defined role.role.exists()Test if a user-defined role exists.role.replace()Replace a user-defined role.role.update()Update a user-defined role.SchemaFQL.Schema.defForIdentifier()Returns the definition for a user-defined collection or user-defined function (UDF) using the same rules as top-level identifier lookups.SetSet.paginate()Get a page of paginated results using an after cursor.Set.sequence()Create an ordered Set of Numbers given start and end values.Set.single()Create a Set containing a single provided element.set.aggregate()Aggregate all elements of a Set.set.any()Test if any element of a Set matches a provided predicate.set.changesOn()Create an event source that tracks changes to specified document fields in a supported Set.set.concat()Concatenate two Sets.set.count()Get the number of elements in a Set.set.distinct()Get the unique elements of a Set.set.drop()Drop the first N elements of a Set.set.eventsOn()Create an event source that tracks changes to specified document fields in a supported Set.set.eventSource()Create an event source that tracks changes to documents in a supported Set.set.every()Test if every element of a Set matches a provided predicate.set.first()Get the first element of a Set.set.firstWhere()Get the first element of a Set that matches a provided predicate.set.flatMap()Apply a provided function to each Set element and flatten the resulting Set by one level.set.fold()Reduce the Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value.set.foldRight()Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value.set.forEach()Run a provided function on each element of a Set. Can perform writes.set.includes()Test if the Set includes a provided element.set.isEmpty()Test if a Set is empty.set.last()Get the last element of a Set.set.lastWhere()Get the last element of a Set that matches a provided predicate.set.map()Apply a provided function to each element of a Set. Can’t perform writes.set.nonEmpty()Test if a Set is not empty.set.order()Sort a Set's elements.set.pageSize()Set the maximum elements per page in paginated results.set.paginate()Convert a Set to an Object with pagination.set.reduce()Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value.set.reduceRight()Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value.set.reverse()Reverse the order of a Set's elements.set.take()Get the first N elements of a Set.set.toArray()Convert a Set to an Array.set.toStream()Create an event source that tracks changes to documents in a supported Set.set.toString()Return the string "[set]".set.where()Get the elements of a Set that match a provided predicate.Stringstring.lengthGet a String's length.string.at()Get the character at a specified index of a String.string.casefold()Convert a String to lower case using a specified format.string.concat()Concatenate two Strings.string.endsWith()Test if a String ends with a provided suffix.string.includes()Test if a String includes a provided substring.string.includesRegex()Test if a String contains a substring that matches a provided regular expression.string.indexOf()Get the index of the first matching substring within a String.string.indexOfRegex()Get the index of the first substring matching a provided regular expression within a String.string.insert()Insert a substring into a String at a specified index.string.lastIndexOf()Get the index of the last matching substring within a String.string.matches()Get the substrings in a String that match a provided regular expression.string.matchIndexes()Get the indexes and substrings in a String that match a provided regular expression.string.parseDouble()Convert a String to a Double.string.parseInt()Convert a String to a Int.string.parseLong()Convert a String to a Long.string.parseNumber()Convert a String to a Number.string.replace()Replace a specified number of occurrences of a substring in a String.string.replaceAll()Replace all occurrences of a substring in a String.string.replaceAllRegex()Replace all occurrences of substrings matching a regular expression in a String.string.replaceRegex()Replace a specified number of occurrences of substrings matching a regular expression in a String.string.slice()Get the substring between two indexes of a String.string.split()Split a String at a provided separator.string.splitAt()Split a String at a provided index.string.splitRegex()Split a String using a provided regular expression.string.startsWith()Test if a String starts with a provided prefix.string.toLowerCase()Convert a String to lower case.string.toString()Get a String representation of the value.string.toUpperCase()Convert a String to upper case.TimedayOfMonthGet the day of the month from a Time.dayOfWeekGet the day of the week from a Time.dayOfYearGet the day of the year from a Time.hourGet the hour of a Time.minuteGet the minute of a Time.monthGet the month of a Time.secondGet the second of a Time.yearGet the year of a Time.Time()Construct a Time from an ISO 8601 timestamp String.Time.epoch()Convert a Unix epoch timestamp to a Time.Time.fromString()Construct a Time from an ISO 8601 timestamp String.Time.now()Get the current UTC Time.time.add()Add a time interval to a Time.time.difference()Get the difference between two Times.time.subtract()Subtract a time interval from a Time.time.toMicros()Convert a Time to a Unix epoch timestamp in microseconds.time.toMillis()Convert a Time to a Unix epoch timestamp in milliseconds.time.toSeconds()Convert a Time to a Unix epoch timestamp in seconds.time.toString()Convert a Time to a String.TokenToken.all()Get a Set of all tokens.Token.byDocument()Get a token by its identity document.Token.byId()Get a token by its document id.Token.create()Create a token without a credential or related password.Token.firstWhere()Get the first token that matches a provided predicate.Token.toString()Get "Token" as a String.Token.where()Get a Set of tokens that match a provided predicate.token.delete()Delete a token.token.exists()Test if a token exists.token.replace()Replace a token.token.update()Update a token.Transaction TimeTransactionTime()Get the query transaction time.TransactionTime.toString()Get "[transaction time]" as a String. | Math.E | Get the Euler’s number mathematical constant (℮). | Math.Infinity | String value representing infinity. | Math.NaN | Value representing Not-a-Number. | Math.PI | Get the mathematical constant pi (π). | Math.abs() | Get the absolute value of a Number. | Math.acos() | Get the inverse cosine in radians of a Number. | Math.asin() | Get the inverse sine in radians of a Number. | Math.atan() | Get the inverse tangent in radians of a Number. | Math.ceil() | Round up a Number. | Math.cos() | Get the cosine of a Number in radians. | Math.cosh() | Get the hyperbolic cosine of a Number. | Math.degrees() | Convert radians to degrees. | Math.exp() | Get the value of ℮ raised to the power of a Number. | Math.floor() | Round down a Number. | Math.hypot() | Get the hypotenuse of a right triangle. | Math.log() | Get the natural logarithm, base e, of a Number. | Math.log10() | Get the base 10 logarithm of a Number. | Math.max() | Get the larger of two Numbers. | Math.mean() | Get the arithmetic mean of an Array or Set of Numbers. | Math.min() | Get the smaller of the input parameter Numbers. | Math.pow() | Get the value of a base raised to a power. | Math.radians() | Convert the value of a Number in degrees to radians. | Math.round() | Get the value of a Number rounded to the nearest integer. | Math.sign() | Get the sign of a Number. | Math.sin() | Get the sine of a Number in radians. | Math.sinh() | Get the hyperbolic sine of a Number. | Math.sqrt() | Get the square root of a Number. | Math.sum() | Get the sum of an Array or Set of Numbers. | Math.tan() | Get the tangent of a Number in radians. | Math.tanh() | Get the hyperbolic tangent of a Number. | Math.trunc() | Truncate a Number to a given precision. | Object.assign() | Copies properties from a source Object to a destination Object. | Object.entries() | Convert an Object to an Array of key-value pairs. | Object.fromEntries() | Convert an Array of key-value pairs to an Object. | Object.hasPath() | Test if an Object has a property. | Object.keys() | Get an Object's top-level property keys as an Array. | Object.select() | Get an Object property’s value by its path. | Object.toString() | Convert an Object to a String. | Object.values() | Get an Object's property values as an Array. | Query.identity() | Get the identity document for the query’s authentication token. | Query.isEnvProtected() | Test if the queried database is in protected mode. | Query.isEnvTypechecked() | Test if the queried database is typechecked. | Query.token() | Get the Token document or JWT payload for the query’s authentication secret. | Role.all() | Get a Set of all user-defined roles. | Role.byName() | Get a user-defined role by its name. | Role.create() | Create a user-defined role. | Role.firstWhere() | Get the first user-defined role matching a provided predicate. | Role.toString() | Get "Role" as a String. | Role.where() | Get a Set of user-defined roles that match a provided predicate. | role.delete() | Delete a user-defined role. | role.exists() | Test if a user-defined role exists. | role.replace() | Replace a user-defined role. | role.update() | Update a user-defined role. | FQL.Schema.defForIdentifier() | Returns the definition for a user-defined collection or user-defined function (UDF) using the same rules as top-level identifier lookups. | Set.paginate() | Get a page of paginated results using an after cursor. | Set.sequence() | Create an ordered Set of Numbers given start and end values. | Set.single() | Create a Set containing a single provided element. | set.aggregate() | Aggregate all elements of a Set. | set.any() | Test if any element of a Set matches a provided predicate. | set.changesOn() | Create an event source that tracks changes to specified document fields in a supported Set. | set.concat() | Concatenate two Sets. | set.count() | Get the number of elements in a Set. | set.distinct() | Get the unique elements of a Set. | set.drop() | Drop the first N elements of a Set. | set.eventsOn() | Create an event source that tracks changes to specified document fields in a supported Set. | set.eventSource() | Create an event source that tracks changes to documents in a supported Set. | set.every() | Test if every element of a Set matches a provided predicate. | set.first() | Get the first element of a Set. | set.firstWhere() | Get the first element of a Set that matches a provided predicate. | set.flatMap() | Apply a provided function to each Set element and flatten the resulting Set by one level. | set.fold() | Reduce the Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | set.foldRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | set.forEach() | Run a provided function on each element of a Set. Can perform writes. | set.includes() | Test if the Set includes a provided element. | set.isEmpty() | Test if a Set is empty. | set.last() | Get the last element of a Set. | set.lastWhere() | Get the last element of a Set that matches a provided predicate. | set.map() | Apply a provided function to each element of a Set. Can’t perform writes. | set.nonEmpty() | Test if a Set is not empty. | set.order() | Sort a Set's elements. | set.pageSize() | Set the maximum elements per page in paginated results. | set.paginate() | Convert a Set to an Object with pagination. | set.reduce() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | set.reduceRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | set.reverse() | Reverse the order of a Set's elements. | set.take() | Get the first N elements of a Set. | set.toArray() | Convert a Set to an Array. | set.toStream() | Create an event source that tracks changes to documents in a supported Set. | set.toString() | Return the string "[set]". | set.where() | Get the elements of a Set that match a provided predicate. | string.length | Get a String's length. | string.at() | Get the character at a specified index of a String. | string.casefold() | Convert a String to lower case using a specified format. | string.concat() | Concatenate two Strings. | string.endsWith() | Test if a String ends with a provided suffix. | string.includes() | Test if a String includes a provided substring. | string.includesRegex() | Test if a String contains a substring that matches a provided regular expression. | string.indexOf() | Get the index of the first matching substring within a String. | string.indexOfRegex() | Get the index of the first substring matching a provided regular expression within a String. | string.insert() | Insert a substring into a String at a specified index. | string.lastIndexOf() | Get the index of the last matching substring within a String. | string.matches() | Get the substrings in a String that match a provided regular expression. | string.matchIndexes() | Get the indexes and substrings in a String that match a provided regular expression. | string.parseDouble() | Convert a String to a Double. | string.parseInt() | Convert a String to a Int. | string.parseLong() | Convert a String to a Long. | string.parseNumber() | Convert a String to a Number. | string.replace() | Replace a specified number of occurrences of a substring in a String. | string.replaceAll() | Replace all occurrences of a substring in a String. | string.replaceAllRegex() | Replace all occurrences of substrings matching a regular expression in a String. | string.replaceRegex() | Replace a specified number of occurrences of substrings matching a regular expression in a String. | string.slice() | Get the substring between two indexes of a String. | string.split() | Split a String at a provided separator. | string.splitAt() | Split a String at a provided index. | string.splitRegex() | Split a String using a provided regular expression. | string.startsWith() | Test if a String starts with a provided prefix. | string.toLowerCase() | Convert a String to lower case. | string.toString() | Get a String representation of the value. | string.toUpperCase() | Convert a String to upper case. | dayOfMonth | Get the day of the month from a Time. | dayOfWeek | Get the day of the week from a Time. | dayOfYear | Get the day of the year from a Time. | hour | Get the hour of a Time. | minute | Get the minute of a Time. | month | Get the month of a Time. | second | Get the second of a Time. | year | Get the year of a Time. | Time() | Construct a Time from an ISO 8601 timestamp String. | Time.epoch() | Convert a Unix epoch timestamp to a Time. | Time.fromString() | Construct a Time from an ISO 8601 timestamp String. | Time.now() | Get the current UTC Time. | time.add() | Add a time interval to a Time. | time.difference() | Get the difference between two Times. | time.subtract() | Subtract a time interval from a Time. | time.toMicros() | Convert a Time to a Unix epoch timestamp in microseconds. | time.toMillis() | Convert a Time to a Unix epoch timestamp in milliseconds. | time.toSeconds() | Convert a Time to a Unix epoch timestamp in seconds. | time.toString() | Convert a Time to a String. | Token.all() | Get a Set of all tokens. | Token.byDocument() | Get a token by its identity document. | Token.byId() | Get a token by its document id. | Token.create() | Create a token without a credential or related password. | Token.firstWhere() | Get the first token that matches a provided predicate. | Token.toString() | Get "Token" as a String. | Token.where() | Get a Set of tokens that match a provided predicate. | token.delete() | Delete a token. | token.exists() | Test if a token exists. | token.replace() | Replace a token. | token.update() | Update a token. | TransactionTime() | Get the query transaction time. | TransactionTime.toString() | Get "[transaction time]" as a String. | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | AccessProvider.all() | Get a Set of all access providers. | | AccessProvider.byName() | Get an access provider by its name. | | AccessProvider.create() | Create an access provider. | | AccessProvider.firstWhere() | Get the first access provider that matches a provided predicate. | | AccessProvider.toString() | Get "AccessProvider" as a String. | | AccessProvider.where() | Get a Set of access providers that match a provided predicate. | | accessProvider.delete() | Delete an access provider. | | accessProvider.exists() | Test if an access provider exists. | | accessProvider.replace() | Replace an access provider. | | accessProvider.update() | Update an access provider. | | Array.sequence() | Create an ordered Array of Numbers given start and end values. | | array.length | The number of elements in the Array. | | array.aggregate() | Aggregate all elements of an Array. | | array.any() | Test if any element of an Array matches a provided predicate. | | array.append() | Append a provided element to an Array. | | array.at() | Get the Array element at a provided index. | | array.concat() | Concatenate two Arrays. | | array.distinct() | Get the unique elements of an Array. | | array.drop() | Drop the first N elements of an Array. | | array.entries() | Add the index to each element of an Array. | | array.every() | Test if every element of an Array matches a provided predicate. | | array.filter() | Filter an Array using a provided predicate. | | array.first() | Get the first element of an Array. | | array.firstWhere() | Get the first element of an Array that matches a provided predicate. | | array.flatMap() | Apply a provided function to each Array element and flatten the resulting Array by one level. | | array.flatten() | Flatten an Array by one level. | | array.fold() | Reduce the Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | | array.foldRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | | array.forEach() | Run a provided function on each element of an Array. Can perform writes. | | array.includes() | Test if the Array includes a provided element. | | array.indexOf() | Get the index of the first Array element that matches a provided value. | | array.indexWhere() | Get the index of the first Array element that matches a provided predicate. | | array.isEmpty() | Test if an Array is empty. | | array.last() | Get the last element of an Array. | | array.lastIndexOf() | Get the index of the last Array element that matches a provided value. | | array.lastIndexWhere() | Get the index of the last Array element that matches a provided predicate. | | array.lastWhere() | Get the last element of an Array that matches a provided predicate. | | array.map() | Apply a provided function to each element of an Array. Can’t perform writes. | | array.nonEmpty() | Test if an Array is not empty. | | array.order() | Sort an Array's elements. | | array.prepend() | Prepend an element to an Array. | | array.reduce() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | | array.reduceRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | | array.reverse() | Reverse the order of an Array's elements. | | array.slice() | Get a subset of an Array's elements based on provided indexes. | | array.take() | Get the first N elements of an Array. | | array.toSet() | Convert an Array to a Set. | | array.toString() | Convert an Array to a String. | | array.where() | Get the elements of an Array that match a provided predicate. | | collection.definition | Get a collection definition, represented as a Collection document with the CollectionDef type. | | Collection() | Access a collection by its name. | | Collection.all() | Get a Set of all collection definitions. | | Collection.byName() | Get a collection definitions by its name. | | Collection.create() | Create a collection. | | Collection.firstWhere() | Get the first collection definition that matches a provided predicate. | | Collection.toString() | Get "Collection" as a String. | | Collection.where() | Get a Set of collection definitions that match a provided predicate. | | collectionDef.delete() | Delete a collection. | | collectionDef.exists() | Test if a collection exists. | | collectionDef.replace() | Replaces a collection definition. | | collectionDef.update() | Update a collection definition. | | collection.all() | Get a Set of all documents in a collection. | | collection.byId() | Get a collection document by its document id. | | collection.create() | Create a collection document. | | collection.firstWhere() | Get the first collection document that matches a provided predicate. | | collection.indexName() | Call an index as a method to get a Set of matching collection documents. | | collection.where() | Get a Set of collection documents that match a provided predicate. | | Credential.all() | Get a Set of all credentials. | | Credential.byDocument() | Get a credential by its identity document. | | Credential.byId() | Get a credential by its document id. | | Credential.create() | Create a credential. | | Credential.firstWhere() | Get the first credential that matches a provided predicate. | | Credential.toString() | Get "Credential" as a String. | | Credential.where() | Get a Set of credentials that match a provided predicate. | | credential.delete() | Delete a credential. | | credential.exists() | Test if a credential exists. | | credential.login() | Create a token for a provided credential and its password. | | credential.replace() | Replace a credential. | | credential.update() | Update a credential. | | credential.verify() | Test whether a provided password is valid for a credential. | | Database.all() | Get a Set of all child databases nested directly under the database. | | Database.byName() | Get a child database by its name. | | Database.create() | Create a child database. | | Database.firstWhere() | Get the first child database document that matches a provided predicate. | | Database.toString() | Get "Database" as a String. | | Database.where() | Get a Set of child databases that match a provided predicate. | | database.delete() | Deletes a child database. | | database.exists() | Test if a child database exists. | | database.replace() | Replace a child database's metadata and settings. | | database.update() | Update a child database's metadata and settings. | | dayOfMonth | Get the day of the month from a Date. | | dayOfWeek | Get the day of the week from a Date. | | dayOfYear | Get the day of the year from a Date. | | month | Get the month of a Date. | | year | Get the year of a Date. | | Date() | Construct a Date from a ISO 8601 date String. | | Date.fromString() | Construct a Date from a date String. | | Date.today() | Get the current UTC Date. | | date.add() | Add number of days to a Date. | | date.difference() | Get the difference between two Dates. | | date.subtract() | Subtract number of days from a Date. | | date.toString() | Convert a Date to a String. | | document.delete() | Delete a collection document. | | document.exists() | Test if a collection document exists. | | document.replace() | Replace all fields in a collection document. | | document.update() | Update a collection document's fields. | | eventSource.map() | Apply an anonymous function to each element of an event source's tracked Set. | | eventSource.toString() | Get "[event source]" as a string. | | eventSource.where() | Create an event source that emits events for a subset of another event source’s tracked Set. | | function.definition | Get or update a user-defined function (UDF)'s definition, represented as a Function document. | | Function() | Call a user-defined function (UDF) by its name. | | Function.all() | Get a Set of all user-defined functions (UDFs). | | Function.byName() | Get a user-defined function (UDF) by its name. | | Function.create() | Create a user-defined function (UDF). | | Function.firstWhere() | Get the first user-defined function (UDF) that matches a provided predicate. | | Function.toString() | Get "Function" as a String. | | Function.where() | Get a Set of user-defined functions (UDFs) that match a provided predicate. | | functionDef.delete() | Delete a user-defined function (UDF). | | functionDef.exists() | Test if a user-defined function (UDF) exists. | | functionDef.replace() | Replace a user-defined function (UDF). | | functionDef.update() | Update a user-defined function (UDF). | | abort() | End the current query and return an abort error with a user-defined abort value. | | dbg() | Output a debug message in the query summary and return the message in the query results. | | ID() | Create a valid ID | | log() | Output a log message in the query summary and return null. | | newId() | Get a unique string-encoded 64-bit integer. | | Key.all() | Get a Set of all keys. | | Key.byId() | Get a key by its document id. | | Key.create() | Create a key. | | Key.firstWhere() | Get the first key that matches a provided predicate. | | Key.toString() | Get "Key" as a String. | | Key.where() | Get a Set of keys that match a provided predicate. | | key.delete() | Delete a key. | | key.exists() | Test if a key exists. | | key.replace() | Replace a key. | | key.update() | Update a key. | | Math.E | Get the Euler’s number mathematical constant (℮). | | Math.Infinity | String value representing infinity. | | Math.NaN | Value representing Not-a-Number. | | Math.PI | Get the mathematical constant pi (π). | | Math.abs() | Get the absolute value of a Number. | | Math.acos() | Get the inverse cosine in radians of a Number. | | Math.asin() | Get the inverse sine in radians of a Number. | | Math.atan() | Get the inverse tangent in radians of a Number. | | Math.ceil() | Round up a Number. | | Math.cos() | Get the cosine of a Number in radians. | | Math.cosh() | Get the hyperbolic cosine of a Number. | | Math.degrees() | Convert radians to degrees. | | Math.exp() | Get the value of ℮ raised to the power of a Number. | | Math.floor() | Round down a Number. | | Math.hypot() | Get the hypotenuse of a right triangle. | | Math.log() | Get the natural logarithm, base e, of a Number. | | Math.log10() | Get the base 10 logarithm of a Number. | | Math.max() | Get the larger of two Numbers. | | Math.mean() | Get the arithmetic mean of an Array or Set of Numbers. | | Math.min() | Get the smaller of the input parameter Numbers. | | Math.pow() | Get the value of a base raised to a power. | | Math.radians() | Convert the value of a Number in degrees to radians. | | Math.round() | Get the value of a Number rounded to the nearest integer. | | Math.sign() | Get the sign of a Number. | | Math.sin() | Get the sine of a Number in radians. | | Math.sinh() | Get the hyperbolic sine of a Number. | | Math.sqrt() | Get the square root of a Number. | | Math.sum() | Get the sum of an Array or Set of Numbers. | | Math.tan() | Get the tangent of a Number in radians. | | Math.tanh() | Get the hyperbolic tangent of a Number. | | Math.trunc() | Truncate a Number to a given precision. | | Object.assign() | Copies properties from a source Object to a destination Object. | | Object.entries() | Convert an Object to an Array of key-value pairs. | | Object.fromEntries() | Convert an Array of key-value pairs to an Object. | | Object.hasPath() | Test if an Object has a property. | | Object.keys() | Get an Object's top-level property keys as an Array. | | Object.select() | Get an Object property’s value by its path. | | Object.toString() | Convert an Object to a String. | | Object.values() | Get an Object's property values as an Array. | | Query.identity() | Get the identity document for the query’s authentication token. | | Query.isEnvProtected() | Test if the queried database is in protected mode. | | Query.isEnvTypechecked() | Test if the queried database is typechecked. | | Query.token() | Get the Token document or JWT payload for the query’s authentication secret. | | Role.all() | Get a Set of all user-defined roles. | | Role.byName() | Get a user-defined role by its name. | | Role.create() | Create a user-defined role. | | Role.firstWhere() | Get the first user-defined role matching a provided predicate. | | Role.toString() | Get "Role" as a String. | | Role.where() | Get a Set of user-defined roles that match a provided predicate. | | role.delete() | Delete a user-defined role. | | role.exists() | Test if a user-defined role exists. | | role.replace() | Replace a user-defined role. | | role.update() | Update a user-defined role. | | FQL.Schema.defForIdentifier() | Returns the definition for a user-defined collection or user-defined function (UDF) using the same rules as top-level identifier lookups. | | Set.paginate() | Get a page of paginated results using an after cursor. | | Set.sequence() | Create an ordered Set of Numbers given start and end values. | | Set.single() | Create a Set containing a single provided element. | | set.aggregate() | Aggregate all elements of a Set. | | set.any() | Test if any element of a Set matches a provided predicate. | | set.changesOn() | Create an event source that tracks changes to specified document fields in a supported Set. | | set.concat() | Concatenate two Sets. | | set.count() | Get the number of elements in a Set. | | set.distinct() | Get the unique elements of a Set. | | set.drop() | Drop the first N elements of a Set. | | set.eventsOn() | Create an event source that tracks changes to specified document fields in a supported Set. | | set.eventSource() | Create an event source that tracks changes to documents in a supported Set. | | set.every() | Test if every element of a Set matches a provided predicate. | | set.first() | Get the first element of a Set. | | set.firstWhere() | Get the first element of a Set that matches a provided predicate. | | set.flatMap() | Apply a provided function to each Set element and flatten the resulting Set by one level. | | set.fold() | Reduce the Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | | set.foldRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | | set.forEach() | Run a provided function on each element of a Set. Can perform writes. | | set.includes() | Test if the Set includes a provided element. | | set.isEmpty() | Test if a Set is empty. | | set.last() | Get the last element of a Set. | | set.lastWhere() | Get the last element of a Set that matches a provided predicate. | | set.map() | Apply a provided function to each element of a Set. Can’t perform writes. | | set.nonEmpty() | Test if a Set is not empty. | | set.order() | Sort a Set's elements. | | set.pageSize() | Set the maximum elements per page in paginated results. | | set.paginate() | Convert a Set to an Object with pagination. | | set.reduce() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | | set.reduceRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | | set.reverse() | Reverse the order of a Set's elements. | | set.take() | Get the first N elements of a Set. | | set.toArray() | Convert a Set to an Array. | | set.toStream() | Create an event source that tracks changes to documents in a supported Set. | | set.toString() | Return the string "[set]". | | set.where() | Get the elements of a Set that match a provided predicate. | | string.length | Get a String's length. | | string.at() | Get the character at a specified index of a String. | | string.casefold() | Convert a String to lower case using a specified format. | | string.concat() | Concatenate two Strings. | | string.endsWith() | Test if a String ends with a provided suffix. | | string.includes() | Test if a String includes a provided substring. | | string.includesRegex() | Test if a String contains a substring that matches a provided regular expression. | | string.indexOf() | Get the index of the first matching substring within a String. | | string.indexOfRegex() | Get the index of the first substring matching a provided regular expression within a String. | | string.insert() | Insert a substring into a String at a specified index. | | string.lastIndexOf() | Get the index of the last matching substring within a String. | | string.matches() | Get the substrings in a String that match a provided regular expression. | | string.matchIndexes() | Get the indexes and substrings in a String that match a provided regular expression. | | string.parseDouble() | Convert a String to a Double. | | string.parseInt() | Convert a String to a Int. | | string.parseLong() | Convert a String to a Long. | | string.parseNumber() | Convert a String to a Number. | | string.replace() | Replace a specified number of occurrences of a substring in a String. | | string.replaceAll() | Replace all occurrences of a substring in a String. | | string.replaceAllRegex() | Replace all occurrences of substrings matching a regular expression in a String. | | string.replaceRegex() | Replace a specified number of occurrences of substrings matching a regular expression in a String. | | string.slice() | Get the substring between two indexes of a String. | | string.split() | Split a String at a provided separator. | | string.splitAt() | Split a String at a provided index. | | string.splitRegex() | Split a String using a provided regular expression. | | string.startsWith() | Test if a String starts with a provided prefix. | | string.toLowerCase() | Convert a String to lower case. | | string.toString() | Get a String representation of the value. | | string.toUpperCase() | Convert a String to upper case. | | dayOfMonth | Get the day of the month from a Time. | | dayOfWeek | Get the day of the week from a Time. | | dayOfYear | Get the day of the year from a Time. | | hour | Get the hour of a Time. | | minute | Get the minute of a Time. | | month | Get the month of a Time. | | second | Get the second of a Time. | | year | Get the year of a Time. | | Time() | Construct a Time from an ISO 8601 timestamp String. | | Time.epoch() | Convert a Unix epoch timestamp to a Time. | | Time.fromString() | Construct a Time from an ISO 8601 timestamp String. | | Time.now() | Get the current UTC Time. | | time.add() | Add a time interval to a Time. | | time.difference() | Get the difference between two Times. | | time.subtract() | Subtract a time interval from a Time. | | time.toMicros() | Convert a Time to a Unix epoch timestamp in microseconds. | | time.toMillis() | Convert a Time to a Unix epoch timestamp in milliseconds. | | time.toSeconds() | Convert a Time to a Unix epoch timestamp in seconds. | | time.toString() | Convert a Time to a String. | | Token.all() | Get a Set of all tokens. | | Token.byDocument() | Get a token by its identity document. | | Token.byId() | Get a token by its document id. | | Token.create() | Create a token without a credential or related password. | | Token.firstWhere() | Get the first token that matches a provided predicate. | | Token.toString() | Get "Token" as a String. | | Token.where() | Get a Set of tokens that match a provided predicate. | | token.delete() | Delete a token. | | token.exists() | Test if a token exists. | | token.replace() | Replace a token. | | token.update() | Update a token. | | TransactionTime() | Get the query transaction time. | | TransactionTime.toString() | Get "[transaction time]" as a String. | # AccessProvider | Learn: Access providers | | --- | --- | --- | An [access provider](../../../learn/security/access-providers/) registers an external identity provider (IdP), such as Auth0, in your Fauna database. Once [set up](../../../learn/security/access-providers/#config), the IdP can issue JSON Web Tokens (JWTs) that act as Fauna [authentication secrets](../../../learn/security/authentication/#secrets). This lets your application’s end users use the IdP for authentication. ## [](#collection)`AccessProvider` collection Fauna stores access providers as documents in the `AccessProvider` system collection. These documents are an FQL version of the FSL [access provider schema](../../fsl/access-provider/). `AccessProvider` documents have the following FQL structure: ```fql { name: "someIssuer", coll: AccessProvider, ts: Time("2099-09-06T21:46:50.272Z"), issuer: "https://example.com/", jwks_uri: "https://example.com/.well-known/jwks.json", roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ], data: { desc: "Access provider for issuer" }, audience: "https://db.fauna.com/db/ysij4khxoynr4" } ``` | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | name | String | | true | Unique name for the access provider in the database.Must begin with a letter. Can only include letters, numbers, and underscores. | | coll | Collection | true | | Collection name: AccessProvider. | | ts | Time | true | | Last time the document was created or updated. | | issuer | String | | true | Issuer for the IdP’s JWTs. Must match the iss claim in JWTs issued by the IdP. | | jwks_uri | String | | true | URI that points to public JSON web key sets (JWKS) for JWTs issued by the IdP. Fauna uses the keys to verify each JWT’s signature. | | roles | String |Object |Array of strings and objects |Null | | | User-defined roles assigned to JWTs issued by the IdP. Can’t be built-in roles.A roles string is the name of a user-defined role. roles objects have the following schema: FieldTypeDescriptionroleStringName of a user-defined role.predicateStringFQL predicate function. If present, JWTs are only assigned the role if the predicate evaluates to true.The predicate function is passed one argument: an object containing the JWT’s payload. The predicate function does not support shorthand syntax. | Field | Type | Description | role | String | Name of a user-defined role. | predicate | String | FQL predicate function. If present, JWTs are only assigned the role if the predicate evaluates to true.The predicate function is passed one argument: an object containing the JWT’s payload. The predicate function does not support shorthand syntax. | | Field | Type | Description | | role | String | Name of a user-defined role. | | predicate | String | FQL predicate function. If present, JWTs are only assigned the role if the predicate evaluates to true.The predicate function is passed one argument: an object containing the JWT’s payload. The predicate function does not support shorthand syntax. | | data | { *: Any } | Null | | | Arbitrary user-defined metadata for the document. | | audience | String | true | | Globally unique URL for the Fauna database. audience URLs have the following structure:https://db.fauna.com/db/ where is the globally unique ID for the database.Must match the aud claim in JWTs issued by the IdP. | ## [](#static-methods)Static methods You can use the following static methods to manage the `AccessProvider` collection in FQL. | Method | Description | | --- | --- | --- | --- | | AccessProvider.all() | Get a Set of all access providers. | | AccessProvider.byName() | Get an access provider by its name. | | AccessProvider.create() | Create an access provider. | | AccessProvider.firstWhere() | Get the first access provider that matches a provided predicate. | | AccessProvider.toString() | Get "AccessProvider" as a String. | | AccessProvider.where() | Get a Set of access providers that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `AccessProvider` documents in FQL. | Method | Description | | --- | --- | --- | --- | | accessProvider.delete() | Delete an access provider. | | accessProvider.exists() | Test if an access provider exists. | | accessProvider.replace() | Replace an access provider. | | accessProvider.update() | Update an access provider. | # `AccessProvider.all()` | Learn: Access providers | | --- | --- | --- | Get a Set of all [access providers](../../../../learn/security/access-providers/). ## [](#signature)Signature ```fql-sig AccessProvider.all() => Set AccessProvider.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [access providers](../../../../learn/security/access-providers/), represented as [`AccessProvider` documents](../), for the database. To limit the returned Set, you can provide an optional range. `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). If this method is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of AccessProvider documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded AccessProvider.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all access providers are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an AccessProvider document. | | to | Any | | End of the range (inclusive). Must be an AccessProvider document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of AccessProvider documents in the provided range. If a range is omitted, all access providers are returned.The Set is empty if:The database has no access providers.There are no access providers in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all access providers for the database: ```fql AccessProvider.all() ``` ``` { data: [ { name: "issuerFoo", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/a", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/a/.well-known/jwks.json" }, { name: "issuerBaz", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/b", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/b/.well-known/jwks.json" }, { name: "issuerBar", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/c", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/c/.well-known/jwks.json" }, { name: "issuerQux", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/d", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/d/.well-known/jwks.json" }, ... ] } ``` 2. Given the previous Set, get all access providers starting with `issuerBaz` (inclusive): ```fql AccessProvider.all({ from: AccessProvider.byName("issuerBaz") }) ``` ``` { data: [ { name: "issuerBaz", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/b", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/b/.well-known/jwks.json" }, { name: "issuerBar", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/c", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/c/.well-known/jwks.json" }, { name: "issuerQux", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/d", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/d/.well-known/jwks.json" }, ... ] } ``` 3. Get a Set of access providers from `issuerBaz` (inclusive) to `issuerBar` (inclusive): ```fql AccessProvider.all({ from: AccessProvider.byName("issuerBaz"), to: AccessProvider.byName("issuerBar") }) ``` ``` { data: [ { name: "issuerBaz", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/b", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/b/.well-known/jwks.json" }, { name: "issuerBar", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/bc", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/c/.well-known/jwks.json" } ] } ``` 4. Get a Set of access providers up to `issuerBar` (inclusive): ```fql AccessProvider.all({ to: AccessProvider.byName("issuerBar") }) ``` ``` { data: [ { name: "issuerFoo", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/a", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/a/.well-known/jwks.json" }, { name: "issuerBaz", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/b", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/b/.well-known/jwks.json" }, { name: "issuerBar", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), ... issuer: "https://example.com/c", audience: "https://db.fauna.com/db/ysjowue14yyr1", jwks_uri: "https://example.com/c/.well-known/jwks.json" } ] } ``` # `AccessProvider.byName()` | Learn: Access providers | | --- | --- | --- | Get an [access provider](../../../../learn/security/access-providers/) by its name. ## [](#signature)Signature ```fql-sig AccessProvider.byName(name: String) => NamedRef ``` ## [](#description)Description Gets an [access provider](../../../../learn/security/access-providers/), represented as an [`AccessProvider` document](../), by its name. `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | name | String | true | name of the AccessProvider document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NamedRef | Resolved reference to the AccessProvider document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql AccessProvider.byName("someIssuer") ``` ``` { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ], issuer: "https://example.com/", jwks_uri: "https://example.com/.well-known/jwks.json", audience: "https://db.fauna.com/db/ysjowue14yyr1" } ``` # `AccessProvider.create()` | Learn: Access providers | | --- | --- | --- | Create an [access provider](../../../../learn/security/access-providers/). ## [](#signature)Signature ```fql-sig AccessProvider.create(data: { name: String, issuer: String, jwks_uri: String, roles: String | { role: String, predicate: String } | Array | Null, data: { *: Any } | Null }) => AccessProvider ``` ## [](#description)Description Creates an [access provider](../../../../learn/security/access-providers/) with the provided document fields. Fauna stores access providers as documents in the [`AccessProvider` system collection](../). `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method adds an access provider to the staged schema, not the active schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the new AccessProvider document.For supported document fields, see AccessProvider collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | AccessProvider | The new AccessProvider document. | ## [](#examples)Examples ```fql AccessProvider.create({ name: "someIssuer", issuer: "https://example.com/", jwks_uri: "https://example.com/.well-known/jwks.json", roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ], data: { desc: "Access provider for issuer" } }) ``` ``` { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T13:08:04.020Z"), issuer: "https://example.com/", audience: "https://db.fauna.com/db/ysjons5xryyr4", data: { desc: "Access provider for issuer" }, jwks_uri: "https://example.com/.well-known/jwks.json", roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ] } ``` # `AccessProvider.firstWhere()` | Learn: Access providers | | --- | --- | --- | Get the first [access provider](../../../../learn/security/access-providers/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig AccessProvider.firstWhere(pred: (AccessProvider => Boolean)) => AccessProvider | Null ``` ## [](#description)Description Gets the first [access provider](../../../../learn/security/access-providers/), represented as an [`AccessProvider` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an AccessProvider document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first AccessProvider document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | AccessProvider | First AccessProvider document that matches the predicate. | | Null | No AccessProvider document matches the predicate. | ## [](#examples)Examples ```fql AccessProvider.firstWhere(.issuer == "https://example.com/") ``` ``` { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T14:57:23.125Z"), jwks_uri: "https://example.com/.well-known/jwks.json", roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ], audience: "https://db.fauna.com/db/ysjowue14yyr1", issuer: "https://example.com/" } ``` # `AccessProvider.toString()` | Learn: Access providers | | --- | --- | --- | Get `"AccessProvider"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig AccessProvider.toString() => String ``` ## [](#description)Description Returns the name of the [`AccessProvider` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "AccessProvider" | ## [](#examples)Examples ```fql AccessProvider.toString() ``` ``` "AccessProvider" ``` # `AccessProvider.where()` | Learn: Access providers | | --- | --- | --- | Get a Set of [access providers](../../../../learn/security/access-providers/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig AccessProvider.where(pred: (AccessProvider => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [access providers](../../../../learn/security/access-providers/), represented as [`AccessProvider` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). If `AccessProvider.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an AccessProvider document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of AccessProvider documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of AccessProvider documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql AccessProvider.where(.issuer.includes("example.com")) ``` ``` { data: [ { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T13:15:14.165Z"), jwks_uri: "https://example.com/.well-known/jwks.json", issuer: "https://example.com/", audience: "https://db.fauna.com/db/ysjons5xryyr4", roles: [ "customer", { role: "manager", predicate: "(jwt) => jwt!.scope.includes(\"manager\")" } ], }, ... ] } ``` # `accessProvider.delete()` | Learn: Access providers | | --- | --- | --- | Delete an [access provider](../../../../learn/security/access-providers/). ## [](#signature)Signature ```fql-sig delete() => NullAccessProvider ``` ## [](#description)Description Deletes an [access provider](../../../../learn/security/access-providers/), represented as a [`AccessProvider` document](../). `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#staged-schema)Staged schema You can’t delete an access provider while a database has [staged schema](../../../../learn/schema/manage-schema/#staged). If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullAccessProvider | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql AccessProvider.byName("someIssuer")?.delete() ``` ``` AccessProvider.byName("someIssuer") /* deleted */ ``` # `accessProvider.exists()` | Learn: Access providers | | --- | --- | --- | Test if an [access provider](../../../../learn/security/access-providers/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if an [access provider](../../../../learn/security/access-providers/), represented as an [`AccessProvider` document](../), exists. `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the AccessProvider document exists. If false, the AccessProvider document doesn’t exist. | ## [](#examples)Examples ```fql AccessProvider.byName("someIssuer").exists() ``` ``` true ``` # `accessProvider.replace()` | Learn: Access providers | | --- | --- | --- | Replace an [access provider](../../../../learn/security/access-providers/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => AccessProvider ``` ## [](#description)Description Replaces all fields in an [access provider](../../../../learn/security/access-providers/), represented as an [`AccessProvider` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `coll` and `ts` metadata fields, are removed. `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#metadata-fields)Metadata fields You can’t use this method to replace the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename an access provider while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Fields for the AccessProvider document. Fields not present, excluding the coll and ts metadata fields, in the object are removed.For supported document fields, see AccessProvider collection.The object can’t include the following metadata fields:collts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | AccessProvider | AccessProvider document with replaced fields. | ## [](#examples)Examples ```fql AccessProvider.byName("someIssuer")?.replace({ name: "someIssuer", issuer: "https://example.com/", roles: "customer", jwks_uri: "https://example.com/.well-known/jwks.json" }) ``` ``` { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T15:00:07.450Z"), audience: "https://db.fauna.com/db/ysjowue14yyr1", issuer: "https://example.com/", roles: "customer", jwks_uri: "https://example.com/.well-known/jwks.json" } ``` # `accessProvider.update()` | Learn: Access providers | | --- | --- | --- | Update an [access provider](../../../../learn/security/access-providers/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => AccessProvider ``` ## [](#description)Description Updates an [access provider](../../../../learn/security/access-providers/), represented as an [`AccessProvider` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. `AccessProvider` documents are FQL versions of a database’s FSL [access provider schema](../../../fsl/access-provider/). `AccessProvider` documents have the [AccessProvider](../../../fql/types/#accessprovider) type. See [Access providers](../../../../learn/security/access-providers/). ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename an access provider while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the AccessProvider document.For supported document fields, see AccessProvider collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | AccessProvider | The updated AccessProvider document. | ## [](#examples)Examples ```fql AccessProvider.byName("someIssuer")?.update({ name: "someIssuer", issuer: "https://example.com/", roles: "customer" }) ``` ``` { name: "someIssuer", coll: AccessProvider, ts: Time("2099-06-25T15:00:27.295Z"), jwks_uri: "https://example.com/.well-known/jwks.json", roles: "customer", issuer: "https://example.com/", audience: "https://db.fauna.com/db/ysjowue14yyr1" } ``` # Array [Array](../../fql/types/#array) methods and properties. ## [](#description)Description [Array](../../fql/types/#array) methods are provided for working with multiple items grouped under a single identifier. Arrays are immutable. ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Array.sequence() | Create an ordered Array of integers, given start and end values. | ## [](#instance-properties)Instance properties | Property | Description | | --- | --- | --- | --- | | array.length | Get the length of an Array. | ## [](#instance-methods)Instance methods | Method | Description | | --- | --- | --- | --- | | array.aggregate() | Aggregate all elements of an Array. | | array.any() | Test if any element of an Array matches a provided predicate. | | array.append() | Append a provided element to an Array. | | array.at() | Get the Array element at a provided index. | | array.concat() | Concatenate two Arrays. | | array.distinct() | Get the unique elements of an Array. | | array.drop() | Drop the first N elements of an Array. | | array.entries() | Add the index to each element of an Array. | | array.every() | Test if every element of an Array matches a provided predicate. | | array.filter() | Filter an Array using a provided predicate. | | array.first() | Get the first element of an Array. | | array.firstWhere() | Get the first element of an Array that matches a provided predicate. | | array.flatMap() | Apply a provided function to each Array element and flatten the resulting Array by one level. | | array.flatten() | Flatten an Array by one level. | | array.fold() | Reduce the Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | | array.foldRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | | array.forEach() | Run a provided function on each element of an Array. Can perform writes. | | array.includes() | Test if the Array includes a provided element. | | array.indexOf() | Get the index of the first Array element that matches a provided value. | | array.indexWhere() | Get the index of the first Array element that matches a provided predicate. | | array.isEmpty() | Test if an Array is empty. | | array.last() | Get the last element of an Array. | | array.lastIndexOf() | Get the index of the last Array element that matches a provided value. | | array.lastIndexWhere() | Get the index of the last Array element that matches a provided predicate. | | array.lastWhere() | Get the last element of an Array that matches a provided predicate. | | array.map() | Apply a provided function to each element of an Array. Can’t perform writes. | | array.nonEmpty() | Test if an Array is not empty. | | array.order() | Sort an Array's elements. | | array.prepend() | Prepend an element to an Array. | | array.reduce() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | | array.reduceRight() | Reduce an Array to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | | array.reverse() | Reverse the order of an Array's elements. | | array.slice() | Get a subset of an Array's elements based on provided indexes. | | array.take() | Get the first N elements of an Array. | | array.toSet() | Convert an Array to a Set. | | array.toString() | Convert an Array to a String. | | array.where() | Get the elements of an Array that match a provided predicate. | # `Array.sequence()` Create an ordered [Array](../../../fql/types/#array) of [Number](../../../fql/types/#number)s given start and end values. ## [](#signature)Signature ```fql-sig Array.sequence(from: Number, until: Number) => Array ``` ## [](#description)Description Create an ordered [Array](../../../fql/types/#array) of integers beginning with provided start and end integers. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Number | true | Start of the sequence (inclusive). Must be an Int. | | until | Number | true | End of the sequence (exclusive). Must be an Int. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of ordered integers. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql Array.sequence(1, 5) ``` ``` [ 1, 2, 3, 4 ] ``` ### [](#equal-start-and-end-values)Equal start and end values If the start and end values are equal, `Array.sequence()` produces an empty Array (`[]`). ```fql Array.sequence(1, 1) ``` ``` [] ``` # `array.length` The number of elements in the [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig length: Number ``` ## [](#description)Description The number of elements in an [Array](../../../fql/types/#array). The length of an empty Array is `0`. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Number of elements in the Array. | ## [](#examples)Examples ```fql [0, 1, 2, 3].length ``` ``` 4 ``` # `array.aggregate()` Aggregate all elements of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig aggregate(seed: A, combiner: (A, A) => A) => A ``` ## [](#description)Description Aggregates all elements of the calling [Array](../../../fql/types/#array). There is no ordering expectation. The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Generic | true | Initial state value. | | combiner | Function | true | Anonymous FQL function that aggregates the elements. | ### [](#combiner-function-parameters)Combiner function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | | Value returned by the previous invocation. | | current | Generic | | The current element’s value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Aggregate of the iterable. If the iterable is empty, the seed value is returned. | ## [](#examples)Examples ```fql let iter = [1, 2, 3, 4] iter.aggregate(0, (a, b) => a + b) ``` ``` 10 ``` # `array.any()` Test if any element of an [Array](../../../fql/types/#array) matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig any(predicate: (A => Boolean | Null)) => Boolean ``` ## [](#description)Description Tests if any element of the calling [Array](../../../fql/types/#array) matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax.Returns Boolean or Null.The method returns true if the predicate is true for any element in the Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the predicate is true for one or more elements in the Array. Otherwise, false. | ## [](#examples)Examples ```fql let iter = [1, 2, 3] iter.any(v => v == 2) ``` ``` true ``` # `array.append()` Append a provided element to an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig append(element: A) => Array ``` ## [](#description)Description Appends a provided element to the calling [Array](../../../fql/types/#array). The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Element to append to the Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array with the appended element. | ## [](#examples)Examples ```fql [1, 2].append(3) ``` ``` [ 1, 2, 3 ] ``` # `array.at()` Get the [Array](../../../fql/types/#array) element at a provided index. ## [](#signature)Signature ```fql-sig at(index: Number) => A ``` ## [](#description)Description Gets the [Array](../../../fql/types/#array) element located at a provided index. The method is equivalent to using `[]` indexing, such that `array.at(0)` returns the same element as `array[0]`. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | index | Number | true | Location of the Array element to return. Must be an Int.Arrays have zero-based indexes. Valid index values are zero to one less than the Array length. Invalid index values result in an error. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Array element located at the provided index. | ## [](#examples)Examples Get the element at index location four: ```fql [1, 2, 3, 4, 5].at(4) ``` ``` 5 ``` # `array.concat()` Concatenate two [Array](../../../fql/types/#array)s. ## [](#signature)Signature ```fql-sig concat(other: Array) => Array ``` ## [](#description)Description Creates an [Array](../../../fql/types/#array) by copying the calling array to a new Array and appending another Array. The calling Array and the other Array aren’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | other | Array | true | Array to append to the calling Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array composed of the concatenated Arrays. | ## [](#examples)Examples This example concatenates the second [Array](../../../fql/types/#array) to the first: ```fql [0, 1, 2, 3, 4].concat([3, 2, 1, 0]) ``` ``` [ 0, 1, 2, 3, 4, 3, 2, 1, 0 ] ``` # `array.distinct()` Get the unique elements of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig distinct() => Array ``` ## [](#description)Description Gets the unique elements of the calling [Array](../../../fql/types/#array). The calling Array isn’t changed. ### [](#avoid-using-distinct-with-large-sets)Avoid using `distinct()` with large Sets Avoid using `distinct()` to process Arrays converted from large or unbounded Sets that contain 16,000 or more documents. If a Set contains 16,000 or more documents, the query requires pagination. [`array.distinct()`](./) would only be able to extract unique elements from each page of results. Instead, retrieve all field values and process them on the client side. See [Get unique field values](../../../../learn/query/patterns/get-unique-values/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Unique elements in the Array. | ## [](#examples)Examples ```fql [1, 1, 2, 3, 3].distinct() ``` ``` [ 1, 2, 3 ] ``` # `array.drop()` Drop the first _N_ elements of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig drop(amount: Number) => Array ``` ## [](#description)Description Drops a provided number of elements from an [Array](../../../fql/types/#array), beginning at element\[0\]. This lets you "skip" the elements. The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Number of elements to drop. If this value is greater than the Array length, an empty Array is returned. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | An Array with the elements dropped. | ## [](#examples)Examples ```fql [1, 2, 3, 4, 5].drop(2) ``` ``` [ 3, 4, 5 ] ``` # `array.entries()` Add the index to each element of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig entries() => Array<[Number, A]> ``` ## [](#description)Description Adds the index to every Array element, creating an Array of each `[index, element]` pair. The calling Array isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array<[Number, Generic]> | List of Arrays of index:element pairs for each element of the calling Array. | ## [](#examples)Examples ```fql ['a', 'b', 'c'].entries() ``` ``` [ [ 0, "a" ], [ 1, "b" ], [ 2, "c" ] ] ``` # `array.every()` Test if every element of an [Array](../../../fql/types/#array) matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig every(predicate: (A => Boolean | Null)) => Boolean ``` ## [](#description)Description Tests if every element of the calling Array matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax.Returns Boolean or Null.The method returns true if the predicate is true for every element in the Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the predicate evaluates to true for every element of the Array. Otherwise, false. | ## [](#examples)Examples ```fql let iter = [1, -2, 3] iter.every(v => v > 0) ``` ``` false ``` # `array.filter()` Filter an [Array](../../../fql/types/#array) using a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig filter(predicate: (A => Boolean | Null)) => Array ``` ## [](#description)Description Returns an Array containing elements of the calling Array that match a provided [predicate function](../../../fql/functions/#predicates). The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax.Returns Boolean or Null.If the predicate evaluates to true for an element, the element is included in the Array returned by the method. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing elements that evaluate to true for the provided predicate.If no elements evaluate to true, the method returns an empty Array. | ## [](#examples)Examples ```fql [1, 2, 3, 4, 5].filter((x) => {x == 1 || x == 4}) ``` ``` [ 1, 4 ] ``` ## [](#see-also)See also [`array.where()`](../where/) # `array.first()` Get the first element of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig first() => A | Null ``` ## [](#description)Description Gets the first element of the calling [Array](../../../fql/types/#array). ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | First element of the Array. | | Null | Returns Null for an empty Array. | ## [](#examples)Examples ```fql [1, 2].first() ``` ``` 1 ``` # `array.firstWhere()` Get the first element of an [Array](../../../fql/types/#array) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig firstWhere(predicate: (A => Boolean | Null)) => A | Null ``` ## [](#description)Description Gets the first element of the calling [Array](../../../fql/types/#array) that matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax. Supports shorthand-syntax for objects and documents.Returns Boolean or Null.The method returns the first Array element for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | First element of the Array that matches the predicate. | | Null | Returned if no Array element matches the predicate or the Array is empty. | ## [](#examples)Examples ```fql let iter = [1, 2, 3, 4] iter.firstWhere(v => v > 2) ``` ``` 3 ``` # `array.flatMap()` Apply a provided [function](../../../fql/functions/) to each [Array](../../../fql/types/#array) element and flatten the resulting Array by one level. ## [](#signature)Signature ```fql-sig flatMap(mapper: (A => Array)) => Array ``` ## [](#description)Description Creates an [Array](../../../fql/types/#array) by invoking a provided mapper [function](../../../fql/functions/) on each element of the calling Array and flattening the resulting Array by one level. The Array elements are passed as a parameter to the mapper function sequentially. The calling Array isn’t changed. ### [](#array-iteration-methods)Array iteration methods FQL provides several methods for iterating over an Array. [`array.forEach()`](../foreach/), [`array.map()`](../map/), and [`array.flatMap()`](./) are similar but return different values. | Method | Return value | | --- | --- | --- | --- | | array.forEach() | Null. | | array.map() | Array. | | array.flatMap() | Array, flattened by one level. | For examples, see: * [`array.forEach()` vs. `array.map()`](../map/#foreach-vs-map) * [`array.map()` vs. `array.flatMap()`](#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | mapper | Function | true | Function to invoke on each element of the calling Array. Each element is passed to the mapper function as an argument. The function must return an Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing the result of invoking the mapper function on each element of the calling Array. The resulting Array is flattened by one level. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql [1, 2, 3].flatMap((val) => [val, val * 2, val * 3]) ``` ``` [ 1, 2, 3, 2, 4, 6, 3, 6, 9 ] ``` ### [](#map-vs-flatmap)`array.map()` vs. `array.flatMap()` [`array.flatMap()`](./) is similar to [`array.map()`](../map/), except [`array.flatMap()`](./) also flattens the resulting Array by one level. In the following example, [`array.map()`](../map/) returns a two-dimensional Array: ```fql // Create an Array of product names. let products = [ "limes", "avocados" ] // Use `map()` to get a Set of matching `Product` collection // documents for each name. Convert each Set to an Array. products.map(product => { Product.byName(product).toArray() }) ``` ``` // Two-dimensional Array. [ [ { id: "777", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("789") } ], [ { id: "444", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] ] ``` To flatten the result to a one-dimensional array, use [`array.flatMap()`](./) instead: ```fql // Create an Array of product names. let products = [ "limes", "avocados" ] // Use `flatMap()` to get a Set of matching `Product` collection // documents for each name. Convert each Set to an Array. // Then flatten the resulting Array by one level. products.flatMap(product => { Product.byName(product).toArray() }) ``` ``` // One-dimensional Array. [ { id: "777", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("789") }, { id: "444", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] ``` # `array.flatten()` Flatten an [Array](../../../fql/types/#array) by one level. ## [](#signature)Signature ```fql-sig flatten() => Array ``` ## [](#description)Description Flattens an [Array](../../../fql/types/#array) by one level, reducing its dimensions by one. The calling Array must be a multi-dimentional Array. If there are non-Array elements in the Array, an error is returned. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Flattened Array. | ## [](#examples)Examples ```fql [[1, 2], [3, 4]].flatten() ``` ``` [ 1, 2, 3, 4 ] ``` # `array.fold()` Reduce the [Array](../../../fql/types/#array) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. ## [](#signature)Signature ```fql-sig fold(seed: B, reducer: (B, A) => B) => B ``` ## [](#description)Description Iterates through each element in an [Array](../../../fql/types/#array) to perform a rolling operation. For example, you can use `fold()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `fold()` calls a reducer callback function on every element of the Array from left to right. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. For the first iteration, a seed value serves as the initial accumulator. * The current element’s value from the Array. The method returns the result of the last iteration. The calling Array isn’t changed. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce an Array to a single value. These methods include: * [`array.fold()`](./) * [`array.foldRight()`](../foldright/) * [`array.reduce()`](../reduce/) * [`array.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`array.fold()`](./) and [`array.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`array.reduce()`](../reduce/) and [`array.reduceRight()`](../reduceright/) use the array’s first element as the initial _accumulator_. * [`array.fold()`](./) and [`array.reduce()`](../reduce/) iterate through the Array’s elements from left to right. [`array.foldRight()`](../foldright/) and [`array.reduceRight()`](../reduceright/) iterate through the Array’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Generic | true | Initial accumulator value provided to the reducer function. | | reducer | Function | true | Anonymous FQL function to call on each element of the Array. | ### [](#reducer-function-arguments)Reducer function arguments: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. For an empty Array, the seed is returned. | ## [](#examples)Examples ```fql let iter = [1, 2, 3] iter.fold(100, (value, elem) => value + elem) ``` ``` 106 ``` ### [](#group-by-operation)Group by operation [FQL](../../../../learn/query/) doesn’t provide a built-in `GROUP BY` operation. However, you use `fold()` in an [anonymous FQL function](../../../fql/functions/) or a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) to achieve the same result. As an FQL function: ```fql // Defines an anonymous `groupBy()` function. // `groupBy()` two arguments: // * `set`: Set or Array containing data to group // * `key_fn`: Grouping key for each element let groupBy = (set, key_fn) => { // Calls the `fold()` function on the `set` // Set or Array. set.fold( // Start with an empty object. {}, (acc, val) => { // For each value, get a key using the `key_fn` arg. let key = key_fn(val) let existing_group = acc[key] ?? [] // Append the current value to the Set or // Array for that key. let new_group = existing_group.append(val) let new_entry = Object.fromEntries([ [key, new_group] ]) // Return an object with grouped results. Object.assign(acc, new_entry) } ) } // Call the `groupBy()` function. // Groups `Product` documents by category name. groupBy(Product.all(), .category!.name) ``` You can also define a `groupBy()` UDF. This lets you reuse the function across multiple queries. You create and manage a UDF as an FSL [function schema](../../../fsl/function/): ```fsl // Defines the `groupBy()` UDF. // `groupBy()` two arguments: // * `set`: Set or Array containing data to group // * `key_fn`: Grouping key for each element function groupBy (set, key_fn) { // Calls the `fold()` function on the `set` // Set or Array. set.fold( // Start with an empty object. {}, (acc, val) => { // For each value, get a key using the `key_fn` arg. let key: String = key_fn(val) let existing_group = acc[key] ?? [] // Append the current value to the Set or // Array for that key. let new_group = existing_group.append(val) let new_entry = Object.fromEntries([ [key, new_group] ]) // Return an object with grouped results. Object.assign(acc, new_entry) } ) } ``` You can create and manage schema using any of the following: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) For additional examples using the `groupBy()` UDF, see [Group By: Aggregate data in Fauna](../../../../learn/query/patterns/group-by/). # `array.foldRight()` Reduce an [Array](../../../fql/types/#array) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. ## [](#signature)Signature ```fql-sig foldRight(seed: B, reducer: (B, A) => B) => B ``` ## [](#description)Description Iterates through each element in an [Array](../../../fql/types/#array) to perform a rolling operation. For example, you can use `foldRight()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `foldRight()` calls a reducer callback function on every element of the Array from right to left. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. For the first iteration, a seed value serves as the initial accumulator. * The current element’s value from the Array. The method returns the result of the last iteration. The calling Array isn’t changed. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce an Array to a single value. These methods include: * [`array.fold()`](../fold/) * [`array.foldRight()`](./) * [`array.reduce()`](../reduce/) * [`array.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`array.fold()`](../fold/) and [`array.foldRight()`](./) accept an initial _seed_ value and use it as the initial _accumulator_. [`array.reduce()`](../reduce/) and [`array.reduceRight()`](../reduceright/) use the array’s first element as the initial _accumulator_. * [`array.fold()`](../fold/) and [`array.reduce()`](../reduce/) iterate through the Array’s elements from left to right. [`array.foldRight()`](./) and [`array.reduceRight()`](../reduceright/) iterate through the Array’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Generic | true | Initial accumulator value provided to the reducer function. | | reducer | Function | true | Anonymous FQL function to call on each element of the Array. | ### [](#reducer-function-arguments)Reducer function arguments: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. For an empty Array, the seed is returned. | ## [](#examples)Examples ```fql let iter = [1, 2, 3] iter.foldRight(100, (value, elem) => value + elem) ``` ``` 106 ``` # `array.forEach()` Run a provided [function](../../../fql/functions/) on each element of an [Array](../../../fql/types/#array). Can perform writes. ## [](#signature)Signature ```fql-sig forEach(callback: (A => Any)) => Null ``` ## [](#description)Description Iterates over all elements in the [Array](../../../fql/types/#array) and executes a provided callback function on each element. It is used for mutations or writing documents based on each Array element. The calling Array isn’t changed. ### [](#array-iteration-methods)Array iteration methods FQL provides several methods for iterating over an Array. [`array.forEach()`](./), [`array.map()`](../map/), and [`array.flatMap()`](../flatmap/) are similar but return different values. | Method | Return value | | --- | --- | --- | --- | | array.forEach() | Null. | | array.map() | Array. | | array.flatMap() | Array, flattened by one level. | For examples, see: * [`array.forEach()` vs. `array.map()`](#foreach-vs-map) * [`array.map()` vs. `array.flatMap()`](../map/#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | callback | Function | true | Anonymous FQL function to call on each element of the Array. Each call returns Null. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Null | This method always returns Null. | ## [](#examples)Examples ### [](#basic)Basic ```fql // Create an Array of objects that contain document data. let customers = [ { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } }, { "name": "Scott Chegg", "email": "chegg@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } }, { "name": "Hilary Ouse", "email": "ouse@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } ] // Use `forEach()` to create a `Customer` collection document for each // element of the previous Array. customers.forEach(doc => Customer.create({ doc })) // `forEach()` returns `null`. ``` ``` null ``` Although it returns `null`, [`array.forEach()`](./) still performed the requested operations. To verify: ```fql // Get all `Customer` collection documents Customer.all() ``` ``` { // The results contain `Customer` documents created by // the previous `forEach()` call. data: [ { id: "410652919999758409", coll: Customer, ts: Time("2099-10-02T16:53:12.770Z"), cart: null, orders: "hdW...", name: "Ruby Von Rails", email: "ruby@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, { id: "410652919999759433", coll: Customer, ts: Time("2099-10-02T16:53:12.770Z"), cart: null, orders: "hdW...", name: "Scott Chegg", email: "chegg@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, { id: "410652919999760457", coll: Customer, ts: Time("2099-10-02T16:53:12.770Z"), cart: null, orders: "hdW...", name: "Hilary Ouse", email: "ouse@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } } ] } ``` ### [](#foreach-vs-map)`array.forEach()` vs. `array.map()` You can use both [`array.forEach()`](./) and [`array.map()`](../map/) to iterate through an Array. However, each method returns a different value type. [`array.forEach()`](./) returns `null`: ```fql // Create an Array of objects that contain category data. let categories = [ { "name": "Electronics", "description": "Bargain electronics!" }, { "name": "Books", "description": "Bargain books!" } ] // Use `forEach()` to create a `Category` collection document for each // element of the previous Array. categories.forEach(doc => Category.create({ doc })) ``` ``` null ``` Although it returns `null`, [`array.forEach()`](./) still performed the requested operations. To verify: ```fql // Get all `Category` collection documents Category.all() ``` ``` // The results contain `Customer` documents created by // the previous `forEach()` call. { data: [ ... { id: "410665732340187209", coll: Category, ts: Time("2099-10-02T20:16:51.560Z"), products: "hdW...", name: "Electronics", description: "Bargain electronics!" }, { id: "410665732340188233", coll: Category, ts: Time("2099-10-02T20:16:51.560Z"), products: "hdW...", name: "Books", description: "Bargain books!" } ] } ``` [`array.map()`](../map/) returns an [Array](../../../fql/types/#array): ```fql // Create an Array of objects that contain category data. let categories = [ { "name": "Movies", "description": "Bargain movies!" }, { "name": "Music", "description": "Bargain music!" } ] // Use `map()` to create a `Category` collection document for each // element of the previous Array. categories.map(doc => Category.create({ doc })) ``` In this case, the Array contains documents created by the [`array.map()`](../map/) call: ``` [ { id: "410655308219678797", coll: Category, ts: Time("2099-10-02T17:31:10.366Z"), products: "hdW...", name: "Movies", description: "Bargain movies!" }, { id: "410655308219679821", coll: Category, ts: Time("2099-10-02T17:31:10.366Z"), products: "hdW...", name: "Music", description: "Bargain music!" } ] ``` # `array.includes()` Test if the [Array](../../../fql/types/#array) includes a provided element. ## [](#signature)Signature ```fql-sig includes(element: A) => Boolean ``` ## [](#description)Description Tests if the [Array](../../../fql/types/#array) includes a provided element. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Element to check the Array for. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Array contains the provided element. Otherwise, false. | ## [](#examples)Examples ```fql let iter = [1, 2, 3] iter.includes(2) ``` ``` true ``` # `array.indexOf()` Get the index of the first [Array](../../../fql/types/#array) element that matches a provided value. ## [](#signature)Signature ```fql-sig indexOf(element: A) => Number | Null indexOf(element: A, start: Number) => Number | Null ``` ## [](#description)Description Searches, left-to-right, for the first element that matches a provided value and returns the index of the element if a match is found. If an optional start index is provided, the method searches left-to-right starting at the start index and returns the first matching index (inclusive). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Value to search for in the Array elements. | | start | Number | | Starting index (inclusive) of the left-to-right search. Must be an Int. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Index of the element that matches the provided value. | | Null | Returned if a match isn’t found. | ## [](#examples)Examples ```fql ['a', 'b', 'c', 'b'].indexOf('c') ``` ``` 2 ``` # `array.indexWhere()` Get the index of the first [Array](../../../fql/types/#array) element that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig indexWhere(predicate: (A => Boolean | Null)) => Number | Null indexWhere(predicate: A => Boolean | Null, start: Number) => Number | Null ``` ## [](#description)Description Searches, left-to-right, for the first element that matches a provided [predicate function](../../../fql/functions/#predicates) and returns the index of the element if a match is found. If the optional start index is provided, the method searches left-to-right starting at index and returns the first matching index (inclusive). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax.Returns Boolean or Null.If the predicate evaluates to true for an element, the element is considered a match. | | start | Number | | Starting index (inclusive) of the left-to-right search. Must be an Int. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Index of the element that matches the provided predicate. | | Null | Returned if a match isn’t found. | ## [](#examples)Examples ```fql ['a', 'b', 'c', 'b'].indexWhere(v => v == 'c') ``` ``` 2 ``` # `array.isEmpty()` Test if an [Array](../../../fql/types/#array) is empty. ## [](#signature)Signature ```fql-sig isEmpty() => Boolean ``` ## [](#description)Description Tests if the calling [Array](../../../fql/types/#array) is empty and contains no elements. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Array is empty. Otherwise, false. | ## [](#examples)Examples ```fql let iter = [] iter.isEmpty() ``` ``` true ``` # `array.last()` Get the last element of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig last() => A | Null ``` ## [](#description)Description Returns the last element of the [Array](../../../fql/types/#array). The method reverses the Array and gets the first item. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Last element of the Array. | | Null | Returned if the Array is empty. | ## [](#examples)Examples ```fql let iter = [1] iter.last() ``` ``` 1 ``` # `array.lastIndexOf()` Get the index of the last [Array](../../../fql/types/#array) element that matches a provided value. ## [](#signature)Signature ```fql-sig lastIndexOf(element: A) => Number | Null lastIndexOf(element: A, end: Number) => Number | Null ``` ## [](#description)Description Searches, right-to-left, for the first element that matches a provided value and returns the index of the element if a match is found. If an optional end index is provided, the method searches right-to-left starting at the end index and returns the first matching index (inclusive). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Value to search for in the Array elements. | | start | Number | | Starting index (inclusive) of the right-to-left search. Must be an Int. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Index of the element that matches the provided value. | | Null | Returned if a match isn’t found. | ## [](#examples)Examples ```fql ['a', 'b', 'c', 'b'].lastIndexOf('c') ``` ``` 2 ``` # `array.lastIndexWhere()` Get the index of the last [Array](../../../fql/types/#array) element that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig lastIndexWhere(predicate: (A => Boolean | Null)) => Number | Null lastIndexWhere(predicate: A => Boolean | Null, end: Number) => Number | Null ``` ## [](#description)Description Searches, right-to-left, for the first element that matches a provided [predicate function](../../../fql/functions/#predicates) and returns the index of the element if a match is found. If the optional start index is provided, the method searches right-to-left starting at index and returns the first matching index (inclusive). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax.Returns Boolean or Null.If the predicate evaluates to true for an element, the element is considered a match. | | end | Number | | Starting index (inclusive) of the right-to-left search. Must be an Int. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Index of the element that matches the provided predicate. | | Null | Returned if a match isn’t found. | ## [](#examples)Examples ```fql ['a', 'b', 'c', 'b'].lastIndexWhere(v => v == 'b') ``` ``` 3 ``` # `array.lastWhere()` Get the last element of an [Array](../../../fql/types/#array) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig lastWhere(predicate: (A => Boolean | Null)) => A | Null ``` ## [](#description)Description Gets the last element of the calling [Array](../../../fql/types/#array) that matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts an Array element as its only argument. You can pass in this argument using arrow function syntax. Supports shorthand-syntax for objects and documents.Returns Boolean or Null.The method returns the last Array element for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Last element of the Array that matches the predicate. | | Null | Returned if no Array element matches the predicate or the Array is empty. | ## [](#examples)Examples ```fql let iter = [1, 2, 3, 4] iter.lastWhere(v => v > 2) ``` ``` 4 ``` # `array.map()` Apply a provided [function](../../../fql/functions/) to each element of an [Array](../../../fql/types/#array). Can’t perform writes. ## [](#signature)Signature ```fql-sig map(mapper: (A => B)) => Array ``` ## [](#description)Description Creates an [Array](../../../fql/types/#array) by applying a mapper function to each element in the calling [Array](../../../fql/types/#array). Writes are not permitted. The calling Array isn’t changed. ### [](#array-iteration-methods)Array iteration methods FQL provides several methods for iterating over an Array. [`array.forEach()`](../foreach/), [`array.map()`](./), and [`array.flatMap()`](../flatmap/) are similar but return different values. | Method | Return value | | --- | --- | --- | --- | | array.forEach() | Null. | | array.map() | Array. | | array.flatMap() | Array, flattened by one level. | For examples, see: * [`array.forEach()` vs. `array.map()`](#foreach-vs-map) * [`array.map()` vs. `array.flatMap()`](#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | mapper | Function | true | Anonymous FQL function to call on each element of the calling Array. Each call returns a value that’s returned in the result Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing values returned by each mapper function call. | ## [](#examples)Examples ### [](#basic)Basic 1. Create an [Array](../../../fql/types/#array) by mapping [Array](../../../fql/types/#array) elements to sub[Array](../../../fql/types/#array)s that are constructed from the element value and the element value plus one, using an anonymous [Function](../../../fql/types/#func): ```fql [1, 2, 3].map(x => [x, x + 1]) ``` ``` [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ] ] ``` 2. Create an [Array](../../../fql/types/#array) by passing a top-level object method as the mapping [Function](../../../fql/types/#func): ```fql [{name: "D"}, {name: "E"}].map(Collection.create) ``` ``` [ { name: "D", coll: Collection, ts: Time("2099-02-18T20:06:25.620Z"), indexes: {}, constraints: [], history_days: 0 }, { name: "E", coll: Collection, ts: Time("2099-02-18T20:06:25.620Z"), indexes: {}, constraints: [], history_days: 0 } ] ``` ### [](#foreach-vs-map)`array.forEach()` vs. `array.map()` You can use both [`array.forEach()`](../foreach/) and [`array.map()`](./) to iterate through an Array. However, each method returns a different value type. [`array.forEach()`](../foreach/) returns `null`: ```fql // Create an Array of objects that contain category data. let categories = [ { "name": "Electronics", "description": "Bargain electronics!" }, { "name": "Books", "description": "Bargain books!" } ] // Use `forEach()` to create a `Category` collection document for each // element of the previous Array. categories.forEach(doc => Category.create({ doc })) ``` ``` null ``` Although it returns `null`, [`array.forEach()`](../foreach/) still performed the requested operations. To verify: ```fql // Get all `Category` collection documents Category.all() ``` ``` // The results contain `Customer` documents created by // the previous `forEach()` call. { data: [ ... { id: "410665732340187209", coll: Category, ts: Time("2099-10-02T20:16:51.560Z"), products: "hdW...", name: "Electronics", description: "Bargain electronics!" }, { id: "410665732340188233", coll: Category, ts: Time("2099-10-02T20:16:51.560Z"), products: "hdW...", name: "Books", description: "Bargain books!" } ] } ``` [`array.map()`](./) returns an [Array](../../../fql/types/#array): ```fql // Create an Array of objects that contain category data. let categories = [ { "name": "Movies", "description": "Bargain movies!" }, { "name": "Music", "description": "Bargain music!" } ] // Use `map()` to create a `Category` collection document for each // element of the previous Array. categories.map(doc => Category.create({ doc })) ``` In this case, the Array contains documents created by the [`array.map()`](./) call: ``` [ { id: "410655308219678797", coll: Category, ts: Time("2099-10-02T17:31:10.366Z"), products: "hdW...", name: "Movies", description: "Bargain movies!" }, { id: "410655308219679821", coll: Category, ts: Time("2099-10-02T17:31:10.366Z"), products: "hdW...", name: "Music", description: "Bargain music!" } ] ``` ### [](#map-vs-flatmap)`array.map()` vs. `array.flatMap()` [`array.flatMap()`](../flatmap/) is similar to [`array.map()`](./), except [`array.flatMap()`](../flatmap/) also flattens the resulting Array by one level. In the following example, [`array.map()`](./) returns a two-dimensional Array: ```fql // Create an Array of product names. let products = [ "limes", "avocados" ] // Use `map()` to get a Set of matching `Product` collection // documents for each name. Convert each Set to an Array. products.map(product => { Product.byName(product).toArray() }) ``` ``` // Two-dimensional Array. [ [ { id: "777", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("789") } ], [ { id: "444", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] ] ``` To flatten the result to a one-dimensional array, use [`array.flatMap()`](../flatmap/) instead: ```fql // Create an Array of product names. let products = [ "limes", "avocados" ] // Use `flatMap()` to get a Set of matching `Product` collection // documents for each name. Convert each Set to an Array. // Then flatten the resulting Array by one level. products.flatMap(product => { Product.byName(product).toArray() }) ``` ``` // One-dimensional Array. [ { id: "777", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("789") }, { id: "444", coll: Product, ts: Time("2099-10-02T19:37:36.357Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] ``` # `array.nonEmpty()` Test if an [Array](../../../fql/types/#array) is not empty. ## [](#signature)Signature ```fql-sig nonEmpty() => Boolean ``` ## [](#description)Description Tests if the calling [Array](../../../fql/types/#array) is not empty. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Array is not empty. Otherwise, false. | ## [](#examples)Examples ```fql let iter = [] iter.nonEmpty() ``` ``` false ``` # `array.order()` Sort an [Array](../../../fql/types/#array)'s elements. ## [](#signature)Signature ```fql-sig order(ordering: ...(A => Any) & {}) => Array ``` ## [](#description)Description Creates a sorted [Array](../../../fql/types/#array) by applying one or more sorting criteria to the calling [Array](../../../fql/types/#array). You define each sorting criterion by wrapping `asc()` (ascending) or `desc()` (descending) around a read-only [anonymous function](../../../fql/functions/). The first criterion has the highest sorting priority, with priority decreasing for each subsequent criterion. The calling Array remains unchanged. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | ordering | Generic | | One or more sorting criteria, separated by commas.Each criterion is a read-only anonymous function, optionally wrapped in asc() (ascending) or desc() (descending) to indicate sort order.If neither asc() or desc() is provided, asc() is used by default.The anonymous function is passed each Array element as an argument. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | New Array with elements in requested order. | ## [](#examples)Examples Order the Array elements returned by the function in ascending order. ```fql [3, 1, 2, 4].order(asc(v => v)) ``` ``` [ 1, 2, 3, 4 ] ``` # `array.prepend()` Prepend an element to an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig prepend(element: A) => Array ``` ## [](#description)Description Prepends an element to an [Array](../../../fql/types/#array) instance. The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Element to prepend to the Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array with the prepended element. | ## [](#examples)Examples ```fql [2, 3].prepend(1) ``` ``` [ 1, 2, 3 ] ``` # `array.reduce()` Reduce an [Array](../../../fql/types/#array) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from left to right. Uses the first element as the initial value. ## [](#signature)Signature ```fql-sig reduce(reducer: ((A, A) => A)) => A | Null ``` ## [](#description)Description Iterates through each element in an [Array](../../../fql/types/#array) to perform a rolling operation. For example, you can use `reduce()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `reduce()` calls a reducer callback function on every element of the Array from left to right. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. The first element in the Array serves as the initial accumulator. * The current element’s value. The method returns the result of the last iteration. The calling Array isn’t changed. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce an Array to a single value. These methods include: * [`array.fold()`](../fold/) * [`array.foldRight()`](../foldright/) * [`array.reduce()`](./) * [`array.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`array.fold()`](../fold/) and [`array.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`array.reduce()`](./) and [`array.reduceRight()`](../reduceright/) use the array’s first element as the initial _accumulator_. * [`array.fold()`](../fold/) and [`array.reduce()`](./) iterate through the Array’s elements from left to right. [`array.foldRight()`](../foldright/) and [`array.reduceRight()`](../reduceright/) iterate through the Array’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | reducer | Function | true | Anonymous FQL function to call on each element in the Array. | ### [](#reducer-function-parameters)Reducer function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Any | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Any | true | The current element’s value. | ## [](#return)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. | | Null | Returns Null if the calling Array is empty. | ## [](#examples)Examples Reduce the [Array](../../../fql/types/#array) elements to a single value: ```fql ["A", "B", "C"].reduce((prev, cur) => prev + cur) ``` ``` "ABC" ``` # `array.reduceRight()` Reduce an [Array](../../../fql/types/#array) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from right to left. Uses the first element as the initial value. ## [](#signature)Signature ```fql-sig reduceRight(reducer: ((A, A) => A)) => A | Null ``` ## [](#description)Description Iterates through each element in an [Array](../../../fql/types/#array) to perform a rolling operation. For example, you can use `reduceRight()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `reduceRight()` calls a reducer callback function on every element of the Array from right to left. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. The last element in the Array serves as the initial accumulator. * The current element’s value. The method returns the result of the last iteration. The calling Array isn’t changed. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce an Array to a single value. These methods include: * [`array.fold()`](../fold/) * [`array.foldRight()`](../foldright/) * [`array.reduce()`](../reduce/) * [`array.reduceRight()`](./) The methods are similar but have the following differences: * [`array.fold()`](../fold/) and [`array.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`array.reduce()`](../reduce/) and [`array.reduceRight()`](./) use the array’s first element as the initial _accumulator_. * [`array.fold()`](../fold/) and [`array.reduce()`](../reduce/) iterate through the Array’s elements from left to right. [`array.foldRight()`](../foldright/) and [`array.reduceRight()`](./) iterate through the Array’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | reducer | Function | true | Anonymous FQL function to call on each element in the Array. | ### [](#reducer-function-parameters)Reducer function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Any | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Any | true | The current element’s value. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. | | Null | Returns Null if the calling Array is empty. | ## [](#examples)Examples Reduce the [Array](../../../fql/types/#array) elements, right to left: ```fql ["A", "B", "C"].reduceRight((prev, cur) => prev + cur) ``` ``` "CBA" ``` # `array.reverse()` Reverse the order of an [Array](../../../fql/types/#array)'s elements. ## [](#signature)Signature ```fql-sig reverse() => Array ``` ## [](#description)Description Reverses the order of the calling [Array](../../../fql/types/#array)'s elements. The calling Array isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing reversed elements. | ## [](#examples)Examples ```fql [1, 2, 3].reverse() ``` ``` [ 3, 2, 1 ] ``` # `array.slice()` Get a subset of an [Array](../../../fql/types/#array)'s elements based on provided indexes. ## [](#signature)Signature ```fql-sig slice(from: Number) => Array slice(from: Number, until: Number) => Array ``` ## [](#description)Description Creates an [Array](../../../fql/types/#array) from the calling [Array](../../../fql/types/#array) by copying the [Array](../../../fql/types/#array) elements from a provided start index (inclusive) up to the end index (exclusive). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Number | true | Zero-based Array element index to start copying (inclusive). Must be an Int. A negative start index counts from Array element zero. | | until | Int | | Zero-based Array element index to end copying (exclusive). Must be an Int.When the end index is larger than the Array length, all elements are copied from start index to the last Array element. If end index is less than or equal to the start index, an empty Array is returned. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array with elements from the start index to the end index (inclusive) of the calling Array. | ## [](#examples)Examples Create an [Array](../../../fql/types/#array) of the second and third elements of the calling [Array](../../../fql/types/#array): ```fql [1, 2, 3, 4, 5].slice(1,3) ``` ``` [ 2, 3 ] ``` # `array.take()` Get the first _N_ elements of an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig take(limit: Number) => Array ``` ## [](#description)Description Takes the first _N_ elements from the calling [Array](../../../fql/types/#array) and returns them as a new [Array](../../../fql/types/#array). If there are fewer values than _N_ elements in the [Array](../../../fql/types/#array), all elements are returned. The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | limit | Number | true | Number of elements to return from the start of the Array. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing the requested elements. | ## [](#examples)Examples ```fql [1, 2, 3, 4, 5].take(2) ``` ``` [ 1, 2 ] ``` # `array.toSet()` Convert an [Array](../../../fql/types/#array) to a [Set](../../../fql/types/#set). ## [](#signature)Signature ```fql-sig toSet() => Set ``` ## [](#description)Description Converts the calling [Array](../../../fql/types/#array) to a [Set](../../../fql/types/#set). The calling Array isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set representation of the Array instance. | ## [](#examples)Examples ```fql [1, 2].toSet() ``` ``` { data: [ 1, 2 ] } ``` # `array.toString()` Convert an Array to a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description Converts an Array to a [String](../../../fql/types/#string) representation. The calling Array isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String representation of the Array. | ## [](#examples)Examples ```fql [1, 2].toString() ``` ``` "[1, 2]" ``` # `array.where()` Get the elements of an [Array](../../../fql/types/#array) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig where(predicate: (A => Boolean | Null)) => Array ``` ## [](#description)Description Returns an [Array](../../../fql/types/#array) of elements from the calling [Array](../../../fql/types/#array) that match a provided [predicate function](../../../fql/functions/#predicates). The calling Array isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | Yes | Anonymous predicate function that:Accepts an Array element as its only argument. Supports shorthand-syntax for objects and documents.Returns a Boolean or NullThe method returns an Array of elements for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array containing elements of the calling Array that match the predicate. If there are no matching elements, the Array is empty. | ## [](#examples)Examples ```fql [1, 2, 3, 4].where(v => v > 2) ``` ``` [ 3, 4 ] ``` ## [](#see-also)See also [`array.filter()`](../filter/) # Collection | Learn: Collections | | --- | --- | --- | You add data to Fauna as JSON-like [documents](../../../learn/data-model/documents/), stored in [collections](../../../learn/data-model/collections/). ## [](#collection)`Collection` collection Fauna stores user-defined [collections](../../../learn/data-model/collections/) as documents in the `Collection` system collection. These documents have the [CollectionDef](../../fql/types/#collectiondef) type and are an FQL version of the FSL [collection schema](../../fsl/collection/). `Collection` documents have the following FQL structure: ```fql { name: "Customer", alias: "Cust", coll: Collection, ts: Time("2099-10-03T20:45:53.780Z"), computed_fields: { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } }, fields: { name: { signature: "String" }, email: { signature: "String" }, address: { signature: "{ street: String, city: String, state: String, postalCode: String, country: String }" } }, migrations: [ { add_wildcard: {} } ], wildcard: "Any", history_days: 0, ttl_days: 10, document_ttls: true, indexes: { byEmail: { terms: [ { field: ".email", mva: false } ], values: [ { field: ".email", order: "desc", mva: false }, { field: ".name", order: "asc", mva: false } ], queryable: true, status: "complete" }, }, constraints: [ { unique: [ { field: ".email", mva: false } ], status: "active" } ], data: { desc: "The Customer collection definition" } } ``` | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | name | String | | true | Name of the collection. | | alias | String | Null | | | Alias used to reference a collection with a name that conflicts with a reserved schema name. By creating and using an alias, the resource doesn’t have to be renamed. See Schema aliasing. | | coll | String | true | | Collection name: Collection. | | ts | Time | true | | Last time the document was created or updated. | | computed_fields | Object | Null | | | FQL version of the collection schema’s computed fields. See FSL collection schema: Computed field definitions | | fields | Object | Null | | | FQL version of the collection schema’s field definitions. See FSL collection schema: Field definitions. | | migrations | Array | Null | | | FQL version of the collection schema’s migrations block. See FSL collection schema: Migrations block. | | wildcard | String | Null | | | FQL version of the collection schema’s wildcard constraint. See Wildcard constraints. | | history_days | Number | Null | | | Number of days of history to retain for collection documents. When the number of days lapses, document snapshots older than the interval are removed. Does not affect the current version of documents.Defaults to 0 (Retain only current documents). See Document history. | | ttl_days | Number | Null | | | Documents are deleted ttl_days number of days after their last write.Defaults to null (Retained documents indefinitely).See Document time-to-live (TTL). | | document_ttls | Boolean | Null | | | If true, you can write to the ttl field in the collection’s documents.document_ttls does not stop ttl-related deletions or affect ttl values set by the collection schema’s ttl_days field.See Enable or disable ttl writes. | | indexes | Object | Null | | | FQL version of the collection schema’s index definitions. See Index definitions.indexes objects include fields you can use to monitor the index build. See indexes build fields. | | constraints | Array | Null | | | FQL version of the collection schema’s check and unique constraints. See FSL collection schema: Check constraint definitions and FSL collection schema: Unique constraint definitions. | | data | { *: Any } | Null | | | Arbitrary user-defined metadata for the document. | ### [](#build)`indexes` build fields `indexes` objects include fields you can use to monitor the [index build](../../../learn/data-model/indexes/#builds): | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | queryable | Boolean | Null | true | | If true, the index is queryable. If false, the index is not queryable. | | status | Union of pending, active, and failed. | true | | Status of the index build. Possible values are pending, active, and failed. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Collection` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Collection() | Access a collection by its name. | | Collection.all() | Get a Set of all collection definitions. | | Collection.byName() | Get a collection definitions by its name. | | Collection.create() | Create a collection. | | Collection.firstWhere() | Get the first collection definition that matches a provided predicate. | | Collection.toString() | Get "Collection" as a String. | | Collection.where() | Get a Set of collection definitions that match a provided predicate. | ## [](#instance-properties)Instance properties `Collection` documents have the following properties. You access the property using an existing collection’s name. | Property | Description | | --- | --- | --- | --- | | collection.definition | Get a collection definition, represented as a Collection document with the CollectionDef type. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage collection definitions, represented as `Collection` documents, in FQL. You call the methods on a [CollectionDef](../../fql/types/#collectiondef). | Method | Description | | --- | --- | --- | --- | | collectionDef.delete() | Delete a collection. | | collectionDef.exists() | Test if a collection exists. | | collectionDef.replace() | Replaces a collection definition. | | collectionDef.update() | Update a collection definition. | ## [](#name-methods)Collection name methods You can use the following collection name methods to create and manage documents within a user-defined collection using FQL. You call the methods directly on an existing collection’s name. | Method | Description | | --- | --- | --- | --- | | collection.all() | Get a Set of all documents in a collection. | | collection.byId() | Get a collection document by its document id. | | collection.create() | Create a collection document. | | collection.createData() | Create a collection document from an object that may contain metadata fields. | | collection.firstWhere() | Get the first collection document that matches a provided predicate. | | collection.where() | Get a Set of collection documents that match a provided predicate. | | collection.indexName() | Call an index as a method to get a Set of matching collection documents. | # `collection.definition` | Learn: Collections | | --- | --- | --- | Get a [collection definition](../../../../learn/data-model/collections/), represented as a [`Collection` document](../#collection) with the [CollectionDef](../../../fql/types/#collectiondef) type. ## [](#signature)Signature ```fql-sig .definition: CollectionDef ``` ## [](#description)Description A collection’s schema, represented as a [`Collection` document](../#collection) with the [CollectionDef](../../../fql/types/#collectiondef) type. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). You access the `.definition` property using an existing collection’s name. ### [](#definition-properties)Definition properties You can use [dot or bracket notation](../../../fql/dot-notation/#dot-notation-field-accessor) to access specific fields in the definition. See [Access definition properties](#access). ### [](#definition-methods)Definition methods The `definition` property supports [collection instance methods](../#instance-methods). ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | CollectionDef | Definition for the collection, represented as a Collection document. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Get the definition for // the `Customer` collection. Customer.definition ``` ``` { name: "Customer", coll: Collection, ts: Time("2099-10-03T20:45:53.780Z"), history_days: 0, fields: { name: { signature: "String" }, email: { signature: "String" }, address: { signature: "{ street: String, city: String, state: String, postalCode: String, country: String }" } }, wildcard: "Any", computed_fields: { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } }, indexes: { byEmail: { terms: [ { field: ".email", mva: false } ], values: [ { field: ".email", order: "desc", mva: false }, { field: ".name", order: "asc", mva: false } ], queryable: true, status: "complete" }, }, ttl_days: 10, constraints: [ { unique: [ { field: ".email", mva: false } ], status: "active" } ], document_ttls: true, migrations: [ { add_wildcard: {} } ] } ``` ### [](#access)Access definition properties Use [dot or bracket notation](../../../fql/dot-notation/#dot-notation-field-accessor) to access specific fields in the definition: ```fql // Access `computed_fields` definitions for // the `Customer` collection. Customer.definition.computed_fields ``` ``` // Only returns computed field definitions. { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } } ``` # `Collection()` | Learn: Collections | | --- | --- | --- | Access a [collection](../../../../learn/data-model/collections/) by its name. ## [](#signature)Signature ```fql-sig Collection(collection: String) => Any ``` ## [](#description)Description Accesses a collection by its name. You can chain [collection name methods](../#name-methods) to the returned collection. ### [](#errors)Errors If you attempt to access a collection that doesn’t exist, Fauna returns a query runtime error with an `invalid_argument` [error code](../../../http/reference/errors/) and a 400 HTTP status code: ``` invalid_argument error: invalid argument `collection`: No such user collection `Foo`. at *query*:1:11 | 1 | Collection("Foo") | ^^^^^^^ | ``` ### [](#comparison-to-collectionname)Comparison to `` Calling `Collection()` is similar to accessing `` directly, except: * `Collection()` returns an [Any](../../../fql/types/#any) value * `` is a [Collection](../../../fql/types/#collection) value This difference only affects static typing, not runtime behavior. Both `Collection()` and `` support the same [collection name methods](../#name-methods). In most cases, you should use ``. However, `Collection()` is useful if you need to iterate through a list of collection names. See [Dynamically specify a collection name](#iterate). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | collection | String | true | Collection name. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | The named collection. You can chain collection name methods to the returned collection. | ## [](#examples)Examples `Collection()` returns an [Any](../../../fql/types/#any) value. For example: ```fql Collection("Product") ``` Returns an [Any](../../../fql/types/#any) value: ``` Product ``` ### [](#difference-with-collectionname)Difference with `` Accessing `` directly returns a similar value, typed as a [Collection](../../../fql/types/#collection). For example: ```fql Product ``` Returns the `Product` [Collection](../../../fql/types/#collection) value: ``` Product ``` ### [](#method-chaining)Method chaining In most cases, you’ll chain other [collection name methods](../#name-methods) to `Collection()`. For example: ```fql let produce = Category.byName("produce").first() Collection("Product").create({ name: "zebra pinata", description: "Giant Zebra Pinata", price: 23_99, stock: 0, category: produce }) ``` Returns an [Any](../../../fql/types/#any) value: ``` { id: "12345", coll: Product, ts: Time("2099-06-24T21:21:37.170Z"), name: "zebra pinata", description: "Giant Zebra Pinata", price: 2399, stock: 0, category: Category("789") } ``` ### [](#iterate)Dynamically specify a collection name Use `Collection()` to dynamically specify collection names in a query. For example, the following [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) uses `Collection()` to pass a collection name as an argument: ```fsl // Accepts a collection name as an argument. function getPriceLowtoHigh(collection) { // Uses `Collection()` to dynamically specify // the collection name. Collection(collection).sortedByPriceLowToHigh() { price, name, description } } ``` The following query calls the function: ```fql // Calls the `getPriceLowtoHigh()` UDF with // a `Product` collection argument. getPriceLowtoHigh("Product") ``` # `Collection.all()` | Learn: Collections | | --- | --- | --- | Get a Set of all [collection definitions](../../../../learn/data-model/collections/). ## [](#signature)Signature ```fql-sig Collection.all() => Set Collection.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [collection definitions](../../../../learn/data-model/collections/), represented as [`Collection` documents](../), for the database. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). To limit the Set, you can provide an optional range of [`Collection` documents](../). If this method is the last expression in a query, the first page of the [Set](../../../fql/types/#set) is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Collection documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Collection.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all collection definitions are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Collection document. | | to | Any | | End of the range (inclusive). Must be an Collection document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Collection documents in the provided range. If a range is omitted, all collection definitions are returned.The Set is empty if:The database has no collection definitions.There are no collection definitions in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all collection definitions for the database: ```fql Collection.all() ``` ``` { data: [ { name: "Customer", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "Product", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "Category", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "Order", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "OrderItem", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... } ] } ``` 2. Given the previous Set, get all collection definitions starting with `Order`: ```fql Collection.all({ from: Collection.byName("Category") }) ``` ``` { data: [ { name: "Category", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "Order", coll: Collection, ts: Time("2099-07-30T22:08:57.650Z"), ... }, { name: "OrderItem", coll: Collection, ts: Time("2099-07-30T22:08:57.650Z"), ... } ] } ``` 3. Get the Set of collection definitions from `Product` to `Manager`, inclusive: ```fql Collection.all({ from: Collection.byName("Category"), to: Collection.byName("Order") }) ``` ``` { data: [ { name: "Category", coll: Collection, ts: Time("2099-07-30T22:04:31.325Z"), ... }, { name: "Order", coll: Collection, ts: Time("2099-07-30T22:08:57.650Z"), ... } ] } ``` # `Collection.byName()` | Learn: Collections | | --- | --- | --- | Get a [collection definitions](../../../../learn/data-model/collections/) by its name. ## [](#signature)Signature ```fql-sig Collection.byName(name: String) => NamedRef ``` ## [](#description)Description Gets a [collection definitions](../../../../learn/data-model/collections/), represented as a [`Collection` document](../), by its name. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | name | String | true | name of a Collection document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NamedRef | Resolved reference to a Collection document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Collection.byName("Product") ``` ``` { name: "Product", coll: Collection, ts: Time("2099-07-30T22:55:21.520Z"), history_days: 0, constraints: [ { unique: [ { field: ".name", mva: false } ], status: "active" }, { check: { name: "stockIsValid", body: "(product) => product.stock >= 0" } }, { check: { name: "priceIsValid", body: "(product) => product.price > 0" } } ], indexes: { byCategory: { terms: [ { field: ".category", mva: false } ], queryable: true, status: "complete" }, sortedByCategory: { values: [ { field: ".category", order: "asc", mva: false } ], queryable: true, status: "complete" }, byName: { terms: [ { field: ".name", mva: false } ], queryable: true, status: "complete" }, sortedByPriceLowToHigh: { values: [ { field: ".price", order: "asc", mva: false }, { field: ".name", order: "asc", mva: false }, { field: ".description", order: "asc", mva: false }, { field: ".stock", order: "asc", mva: false } ], queryable: true, status: "complete" } }, fields: { name: { signature: "String" }, description: { signature: "String" }, price: { signature: "Int" }, category: { signature: "Ref" }, stock: { signature: "Int" } } } ``` # `Collection.create()` | Learn: Collections | | --- | --- | --- | Create a [collection](../../../../learn/data-model/collections/). ## [](#signature)Signature ```fql-sig Collection.create(data: { name: String, alias: String | Null, computed_fields: { *: { body: String, signature: String | Null } } | Null, fields: { *: { signature: String, default: String | Null } } | Null, migrations: Array<{ backfill: { field: String, value: String } } | { drop: { field: String } } | { split: { field: String, to: Array } } | { move: { field: String, to: String } } | { add: { field: String } } | { move_conflicts: { into: String } } | { move_wildcard: { into: String } } | { add_wildcard: {} }> | Null, wildcard: String | Null, history_days: Number | Null, ttl_days: Number | Null, document_ttls: Boolean | Null, indexes: { *: { terms: Array<{ field: String, mva: Boolean | Null }> | Null, values: Array<{ field: String, mva: Boolean | Null, order: "asc" | "desc" | Null }> | Null, queryable: Boolean | Null } } | Null, constraints: Array<{ unique: Array | Array<{ field: String, mva: Boolean | Null }> } | { check: { name: String, body: String } }> | Null, data: { *: Any } | Null }) => CollectionDef ``` ## [](#description)Description Creates a [collection](../../../../learn/data-model/collections/) with a provided collection definition, represented as a [`Collection` document](../). `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). You can’t create a collection and use it in the same query. Use separate queries instead. ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method adds a collection to the staged schema, not the active schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. Unstaged schema changes that trigger an [index build](../../../../learn/data-model/indexes/#builds) may result in downtime where the index is not queryable. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the new Collection document.For supported document fields, see Collection collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | CollectionDef | The new Collection document. | ## [](#examples)Examples Create a collection named `Inventory` without defining fields for the collection: ```fql Collection.create({ name: "Inventory" }) ``` ``` { name: "Inventory", coll: Collection, ts: Time("2099-02-18T20:49:36.680Z"), history_days: 0, indexes: {}, constraints: [] } ``` Fields can be added and changed with the [`document.update()`](../../document/update/) and [`document.replace()`](../../document/replace/) methods. ## [](#see-also)See also [`collectionDef.delete()`](../delete/) # `Collection.firstWhere()` | Learn: Collections | | --- | --- | --- | Get the first [collection definition](../../../../learn/data-model/collections/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Collection.firstWhere(pred: (CollectionDef => Boolean)) => CollectionDef | Null ``` ## [](#description)Description Gets the first [collection definition](../../../../learn/data-model/collections/), represented as a [`Collection` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Collection document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Collection document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | CollectionDef | First Collection document that matches the predicate. | | Null | No Collection document matches the predicate. | ## [](#examples)Examples ```fql Collection.firstWhere(.name.includes('Prod')) ``` ``` { name: "Product", coll: Collection, ts: Time("2099-04-10T14:13:05.740Z"), ... } ``` # `Collection.toString()` | Learn: Collections | | --- | --- | --- | Get `"Collection"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Collection.toString() => String ``` ## [](#description)Description Returns the name of the [`Collection` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Collection" | ## [](#examples)Examples ```fql Collection.toString() ``` ``` "Collection" ``` # `Collection.where()` | Learn: Collections | | --- | --- | --- | Get a Set of [collection definitions](../../../../learn/data-model/collections/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Collection.where(pred: (CollectionDef => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [collection definitions](../../../../learn/data-model/collections/), represented as [`Collection` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). If this method is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Collection document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Collection documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Collection documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Collection.where(.name.includes('Prod')) ``` ``` { data: [ { name: "Product", coll: Collection, ts: Time("2099-04-10T17:01:11.995Z"), ... } ] } ``` # `collectionDef.delete()` | Learn: Collections | | --- | --- | --- | Delete a [collection](../../../../learn/data-model/collections/). ## [](#signature)Signature ```fql-sig delete() => NullCollectionDef ``` ## [](#description)Description Deletes a [collection](../../../../learn/data-model/collections/), represented as a [`Collection` document](../). `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#staged-schema)Staged schema You can’t delete a collection while a database has [staged schema](../../../../learn/schema/manage-schema/#staged). If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullCollectionDef | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql Collection.byName("Category")!.delete() ``` ``` Collection.byName("Category") /* deleted */ ``` # `collectionDef.exists()` | Learn: Collections | | --- | --- | --- | Test if a [collection](../../../../learn/data-model/collections/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if a collection definition, represented as a [`Collection` document](../), exists. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Collection document exists. If false, the Collection document doesn’t exist. | ## [](#examples)Examples ```fql Collection.byName("Product").exists() ``` ``` true ``` # `collectionDef.replace()` | Learn: Collections | | --- | --- | --- | Replaces a [collection definition](../../../../learn/data-model/collections/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => CollectionDef ``` ## [](#description)Description Replaces all fields in a [collection definition](../../../../learn/data-model/collections/), represented as a [`Collection` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `coll` and `ts` metadata fields, are removed. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#metadata-fields)Metadata fields You can’t use this method to replace the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a collection while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. Unstaged schema changes that trigger an [index build](../../../../learn/data-model/indexes/#builds) may result in downtime where the index is not queryable. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object containing valid Collection document fields. | true | Fields for the Collection document. Fields not present, excluding the coll and ts metadata fields, in the object are removed.For supported document fields, see Collection collection.The object can’t include the following metadata fields:collts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | CollectionDef | Collection document with replaced fields. | ## [](#examples)Examples ```fql Collection.byName("Customer")!.replace({ name: "Customer", history_days: 0, migrations: [ { add_wildcard: {} } ], computed_fields: { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } }, wildcard: "Any", constraints: [ { unique: [ { field: ".email", mva: false } ], status: "active" } ], indexes: { byEmail: { terms: [ { field: ".email", mva: false } ], queryable: true, status: "complete" } }, document_ttls: true, ttl_days: 10, fields: { name: { signature: "String" }, email: { signature: "String" }, address: { signature: "{ street: String, city: String, state: String, postalCode: String, country: String }" } } }) ``` ``` { name: "Customer", coll: Collection, ts: Time("2099-10-03T21:50:53.550Z"), migrations: [ { add_wildcard: {} } ], indexes: { byEmail: { terms: [ { field: ".email", mva: false } ], queryable: true, status: "complete" } }, constraints: [ { unique: [ { field: ".email", mva: false } ], status: "active" } ], wildcard: "Any", ttl_days: 10, computed_fields: { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } }, fields: { name: { signature: "String" }, email: { signature: "String" }, address: { signature: "{ street: String, city: String, state: String, postalCode: String, country: String }" } }, history_days: 0, document_ttls: true } ``` # `collectionDef.update()` | Learn: Collections | | --- | --- | --- | Update a [collection definition](../../../../learn/data-model/collections/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => CollectionDef ``` ## [](#description)Description Updates a [collection definition](../../../../learn/data-model/collections/), represented as a [`Collection` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. `Collection` documents are FQL versions of a database’s FSL [collection schema](../../../fsl/collection/). `Collection` documents have the [CollectionDef](../../../fql/types/#collectiondef) type. See [Collections](../../../../learn/data-model/collections/). ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a collection while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. Unstaged schema changes that trigger an [index build](../../../../learn/data-model/indexes/#builds) may result in downtime where the index is not queryable. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the Collection document.For supported document fields, see the Collection collection.The object can’t include the following metadata fields:collts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | CollectionDef | The updated Collection document. | ## [](#examples)Examples ```fql Collection.byName("Customer")!.update({ ttl_days: 15 }) ``` ``` { name: "Customer", coll: Collection, ts: Time("2099-10-03T20:45:53.780Z"), history_days: 0, fields: { name: { signature: "String" }, email: { signature: "String" }, address: { signature: "{ street: String, city: String, state: String, postalCode: String, country: String }" } }, wildcard: "Any", computed_fields: { cart: { body: "(customer) => Order.byCustomerAndStatus(customer, \"cart\").first()", signature: "Order?" }, orders: { body: "(customer) => Order.byCustomer(customer)", signature: "Set" } }, indexes: { byEmail: { terms: [ { field: ".email", mva: false } ], values: [ { field: ".email", order: "desc", mva: false }, { field: ".name", order: "asc", mva: false } ], queryable: true, status: "complete" }, }, ttl_days: 15, constraints: [ { unique: [ { field: ".email", mva: false } ], status: "active" } ], document_ttls: true, migrations: [ { add_wildcard: {} } ] } ``` # `collection.all()` | Learn: Documents | | --- | --- | --- | Get a Set of all [documents](../../../../learn/data-model/documents/) in a collection. ## [](#signature)Signature ```fql-sig all() => Set all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all documents in a collection. To limit the returned Set, you can provide an optional range. If `all()` is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#built-in-index)Built-in index Fauna implements `.all()` as a built-in [collection index](../../../../learn/data-model/indexes/). The index uses ascending the [document `id`](../../../../learn/data-model/documents/#meta) as its only [index value](../../../../learn/data-model/indexes/#values). The `.all()` index has no [index terms](../../../../learn/data-model/indexes/#terms). Like all indexes, the `.all()` index reads [historical data when queried](../../../../learn/data-model/indexes/#history). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of collection documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all collection documents are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be a document in the collection. | | to | Any | | End of the range (inclusive). Must be a document in the collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | All matching documents in the collection. | ## [](#examples)Examples ### [](#range)Range examples 1. First, get all documents in the collection instance: ```fql Category.all() ``` ``` { data: [ { id: "123", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "party", description: "Party Supplies" }, { id: "456", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "frozen", description: "Frozen Foods" }, { id: "789", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "produce", description: "Fresh Produce" } ] } ``` 2. Provide a range to get all documents beginning with a given document: ```fql let frozen = Category.byName("frozen").first() Category.all({from: frozen}) ``` ``` { data: [ { id: "456", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "frozen", description: "Frozen Foods" }, { id: "789", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "produce", description: "Fresh Produce" } ] } ``` 3. Get all documents beginning up to a given document: ```fql let frozen = Category.byName("frozen").first() Category.all({to: frozen}) ``` ``` { data: [ { id: "123", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "party", description: "Party Supplies" }, { id: "456", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "frozen", description: "Frozen Foods" } ] } ``` 4. Get all documents between the given `from` and `to` range parameters (inclusive): ```fql let party = Category.byName("party").first() let frozen = Category.byName("frozen").first() Category.all({from: party, to: frozen}) ``` ``` { data: [ { id: "123", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "party", description: "Party Supplies" }, { id: "456", coll: Category, ts: Time("2099-07-30T21:56:38.130Z"), products: "hdW...", name: "frozen", description: "Frozen Foods" } ] } ``` # `collection.byId()` | Learn: Documents | | --- | --- | --- | Get a collection document by its [document `id`](../../../../learn/data-model/documents/#meta). ## [](#signature)Signature ```fql-sig byId(id: ID) => Ref ``` ## [](#description)Description Gets a [collection document](../../../../learn/data-model/documents/) by its [document `id`](../../../../learn/data-model/documents/#meta). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | id | ID | true | ID of the collection document to retrieve.The ID must be a Int or String that be coerced into a 64-bit unsigned integer in the 253-1 range. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Ref | Resolved reference to the collection document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples Get document by ID: ```fql Product.byId("111") ``` ``` { id: "111", coll: Product, ts: Time("2099-06-25T20:23:49.070Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") } ``` Get document by [Int](../../../fql/types/#integer) value assigned to `id`: ```fql let id = 12345 let produce = Category.byName("produce").first() Product.create({ id: id, name: "key lime", description: "Organic, 1 ct", price: 79, category: produce, stock: 2000 }) Product.byId(id) ``` ``` { id: "12345", coll: Product, ts: Time("2099-10-25T16:52:26.510Z"), name: "key lime", description: "Organic, 1 ct", price: 79, category: Category("789"), stock: 2000 } ``` # `collection.create()` | Learn: Documents | | --- | --- | --- | Create a [collection document](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig create(data: { id: ID | Null, ttl: Time | Null, data: Null, *: Any }) => A ``` ## [](#description)Description Creates a [document](../../../../learn/data-model/documents/) in the collection with the provided document fields. ### [](#reserved-fields)Reserved fields You can’t use this method to write to the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` * `data` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Object containing the document’s fields.For supported fields in user-defined collections, see Document fields.To create a document with a user-provided id, you must use an authentication secret with the create_with_id privilege.The object can’t include the following metadata fields:colltsdata | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | New collection document. | ## [](#examples)Examples ### [](#basic)Basic example ```fql Customer.create({ name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } }) ``` ``` { id: "12345", coll: Customer, ts: Time("2099-02-19T14:53:53.940Z"), cart: null, orders: "hdWCxmVPcmRlcoHKhGpieUN1c3RvbWVygcZidjD09oHNSgW6Vc/c8AIABAD2wYIaZxvNCBoz2yWAEA==", name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } } ``` ### [](#id)Create with ID You can specify a custom `id` when creating a document. The `id` must be unique within the collection: ```fql Customer.create({ id: "999", name: "Jane Doe", email: "jane.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } }) ``` If you don’t specify an `` id` ``, Fauna auto-generates one. To create documents with a custom `id`, you must have the [`create_with_id` privilege](../../../fsl/role/#privilege-actions) on the collection. ### [](#default)Default values A [field definition](../../../../learn/schema/#field-definitions) can set a [default field value](../../../fsl/field-definitions/#default) for documents in a collection: ```fsl collection Customer { // `name` accepts `String` and `Null` values. // If missing, defaults to `unknown`. name: String? = "unknown" email: String } ``` If you don’t provide a value during document creation, the document uses the default: ```fql Customer.create({ // The `name` field is missing. email: "john.doe@example.com" }) ``` ``` { id: "12345", coll: Customer, ts: Time("2099-02-19T14:53:53.940Z"), email: "john.doe@example.com", // `name` defaulted to `unknown`. name: "unknown" } ``` If you provide an explicit `null` value, the field is `null`. Fields with `null` values aren’t stored or returned. ```fql Customer.create({ // `name` is an explicit `null`. name: null, email: "jane.doe@example.com" }) ``` ``` { id: "12345", coll: Customer, ts: Time("2099-02-19T14:53:53.940Z"), // `name` is not stored or returned. email: "jane.doe@example.com" } ``` ## [](#see-also)See also [`ID()`](../../globals/id/) [`newId()`](../../globals/newid/) # `collection.createData()` | Learn: Documents | | --- | --- | --- | Create a [collection document](../../../../learn/data-model/documents/) from an object that may contain [metadata fields](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig createData(data: { *: Any }) => A ``` ## [](#description)Description Creates a document in the collection with user-provided document fields. If the following [metadata fields](../../../../learn/data-model/documents/) are included, they populate the document `data` [Object](../../../fql/types/#object) field: * `id` * `ts` * `ttl` * `data`. Otherwise, the `data` field isn’t instantiated. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Object containing the document’s fields.For supported fields in user-defined collections, see Document fields.To create a document with a user-provided id, you must use an authentication secret with the create_with_id privilege.Fields with keys that match metadata fields are moved to the data field. See Document fields that populate the data field. | ### [](#data)Document fields that populate the `data` field | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | ttl | Time | | Time-to-live (TTL) for the document. Only present if set. If not present or set to null, the document persists indefinitely. | | id | ID | | ID for the document. The ID is a string-encoded, 64-bit unsigned integer in the 253-1 range. The ID is unique within the collection.IDs are assigned at document creation. To create a document with a user-provided id using collection.createData(), you must use a secret with the create_with_id privilege. If not provided, Fauna generates the id. | | | Any supported data type | | User-defined document field. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | New collection document. | ## [](#examples)Examples Create a document with the `id` and `coll` [metadata fields](../../../../learn/data-model/documents/): ```fql Customer.createData({ id: 12345, coll: "Person", name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } }) ``` ``` { id: "412999820218728960", coll: Customer, ts: Time("2099-07-30T22:04:39.400Z"), cart: null, orders: "hdW...", name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" }, data: { coll: "Person", id: 12345 } } ``` `createData()` treats any metadata field as a document field and nests it in the document’s `data` property. # `collection.firstWhere()` | Learn: Documents | | --- | --- | --- | Get the first [collection document](../../../../learn/data-model/documents/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig firstWhere(pred: (A => Boolean)) => A | Null ``` ## [](#description)Description Gets the first collection document that matches a provided [predicate function](../../../fql/functions/#predicates). Performance hint: `collection_scan` Queries that call this method emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example: ``` performance_hint: collection_scan - Using firstWhere() on collection Product can cause a read of every document. See https://docs.fauna.com/performance_hint/collection_scan. at *query*:1:19 | 1 | Product.firstWhere(.name == "limes") | ^^^^^^^^^^^^^^^^^^ | ``` To address the hint, create an [index definition with a `terms`](../../../../learn/data-model/indexes/#exact-match) to look up matching documents instead. For example: ```fsl collection Product { ... // Adds `name` as an index term index byName { terms [.name] values [.name, .price, .description, .stock] } ... } ``` Then call the index in your query. Pass an argument for each term in the index definition. To avoid other performance hints, only [project](../../../fql/projection/) or [map](../../set/map/#project) field values covered by the index definition’s [`values`](../../../../learn/data-model/indexes/#sort-documents): ```fql // Get the first product named "limes" Product.byName("limes").first() { name, price, description, stock } ``` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a collection document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first collection document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Document | First collection document that matches the predicate. | | NullDoc | Document doesn’t exist. Returned when no collection document matches the predicate. See NullDoc. | ## [](#examples)Examples ```fql Product.firstWhere(.stock < 20) ``` ``` { id: "999", coll: Product, ts: Time("2099-07-30T21:56:38.130Z"), name: "taco pinata", description: "Giant Taco Pinata", price: 2399, stock: 10, category: Category("123") } ``` # `collection.where()` | Learn: Documents | | --- | --- | --- | Get a Set of [collection documents](../../../../learn/data-model/documents/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig where(pred: (A => Boolean)) => Set ``` ## [](#description)Description Gets a Set of collection documents that match a provided [predicate function](../../../fql/functions/#predicates). If this method is the last value in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). Performance hint: `collection_scan` Queries that call this method emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example: ``` performance_hint: collection_scan - Using where() on collection Product can cause a read of every document. See https://docs.fauna.com/performance_hint/collection_scan. at *query*:1:14 | 1 | Product.where(.name == "limes") | ^^^^^^^^^^^^^^^^^^ | ``` To address the hint, create an [index definition with a `terms`](../../../../learn/data-model/indexes/#exact-match) to look up matching documents instead. For example: ```fsl collection Product { ... // Adds `name` as an index term index byName { terms [.name] values [.name, .price, .description, .stock] } ... } ``` Then call the index in your query. Pass an argument for each term in the index definition. To avoid other performance hints, only [project](../../../fql/projection/) or [map](../../set/map/#project) field values covered by the index definition’s [`values`](../../../../learn/data-model/indexes/#sort-documents): ```fql // Get products named "limes" Product.byName("limes") { name, price, description, stock } ``` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:* Accepts a collection document as its only argument. Supports shorthand-syntax. * Returns a Boolean value.The method returns collection documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of collection documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Product.where(.stock < 20) ``` ``` { data: [ { id: "999", coll: Product, ts: Time("2099-07-30T21:56:38.130Z"), name: "taco pinata", description: "Giant Taco Pinata", price: 2399, stock: 10, category: Category("123") } ] } ``` # `collection.indexName()` | Learn: Indexes | | --- | --- | --- | Call an [index](../../../../learn/data-model/indexes/) as a method to get a Set of matching collection documents. ## [](#signature)Signature ```fql-sig () => Set (term: B, ... ) => Set (term: B, ..., range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Calls an [index](../../../../learn/data-model/indexes/) by its name as a method to get a Set of matching collection documents. An index stores, or covers, specific document field values for quick retrieval. You can use indexes to filter and sort a collection’s documents in a performant way. The call returns: * Documents with terms that exactly match the provided `term` arguments (if any) * Documents within the specified range of `values` (if provided) * All indexed documents sorted by the index `values` if no arguments are provided ### [](#index-definitions)Index definitions You define an index as part of a [collection schema](../../../fsl/collection/). See [FSL collection schema: Index definitions](../../../fsl/indexes/). You can only call an index that is part of the database’s active schema. ## [](#missing-or-null-values)Missing or null values * **Terms:** If an index definition contains terms, Fauna doesn’t index a document if all its index terms are missing or otherwise evaluate to null. This applies even if the document contains index values. * **Values:** If an index definition contains only values, Fauna indexes all documents in the collection, regardless of whether the document’s index values are missing or otherwise null. ## [](#covered-queries)Covered queries If you only [project](../../../fql/projection/) fields that are covered by the index terms or values, Fauna can retrieve the data directly from the index without reading the documents. These are called "covered queries" and are more performant. A query is uncovered if: * It projects fields not included in the index definition. * It has no projection, which means it returns entire documents. Uncovered queries require additional document reads and are typically more expensive. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | term | Generic | true | Arguments that exactly match the index terms defined in the index definition. Must be provided in the same order as defined in the index definition. Required if the index definition includes terms.Use a comma to separate term arguments when passing multiple terms. | | range | Object | | Specifies a range of values to match in the form { from: start, to: end } where:from: The start of the range (inclusive)to: The end of the range (inclusive)Both from and to can be single values or Arrays of values matching the index values in the index definition.When using Arrays, values are compared in order:Documents are first compared against the first Array element.If documents have matching first values, they are compared against subsequent Array elements.For range searches on indexes with descending order values, pass the higher value in from.Omit from or to to run unbounded range searches. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of matching collection documents. Results are sorted according to the index values defined in the index definition. | ## [](#examples)Examples ### [](#basic-example)Basic example You define an index in an FSL [collection schema](../../../fsl/collection/): ```fsl collection Product { ... index byName { terms [.name] } ... } ``` Once the index is [built](../../../../learn/data-model/indexes/#builds), you call it as a method on the collection: ```fql // Call the `byName()` index to fet `Product` collection // documents with a `name` value of `limes`. Values must // match exactly. Product.byName("limes") ``` The call returns a Set of matching collection documents. ### [](#use-index-terms-for-exact-match-searches)Use index terms for exact match searches You can use index terms to run exact match searches on document field values. The following index definition includes `name` as an index term: ```fsl collection Product { ... index byName { terms [.name] } ... } ``` When you call the index, you must pass an argument for each term in the index definition. ```fql // Get products named "limes" Product.byName("limes") ``` The call returns a Set of `Product` collection documents with a `name` of `limes`. ### [](#pass-multi-terms)Pass multiple index terms The following index definition includes two index terms: ```fsl collection Customer { ... index byName { terms [.firstName, .lastName] } } ``` In an index call, use a comma to separate term arguments. Provide arguments in the same field order used in the index definition. ```fql // Get customers named "Alice Appleseed" Customer.byName("Alice", "Appleseed") ``` The call returns a Set of matching collection documents. ### [](#use-index-values-for-sorting-and-range-searches)Use index values for sorting and range searches You can use index values to sort a collection’s documents. You can also use index values for range searches. ### [](#sort-documents)Sort documents The following index definition includes several index values: ```fsl collection Product { ... index sortedByPriceLowToHigh { values [.price, .name, .description] } } ``` Call the `sortedByPriceLowToHigh()` index with no arguments to return `Product` documents sorted by: * Ascending `price`, then …​ * Ascending `name`, then …​ * Ascending `description`, then …​ * Ascending `id` (default) ```fql // Get products by ascending price, name, and description Product.sortedByPriceLowToHigh() ``` ### [](#sort-in-descending-order)Sort in descending order By default, index values sort results in ascending order. To use descending order, use `desc()` in the index definition: ```fsl collection Product { ... index sortedByPriceHighToLow { values [desc(.price), .name, .description] } ... } ``` Call the index with no arguments to return `Product` documents sorted by: * Descending `price`, then …​ * Ascending `name`, then …​ * Ascending `description`, then …​ * Ascending `id` (default) ```fql // Get products by descending price, // ascending name, and ascending description Product.sortedByPriceHighToLow() ``` ### [](#run-a-range-search)Run a range search You can also use index values for range searches. The following index definition includes several index values: ```fsl collection Product { ... index sortedByPriceLowToHigh { values [.price, .name, .description] } } ``` The index specifies `price` as its first value. The following query passes an argument to run a range search on `price`: ```fql // Get products with a price between // 20_00 (inclusive) and 30_00 (inclusive) Product.sortedByPriceLowToHigh({ from: 20_00, to: 30_00 }) ``` If an index value uses descending order, pass the higher value in `from`: ```fql // Get products with a price between // 20_00 (inclusive) and 30_00 (inclusive) in desc order Product.sortedByPriceHighToLow({ from: 30_00, to: 20_00 }) ``` Omit `from` or `to` to run unbounded range searches: ```fql // Get products with a price greater than or equal to 20_00 Product.sortedByPriceLowToHigh({ from: 20_00 }) // Get products with a price less than or equal to 30_00 Product.sortedByPriceLowToHigh({ to: 30_00 }) ``` ### [](#pass-multi-values)Pass multiple index values Use an Array to pass multiple value arguments. Pass the arguments in the same field order used in the index definition. ```fql Product.sortedByPriceLowToHigh({ from: [ 20_00, "l" ], to: [ 30_00, "z" ] }) ``` The index returns any document that matches the first value in the `from` and `to` Arrays. If matching documents have the same values, they are compared against the next Array element value, and so on. For example, the `Product` collection’s `sortedByPriceLowToHigh()` index covers the `price` and `name` fields as index values. The `Product` collection contains two documents: | Document | price | name | | --- | --- | --- | --- | --- | | Doc1 | 4_99 | pizza | | Doc2 | 6_98 | cups | The following query returns both Doc1 and Doc2, in addition to other matching documents: ```fql Product.sortedByPriceLowToHigh({ from: [4_99, "p"] }) ``` The first value (`4_99` and `6_98`) of each document matches the first value (`4_99`) of the `from` Array. Later, you update the document values to: | Document | price | name | | --- | --- | --- | --- | --- | | Doc1 | 4_99 | pizza | | Doc2 | 4_99 | cups | The following query no longer returns Doc2: ```fql Product.sortedByPriceLowToHigh({ from: [4_99, "p"] }) ``` Although the first value (`4_99`) in both documents matches the first value in the `from` Array, the second value (`cups`) in Doc2 doesn’t match the second value (`p`) of the `from` Array. ### [](#run-a-range-search-on-id)Run a range search on `id` All indexes implicitly include an ascending document `id` as the index’s last value. If you intend to run range searches on `id`, we recommend you explicitly include an ascending `id` as the last index value in the index definition, even if you have an otherwise identical index. For example, the following `sortByStock()` and `sortByStockandId()` indexes have the same values: ```fsl collection Product { ... index sortByStock { values [.stock] } index sortByStockandId { values [.stock, .id] } ... } ``` Although it’s not explicitly listed, `sortByStock()` implicitly includes an ascending `id` as its last value. To reduce your costs, Fauna only builds the `sortByStock()` index. When a query calls the `sortByStockandId()` index, Fauna uses the `sortByStock()` index behind the scenes. `sortByStockandId()` only acts as a [virtual index](../../../../learn/data-model/indexes/#virtual-indexes) and isn’t materialized. ### [](#pass-terms-and-values)Pass terms and values If an index has both terms and values, you can run an exact match search on documents in a provided range. The following index definition includes `name` as an index term and `stock` as an index value: ```fsl collection Product { ... index byName { terms [.name] values [.stock] } ... } ``` When you call the index, you must provide a term and can specify an optional range: ```fql // Get products named "donkeypinata" // with a stock between 10 (inclusive) and 50 (inclusive) Product.byName("donkey pinata", { from: 10, to: 50 }) ``` ### [](#covered-queries-2)Covered queries If you [project](../../../fql/projection/) or [map](../../set/map/#project) an index’s covered term or value fields, Fauna gets the field values from the index. The following index definition includes several index values: ```fsl collection Product { ... index sortedByPriceLowToHigh { values [.price, .name, .description] } } ``` The following is a covered query: ```fql // This is a covered query. // `name`, `description`, and `price` are values // in the `sortedByPriceLowToHigh()` index definition. Product.sortedByPriceLowToHigh() { name, description, price } ``` If the projection contains an uncovered field, Fauna must retrieve the field values from the documents. This is an uncovered query: ```fql // This is an uncovered query. // `stock` is not one of the terms or values // in the `sortedByPriceLowToHigh()` index definition. Product.sortedByPriceLowToHigh() { name, stock } ``` Performance hint: `non_covered_document_read` Uncovered queries emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example: ``` performance_hint: non_covered_document_read - .stock is not covered by the Product.sortedByPriceLowToHigh index. See https://docs.fauna.com/performance_hint/non_covered_document_read. at *query*:1:42 | 1 | Product.sortedByPriceLowToHigh() { name, stock } | ^^^^^ | ``` Covered queries are typically faster and less expensive than uncovered queries, which require document reads. If you frequently run uncovered queries, consider adding the uncovered fields to the index definition’s [`values`](../../../../learn/data-model/indexes/#sort-documents). For example: ```fsl collection Product { ... // Adds the `stock` field as an index value. index sortedByPriceLowToHigh { values [.price, .name, .description, .stock] } } ``` #### [](#no-projection-or-mapping)No projection or mapping Index queries without a [projection](../../../fql/projection/) or [mapping](../../set/map/#project) are uncovered. Fauna must read each document returned in the Set. For example: ```fql // This is an uncovered query. // Queries without a projection or mapping // require a document read. Product.byName("limes") ``` Performance hint : `non_covered_document_read` If [performance hints](../../../http/reference/query-summary/#perf) are enabled, index queries without a projection or mapping emit a performance hint. For example: ``` performance_hint: non_covered_document_read - Full documents returned from Product.byName. See https://docs.fauna.com/performance_hint/non_covered_document_read. at *query*:1:15 | 1 | Product.byName("limes") | ^^^^^^^^^ | ``` If you frequently run such queries, consider adding the uncovered fields to the index definition’s [`values`](../../../../learn/data-model/indexes/#sort-documents). For example: ```fsl collection Product { ... index byName { terms [.name] values [.price, .stock, .description] } ... } ``` Then use projection or mapping to only return the fields you need. Given the previous index definition, the following query is covered: ```fql // This is a covered query. // `price`, `stock`, and `description` are values // in the `byName()` index definition. Product.byName("limes") { price, stock, description } ``` #### [](#filter-covered-values)Filter covered values You can use [`set.where()`](../../set/where/) to filter the results of an [index call](../../../../learn/data-model/indexes/#call). If the [`set.where()`](../../set/where/) predicate only accesses fields defined in the index definition’s `terms` and `values`, the query is [covered](../../../../learn/data-model/indexes/#covered-queries). For example, given the following index definition: ```fsl collection Product { ... index byName { terms [.name] values [.price, .description] } ... } ``` The following query is covered: ```fql // Covered query. // Calls the `byName()` index. // Uses `where()` to filter the results of // the index call. The predicates only // access covered terms and values. Product.byName("limes") .where(.description.includes("Conventional")) .where(.price < 500) { name, description, price } ``` The following query is uncovered: ```fql Product.byName("limes") .where(.description.includes("Conventional")) // The `where()` predicate accesses the uncovered // `stock` field. .where(.stock < 100) .where(.price < 500) { name, description, price } ``` To cover the query, add the uncovered field to the index definition’s `values`: ```fsl collection Product { ... index byName { terms [.name] // Adds `stock` to the index's values values [.price, .description, .stock] } ... } ``` #### [](#dynamic-filtering-using-advanced-query-composition)Dynamic filtering using advanced query composition Complex applications may need to handle arbitrary combinations of search criteria. In these cases, you can use [query composition](../../../../learn/query/composition/) to dynamically apply [indexes](../../../../learn/data-model/indexes/) and [filters](../../../../learn/query/patterns/sets/#filters) to queries. The following template uses query composition to: * Automatically select the most selective index * Apply remaining criteria as filters in priority order * Support both index-based and filter-based search patterns The template uses TypeScript and the [JavaScript driver](../../../../build/drivers/js-client/). A similar approach can be used with any [Fauna client driver](../../../../build/drivers/). ```typescript /** * A Javascript object with a sorted list of indexes or filters. * * Javascript maintains key order for objects. * Sort items in the map from most to least selective. */ type QueryMap = Record Query> /** Object to represent a search argument. * * Contains the name of the index to use and the arguments * to pass to it. * * Example: * { name: "by_name", args: ["limes"] } * { name: "range_price", args: [{ from: 100, to: 500 }] } */ type SearchTerm = { name: string args: any[] } /** * Composes a query by prioritizing the most selective index and then * applying filters. * * @param default_query - The initial query to which indexes and filters are applied. * @param index_map - A map of index names to functions that generate query components. * @param filter_map - A map of filter names to functions that generate query components. * @param search_terms - An array of search terms that specify the type and arguments * for composing the query. * @returns The composed query after applying all relevant indices and filters. */ const build_search = ( default_query: Query, index_map: QueryMap, filter_map: QueryMap, search_terms: SearchTerm[] ): Query => { const _search_terms = [...search_terms] // Initialize a default query. Used if no other indexes are applicable. let query: Query = default_query // Iterate through the index map, from most to least selective. build_index_query: for (const index_name of Object.keys( index_map )) { // Iterate through each search term to check if it matches the highest priority index. for (const search_term of _search_terms) { // If a match is found, update the query. Then remove the search term from the // list and break out of the loop. if (index_name === search_term.name) { query = index_map[search_term.name](...search_term.args) _search_terms.splice(_search_terms.indexOf(search_term), 1) break build_index_query } } } // Iterate through the filter map, from most to least selective. for (const filter_name of Object.keys(filter_map)) { // Iterate through each search term to check if it matches the highest priority filter. for (const search_term of _search_terms) { // If a match is found, update the query. Then remove the search term from the list. if (filter_name === search_term.name) { const filter = filter_map[search_term.name](...search_term.args) query = fql`${query}${filter}` _search_terms.splice(_search_terms.indexOf(search_term), 1) } } } // If there are remaining search terms, you can't build the full query. if (_search_terms.length > 0) { throw new Error("Unable to build query") } return query } ``` The following example implements the template using the [Fauna Dashboard](https://dashboard.fauna.com/)'s demo data: ```typescript // Implementation of `index_map` from the template. // Sort items in the map from most to least selective. const product_index_priority_map: QueryMap = { by_order: (id: string) => fql`Order.byId(${id})!.items.map(.product!)`, by_name: (name: string) => fql`Product.byName(${name})`, by_category: (category: string) => fql`Product.byCategory(Category.byName(${category}).first()!)`, range_price: (range: { from?: number; to?: number }) => fql`Product.sortedByPriceLowToHigh(${range})`, } // Implementation of `filter_map` from the template. // Sort items in the map from most to least selective. const product_filter_map: QueryMap = { by_name: (name: string) => fql`.where(.name == ${name})`, by_category: (category: string) => fql`.where(.category == Category.byName(${category}).first()!)`, range_price: ({ from, to }: { from?: number; to?: number }) => { // Dynamically filter products by price range. if (from && to) { return fql`.where(.price >= ${from} && .price <= ${to})` } else if (from) { return fql`.where(.price >= ${from})` } else if (to) { return fql`.where(.price <= ${to})` } return fql`` }, } // Hybrid implementation of `index_map` and `filter_map` from the template. // Combines filters and indexes to compose FQL query fragments. // Sort items in the map from most to least selective. const product_filter_with_indexes_map: QueryMap = { by_name: (name: string) => fql`.where(doc => Product.byName(${name}).includes(doc))`, by_category: (category: string) => fql`.where(doc => Product.byCategory(Category.byName(${category}).first()!).includes(doc))`, range_price: (range: { from?: number; to?: number }) => fql`.where(doc => Product.sortedByPriceLowToHigh(${range}).includes(doc))`, } const order_id = (await client.query(fql`Order.all().first()!`)) .data.id const query = build_search( fql`Product.all()`, product_index_priority_map, product_filter_with_indexes_map, [ // { type: "by", name: "name", args: ["limes"] }, // { type: "by", name: "category", args: ["produce"] }, { type: "range", name: "price", args: [{ to: 1000 }] }, { type: "by", name: "order", args: [order_id] }, ] ) const res = await client.query(query) ``` # Credential | Learn: Credentials | | --- | --- | --- | A [credential](../../../learn/security/tokens/#credentials) associates a password with an [identity document](../../../learn/security/tokens/#identity-document). You can use the credential and password to create an [authentication token](../../../learn/security/tokens/) for an end user, system, or other identity. ## [](#collection)`Credential` collection Fauna stores credentials as documents in the `Credential` system collection. You can also access this collection using the `Credentials` alias. `Credential` documents have the following FQL structure: ``` { id: "401328088768577609", coll: Credential, ts: Time("2099-06-21T18:39:00.735Z"), document: Customer("401328088729780297") password: "sekret" data: { desc: "Credential for VIP customer" } } ``` | Field name | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | id | ID | | | ID for the Credential document. The ID is a string-encoded, 64-bit unsigned integer in the 253-1 range. The ID is unique within the collection.IDs are assigned at document creation. To create a credential with a user-provided id using Credential.create(), you must use a secret with the create_with_id privilege for the Credential collection. If not provided, Fauna generates the id. | | coll | Collection | true | | Collection name: Credential. | | ts | Time | true | | Last time the document was created or updated. | | document | Ref< { *: Any } > | | true | Reference to the credential’s identity document. The identity document can be in any user-defined collection. | | password | String | Null | | | End-user password to associate with the credential’s identity document. Only provided when creating, replacing, or updating a credential.You can use the password to generate a token for the credential using credential.login().Passwords are not returned in Credential documents. | | data | { *: Any } | Null | | | Arbitrary user-defined metadata for the document. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Credential` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Credential.all() | Get a Set of all credentials. | | Credential.byDocument() | Get a credential by its identity document. | | Credential.byId() | Get a credential by its document id. | | Credential.create() | Create a credential. | | Credential.firstWhere() | Get the first credential that matches a provided predicate. | | Credential.toString() | Get "Credential" as a String. | | Credential.where() | Get a Set of credentials that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `Credential` documents in FQL. | Method | Description | | --- | --- | --- | --- | | credential.delete() | Delete a credential. | | credential.exists() | Test if a credential exists. | | credential.login() | Create a token for a provided credential and its password. | | credential.replace() | Replace a credential. | | credential.update() | Update a credential. | | credential.verify() | Test whether a provided password is valid for a credential. | # `Credential.all()` | Learn: Credentials | | --- | --- | --- | Get a Set of all [credentials](../../../../learn/security/tokens/#credentials). ## [](#signature)Signature ```fql-sig Credential.all() => Set Credential.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [credentials](../../../../learn/security/tokens/#credentials), represented as [`Credential` documents](../), for the database. To limit the returned Set, you can provide an optional range. If this method is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Credential documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Credential.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all credentials are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Credential document. | | to | Any | | End of the range (inclusive). Must be an Credential document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Credential documents in the provided range. If a range is omitted, all credentials are returned.The Set is empty if:The database has no credentials.There are no credentials in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all credentials for the database: ```fql Credential.all() ``` ``` { data: [ { id: "401670531158376525", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("111") }, { id: "401670531164667981", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("222") }, { id: "401670531170959437", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("333") } ] } ``` 2. Given the previous Set, get all credentials starting with the credential for `Customer("222")` (inclusive): ```fql Credential.all({ from: Credential.byDocument(Customer.byId("222")) }) ``` ``` { data: [ { id: "401670531164667981", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("222") }, { id: "401670531170959437", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("333") } ] } ``` 3. Get a Set of credentials from the credential for `Customer("111")` (inclusive) to the credential for `Customer("222")` (inclusive): ```fql Credential.all({ from: Credential.byDocument(Customer.byId("111")), to: Credential.byDocument(Customer.byId("222")) }) ``` ``` { data: [ { id: "401670531158376525", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("111") }, { id: "401670531164667981", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("222") } ] } ``` 4. Get a Set of credentials up to the credential for `Customer("222")` (inclusive): ```fql Credential.all({ to: Credential.byDocument(Customer.byId("222")) }) ``` ``` { data: [ { id: "401670531158376525", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("111") }, { id: "401670531164667981", coll: Credential, ts: Time("2099-06-25T13:21:59.270Z"), document: Customer("222") } ] } ``` # `Credential.byDocument()` | Learn: Credentials | | --- | --- | --- | Get a [credential](../../../../learn/security/tokens/#credentials) by its [identity document](../../../../learn/security/tokens/#identity-document). ## [](#signature)Signature ```fql-sig Credential.byDocument(document: { *: Any } | Null) => Ref ``` ## [](#description)Description Gets a [credential](../../../../learn/security/tokens/#credentials), represented as a [`Credential` document](../), by its [identity document](../../../../learn/security/tokens/#identity-document). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | document | Object | true | Identity document for the credential to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Ref | Resolved reference to a Credential document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql let document = Customer.byId("111") Credential.byDocument(document) ``` ``` { id: "401328088781160521", coll: Credential, ts: Time("2099-06-21T18:39:00.735Z"), document: Customer("111") } ``` # `Credential.byId()` | Learn: Credentials | | --- | --- | --- | Get a [credential](../../../../learn/security/tokens/#credentials) by its [document `id`](../../../../learn/data-model/documents/#meta). ## [](#signature)Signature ```fql-sig Credential.byId(id: ID) => Ref ``` ## [](#description)Description Gets a [credential](../../../../learn/security/tokens/#credentials), represented as an [`Credential` document](../), by its [document `id`](../../../../learn/data-model/documents/#meta). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | id | String | true | ID of the Credential document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Ref | Resolved reference to the Credential document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Credential.byId("401328088781160521") ``` ``` { id: "401328088768577609", coll: Credential, ts: Time("2099-06-21T18:39:00.735Z"), document: Customer("111") } ``` # `Credential.create()` | Learn: Credentials | | --- | --- | --- | Create a [credential](../../../../learn/security/tokens/#credentials). ## [](#signature)Signature ```fql-sig Credential.create(data: { id: ID | Null, document: Ref<{ *: Any }>, password: String | Null, data: { *: Any } | Null }) => Credential ``` ## [](#description)Description Creates a [credential](../../../../learn/security/tokens/#credentials) with the provided document fields. Fauna stores credentials as documents in the [`Credential` system collection](../). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the new Credential document.For supported document fields, see Credential collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Credential | The new Credential document. | ## [](#examples)Examples ```fql Credential.create({ document: Customer.byId("111"), password: "sekret" }) ``` ``` { id: "401670627820306505", coll: Credential, ts: Time("2099-06-25T13:23:31.440Z"), document: Customer("111") } ``` # `Credential.firstWhere()` | Learn: Credentials | | --- | --- | --- | Get the first [credential](../../../../learn/security/tokens/#credentials) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Credential.firstWhere(pred: (Credential => Boolean)) => Credential | Null ``` ## [](#description)Description Gets the first [credential](../../../../learn/security/tokens/#credentials), represented as a [`Credential` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Credential document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Credential document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Credential | First Credential document that matches the predicate. | | Null | No Credential document matches the predicate. | ## [](#examples)Examples ```fql Credential.firstWhere(.document == Customer.byId("111")) ``` ``` { id: "371153420791316514", coll: Credential, ts: Time("2099-07-24T17:05:34.890Z"), document: Customer("111") } ``` # `Credential.toString()` | Learn: Credentials | | --- | --- | --- | Get `"Credential"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Credential.toString() => String ``` ## [](#description)Description Returns the name of the [`Credential` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Credential" | ## [](#examples)Examples ```fql Credential.toString() ``` ``` "Credential" ``` # `Credential.where()` | Learn: Credentials | | --- | --- | --- | Get a Set of [credentials](../../../../learn/security/tokens/#credentials) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Credential.where(pred: (Credential => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [credentials](../../../../learn/security/tokens/#credentials), represented as [`Credential` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). If `Credential.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Credential document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Credential documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Credential documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Credential.where(.document == Customer.byId("111")) ``` ``` { data: [ { id: "412654807560487424", coll: Credential, ts: Time("2099-08-11T04:25:08.950Z"), document: Customer("111") } ] } ``` # `credential.delete()` | Learn: Credentials | | --- | --- | --- | Delete a credential. ## [](#signature)Signature ```fql-sig delete() => NullCredential ``` ## [](#description)Description Deletes a [credential](../../../../learn/security/tokens/#credentials), represented as a [`Credential` document](../). A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullCredential | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql Credential.byId("401670627820306505")!.delete() ``` ``` Credential("401670627820306505") /* deleted */ ``` # `credential.exists()` | Learn: Credentials | | --- | --- | --- | Test if a [credential](../../../../learn/security/tokens/#credentials) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if a [credential](../../../../learn/security/tokens/#credentials), represented as an [`Credential` document](../), exists. A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Credential document exists. If false, the Credential document doesn’t exist. | ## [](#examples)Examples ```fql Credential.byId("356573262084309026").exists() ``` ``` true ``` # `credential.login()` | Learn: Credentials | | --- | --- | --- | Create a [token](../../../../learn/security/tokens/) for a provided [credential](../../../../learn/security/tokens/#credentials) and its password. ## [](#signature)Signature ```fql-sig login(secret: String) => Token login(secret: String, ttl: Time) => Token ``` ## [](#description)Description The `login()` method authenticates an identity in Fauna by providing the password for a `Credential` document. Attempts to login with an incorrect password result in an error. Call [`credential.update()`](../update/) to set a new password. This method creates a token when it authenticates an identity. ### [](#required-privileges)Required privileges To call `login()` in a query, your access token must have a role with the `create` privilege for the `Token` system collection. For example: ```fsl role manager { ... privileges Token { create } } ``` The built-in `admin` and `server` roles have this privilege. User-defined functions (UDFs) can be assigned an optional role. If assigned, this role supersedes the access token’s privileges. If a UDF includes `login()`, the UDF’s role must have the `create` privilege for the `Token` collection. ### [](#multiple-tokens)Multiple tokens If you call this method multiple times, it creates multiple tokens. This is because an identity may have multiple tokens that can access multiple devices simultaneously. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | secret | String | true | Credential document password. | | ttl | Time | | Timestamp indicating a document lifespan. When the ttl is reached, Fauna removes it. If ttl isn’t set, its default value is null, which causes the document to persist indefinitely or until deleted. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Token | Token, which includes the token’s secret. | ## [](#examples)Examples The following simplified sequence creates a user and associates credentials with the user, which can then be used to log in. 1. Create a user in the example `Customer` collection: ```fql Customer.create({ name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } }) ``` ``` { id: "999", coll: Customer, ts: Time("2099-07-31T13:16:15.040Z"), cart: null, orders: "hdW...", name: "John Doe", email: "john.doe@example.com", address: { street: "123 Main St", city: "San Francisco", state: "CA", postalCode: "12345", country: "United States" } } ``` 2. Create a user credential, including the password: ```fql Credential.create({ document: Customer.byId("999"), password: "sekret" }) ``` ``` { id: "412654692679549440", coll: Credential, ts: Time("2099-06-25T13:27:23.170Z"), document: Customer("999") } ``` 3. Log in with a password: ```fql let document = Customer.byId("999") Credential.byDocument(document)?.login("sekret") ``` ``` { id: "412654692933304832", coll: Token, ts: Time("2099-07-31T13:17:46.900Z"), document: Customer("111"), secret: "fn..." } ``` # `credential.replace()` | Learn: Credentials | | --- | --- | --- | Replace a [credential](../../../../learn/security/tokens/#credentials). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => Credential ``` ## [](#description)Description Replaces all fields in a [credential](../../../../learn/security/tokens/#credentials), represented as a [`Credential` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `id`, `coll`, and `ts` metadata fields, are removed. A credential associates a password with an [identity document](../../../../learn/security/tokens/#identity-document). You can use credentials and the [`credential.login()`](../login/) method to create [tokens](../../../../learn/security/tokens/) as part of an [end-user authentication system](../../../../build/tutorials/auth/). ### [](#metadata-fields)Metadata fields You can’t use this method to replace the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the Credential document. Fields not present, excluding the id, coll, and ts metadata fields, in the object are removed.For supported document fields, see Credential collection.The object can’t include the following metadata fields:* id * coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Credential | Credential document with replaced fields. | ## [](#examples)Examples ```fql Credential.byId("412654807560487424")!.replace({ document: Customer.byId("111"), password: "sekret" }) ``` ``` { id: "412654807560487424", coll: Credential, ts: Time("2099-07-28T03:42:54.650Z"), document: Customer("111") } ``` # `credential.update()` | Learn: Credentials | | --- | --- | --- | Update a [credential](../../../../learn/security/tokens/#credentials). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => Credential ``` ## [](#description)Description Updates a [credential](../../../../learn/security/tokens/#credentials), represented as a [`Credential` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the Credential document.For supported document fields, see Credential collection.The object can’t include the following metadata fields:* id * coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | The updated Credential document. | ## [](#examples)Examples ```fql Credential.byId("412654807560487424")!.update({ password: "newest-sekret" }) ``` ``` { id: "412654807560487424", coll: Credential, ts: Time("2099-08-14T23:50:22.420Z"), document: Customer("111") } ``` # `credential.verify()` | Learn: Credentials | | --- | --- | --- | Test whether a provided password is valid for a [credential](../../../../learn/security/tokens/#credentials). ## [](#signature)Signature ```fql-sig verify(secret: String) => Boolean ``` ## [](#description)Description Verify a password against a `Credential` document. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | secret | String | true | Password to compare against the credential document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | The secret status. A status of true means the password is valid, while false means it is invalid. | ## [](#examples)Examples ```fql Credential.byId("412654807560487424")!.verify("fauna-demo") ``` ``` true ``` # Database | Learn: Databases and multi-tenancy | | --- | --- | --- | In Fauna, a database stores data as [documents](../../../learn/data-model/documents/) in one or more [collections](../../../learn/data-model/collections/). Fauna databases support a hierarchical database structure with top-level and child databases. ## [](#collection)`Database` collection Fauna stores metadata and settings for a database’s child databases as documents in the `Database` system collection. These documents have the [DatabaseDef](../../fql/types/#databasedef) type. `Database` documents have the following FQL structure: ``` { name: "child_db", coll: Database, ts: Time("2099-06-24T21:53:40.670Z"), typechecked: true, protected: false, priority: 10, global_id: "ysjpygonryyr1", data: { desc: "Prod child database" } } ``` | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | name | String | | true | Name of the database. | | coll | String | true | | Collection name: Database. | | ts | Time | true | | Last time the document was created or updated. | | priority | Number | Null | | | User-defined priority assigned to the database. | | typechecked | Boolean | Null | | | If true, typechecking is enabled for the database. If false, typechecking is disabled.Inherits the parent database’s typechecking setting. | | protected | Boolean | Null | | | If true, protected mode is enabled for the database. If false, protected mode is disabled.Inherits the parent database’s protected mode setting. | | global_id | String | true | | Auto-generated, globally unique ID for the database. See Global database ID. | | data | { *: Any } | Null | | | Arbitrary user-defined metadata for the document. | ## [](#scope)Scope The `Database` collection only contains documents for the direct child databases of the database scoped to your authentication secret. You can’t use the `Database` collection to access parent, peer, or other descendant databases. Using FQL to create or manage top-level databases is not supported. ## [](#static-methods)Static methods You can use the following static methods to manage the `Database` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Database.all() | Deletes a child database. | | Database.byName() | Get a child database by its name. | | Database.create() | Create a child database. | | Database.firstWhere() | Get the first child database document that matches a provided predicate. | | Database.toString() | Get "Database" as a String. | | Database.where() | Get a Set of child databases that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `Database` documents in FQL. | Method | Description | | --- | --- | --- | --- | | database.delete() | Deletes a child database. | | database.exists() | Test if a child database exists. | | database.replace() | Replace a child database's metadata and settings. | | database.update() | Update a child database's metadata and settings. | # `Database.all()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Get a Set of all [child databases](../../../../learn/data-model/databases/#child) nested directly under the database. ## [](#signature)Signature ```fql-sig Database.all() => Set Database.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [child databases](../../../../learn/data-model/databases/#child), represented as [`Database` documents](../), nested directly under the database to which the query’s [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. To limit the returned Set, you can provide an optional range. If this method is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#scope)Scope The `Database` collection only contains documents for the direct child databases of the database scoped to your authentication secret. You can’t use the `Database` collection to access parent, peer, or other descendant databases. Using FQL to create or manage top-level databases is not supported. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Database documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Database.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all credentials are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Database document. | | to | Any | | End of the range (inclusive). Must be an Database document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Database documents in the provided range. If a range is omitted, all credentials are returned.The Set is empty if:The database has no child databases.There are no child databases in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples ```fql Database.all() ``` ``` { data: [ { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), typechecked: true, priority: 10, global_id: "ysjpykbahyyr1" }, ... ] } ``` ```fql Database.all({ from: Database.byName("childDB") }) ``` ``` { data: [ { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), typechecked: true, priority: 10, global_id: "ysjpykbahyyr1" }, ... ] } ``` # `Database.byName()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Get a [child database](../../../../learn/data-model/databases/#child) by its name. ## [](#signature)Signature ```fql-sig Database.byName(name: String) => NamedRef ``` ## [](#description)Description Gets a [child database](../../../../learn/data-model/databases/#child), represented as an [`Database` document](../), by its name. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ### [](#scope)Scope The `Database` collection only contains documents for the direct child databases of the database scoped to your authentication secret. You can’t use the `Database` collection to access parent, peer, or other descendant databases. Using FQL to create or manage top-level databases is not supported. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | name | String | true | name of the Database document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NamedRef | Resolved reference to the Database document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Database.byName("childDB") ``` ``` { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), global_id: "ysjpykbahyyr1", priority: 10, typechecked: true } ``` # `Database.create()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Create a [child database](../../../../learn/data-model/databases/#child). ## [](#signature)Signature ```fql-sig Database.create(data: { name: String, priority: Number | Null, typechecked: Boolean | Null, protected: Boolean | Null, data: { *: Any } | Null }) => DatabaseDef ``` ## [](#description)Description Creates a [child database](../../../../learn/data-model/databases/#child) with the provided metadata and settings. The parent database is the database to which the query’s the [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. Using `Database.create()` to create a top-level database is not supported. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields containing metadata and settings for the new Database document.For supported document fields, see Database collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | DatabaseDef | The new Database document. | ## [](#examples)Examples ```fql Database.create({ name: "childDB", typechecked: true, priority: 10 }) ``` ``` { name: "childDB", coll: Database, ts: Time("2099-06-24T21:53:40.670Z"), typechecked: true, priority: 10, global_id: "ysjpygonryyr1" } ``` # `Database.firstWhere()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Get the first [child database](../../../../learn/data-model/databases/#child) document that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Database.firstWhere(pred: (DatabaseDef => Boolean)) => DatabaseDef | Null ``` ## [](#description)Description Gets the first [child database](../../../../learn/data-model/databases/#child), represented as an [`Database` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ### [](#scope)Scope The `Database` collection only contains documents for the direct child databases of the database scoped to your authentication secret. You can’t use the `Database` collection to access parent, peer, or other descendant databases. Using FQL to create or manage top-level databases is not supported. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Database document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Database document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | DatabaseDef | First Database document that matches the predicate. | | Null | No Database document matches the predicate. | ## [](#examples)Examples ```fql Database.firstWhere(.name.includes("child")) ``` ``` { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), typechecked: true, global_id: "ysjpykbahyyr1", priority: 10 } ``` ```fql Database.firstWhere(childDB => childDB.priority > 5) ``` ``` { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), global_id: "ysjpykbahyyr1", priority: 10, typechecked: true } ``` # `Database.toString()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Get `"Database"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Database.toString() => String ``` ## [](#description)Description Returns the name of the [`Database` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Database" | ## [](#examples)Examples ```fql Database.toString() ``` ``` "Database" ``` # `Database.where()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Get a Set of [child databases](../../../../learn/data-model/databases/#child) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Database.where(pred: (DatabaseDef => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [child databases](../../../../learn/data-model/databases/#child), represented as [`Database` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. If `Database.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#scope)Scope The `Database` collection only contains documents for the direct child databases of the database scoped to your authentication secret. You can’t use the `Database` collection to access parent, peer, or other descendant databases. Using FQL to create or manage top-level databases is not supported. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Database document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Database documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Database documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Database.where(.name.includes("child")) ``` ``` { data: [ { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), global_id: "ysjpykbahyyr1", priority: 10, typechecked: true }, ... ] } ``` ```fql Database.where(childDB => childDB.priority == 10) ``` ``` { data: [ { name: "childDB", coll: Database, ts: Time("2099-06-24T21:54:38.890Z"), typechecked: true, global_id: "ysjpykbahyyr1", priority: 10 }, ... ] } ``` # `database.delete()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Deletes a [child database](../../../../learn/data-model/databases/#child). ## [](#signature)Signature ```fql-sig delete() => NullDatabaseDef ``` ## [](#description)Description Deletes an [child database](../../../../learn/data-model/databases/#child), represented as a [`Database` document](../). The parent database is the database to which the query’s the [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. Using `Database.create()` to create a top-level database is not supported. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ### [](#considerations)Considerations When you delete a database, its data becomes inaccessible and is asynchronously deleted. As part of the deletion process, Fauna recursively deletes: * Any keys scoped to the database. * The database’s child databases, including any nested databases. Deleting a database with a large number of keys can exceed [Transactional Write Ops throughput limits](../../../../manage/plans-billing/plan-details/#throughput-limits). This can cause [throttling errors](../../../http/reference/errors/#rate-limits) with a `limit_exceeded` [error code](../../../http/reference/errors/#error-codes) and a 429 HTTP status code. Deleting a database with a large number of child databases can cause timeout errors with a `time_out` [error code](../../../http/reference/errors/#error-codes) and a 440 HTTP status code. To avoid throttling or timeouts, incrementally delete all keys and child databases before deleting the database. See [delete all keys](../../key/delete/#delete-all-keys) and [delete all child databases](#delete-all-dbs). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullDatabaseDef | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ### [](#basic-ex)Basic example ```fql Database.byName("childDB")!.delete() ``` ``` Database.byName("childDB") /* deleted */ ``` ### [](#delete-all-dbs)Delete all child databases To [avoid timeouts](../../../../learn/data-model/databases/#delete-cons), you can incrementally delete all child databases for a database before deleting the database itself. To stay within [transaction size limits](../../../requirements-limits/#glimits), use [`set.paginate()`](../../set/paginate/) to perform the deletions over several queries instead of one. ```fql // Gets all `Database` system collection documents. // Uses `pageSize()` to limit the page size. // Uses `paginate()` to project the after cursor. let page = Database.all().pageSize(200).paginate() // `paginate()` returns an object. The object's `data` property // contains an Array of `Database` documents. let data = page.data // Use `forEach()` to delete each `Database` document in the // `data` Array. data.forEach(doc => doc.delete()) // Project the `after` cursor returned by `paginate()`. // Use the cursor to iterate through the remaining pages. page { after } ``` ``` { after: "hdWDxoq..." } ``` Subsequent queries use the cursor and [`Set.paginate()`](../../set/static-paginate/) to iterate through the remaining pages: ```fql // Uses `Set.paginate()` to iterate through pages. let page = Set.paginate("hdWDxoq...") let data = page.data data.forEach(doc => doc.delete()) page { after } ``` # `database.exists()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Test if a [child database](../../../../learn/data-model/databases/#child) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if a [child database](../../../../learn/data-model/databases/#child), represented as an [`Database` document](../), exists. The parent database is the database to which the query’s the [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. Using `database.create()` to check the existence of a top-level database is not supported. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Database document exists. If false, the Database document doesn’t exist. | ## [](#examples)Examples ```fql Database.byName("childDB").exists() ``` ``` true ``` ```fql Database.byName("noChildDB").exists() ``` ``` false ``` # `database.replace()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Replace a [child database](../../../../learn/data-model/databases/#child)'s metadata and settings. ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => DatabaseDef ``` ## [](#description)Description Replaces all fields in a [child database](../../../../learn/data-model/databases/#child)'s metadata and settings, represented as an [`Database` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `coll` and `ts` metadata fields, are removed. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Fields for the Database document. Fields not present, excluding the coll and ts metadata fields, in the object are removed.For supported document fields, see Database collection.The object can’t include the following metadata fields:collts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | DatabaseDef | Database document with replaced fields. | ## [](#examples)Examples ```fql Database.byName("childDB")!.replace({name: "childDB2"}) ``` ``` { name: "childDB2", coll: Database, ts: Time("2099-06-24T21:54:13.225Z"), global_id: "ysjpyeykhyyr4" } ``` # `database.update()` | Learn: Databases and multi-tenancy | | --- | --- | --- | Update a [child database](../../../../learn/data-model/databases/#child)'s metadata and settings. ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => DatabaseDef ``` ## [](#description)Description Updates a [child database](../../../../learn/data-model/databases/#child)'s metadata and settings, represented as a [`Database` document](../), with fields from a provided data object. Fauna stores child databases as documents in the parent database’s [`Database` system collection](../). `Database` documents have the [DatabaseDef](../../../fql/types/#databasedef) type. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the Database document.For supported document fields, see Database collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | DatabaseDef | The updated Database document. | ## [](#examples)Examples ```fql Database.byName("childDB")!.update({typechecked: false}) ``` ``` { name: "childDB", coll: Database, ts: Time("2099-06-24T21:58:19.346Z"), priority: 10, global_id: "ysjpykbahyyr1", typechecked: false } ``` # Date [Date](../../fql/types/#date) methods and properties. ## [](#description)Description [Date](../../fql/types/#date) functions are provided to represent dates without a time. ## [](#instance-properties)Instance properties | Method | Description | | --- | --- | --- | --- | | dayOfMonth | Get the day of the month from a Date. | | dayOfWeek | Get the day of the week from a Date. | | dayOfYear | Get the day of the year from a Date. | | month | Get the month of a Date. | | year | Get the year of a Date. | ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Date() | Construct a Date from a ISO 8601 date String. | | Date.fromString() | Construct a Date from a date String. | | Date.today() | Get the current UTC Date. | ## [](#instance-methods)Instance methods | Method | Description | | --- | --- | --- | --- | | date.add() | Add number of days to a Date. | | date.difference() | Get the difference between two Dates. | | date.subtract() | Subtract number of days from a Date. | | date.toString() | Convert a Date to a String. | # `dayOfMonth` Get the day of the month from a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig dayOfMonth: Number ``` ## [](#description)Description Extracts the day-of-month from the instance date. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day of month. | ## [](#examples)Examples ```fql Date('2099-02-10').dayOfMonth ``` ``` 10 ``` # `dayOfWeek` Get the day of the week from a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig dayOfWeek: Number ``` ## [](#description)Description Extracts the day-of-week from the instance date. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day of week.1 = Monday7 = Sunday | ## [](#examples)Examples ```fql Date('2099-02-10').dayOfWeek ``` ``` 2 ``` # `dayOfYear` Get the day of the year from a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig dayOfYear: Number ``` ## [](#description)Description Extracts the day-of-year from the instance date. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day of year. | ## [](#examples)Examples ```fql Date('2099-02-10').dayOfYear ``` ``` 41 ``` # `month` Get the month of a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig month: Number ``` ## [](#description)Description Extract the month from the instance date. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Month part of Date. | ## [](#examples)Examples ```fql Date('2099-02-10').month ``` ``` 2 ``` # `year` Get the year of a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig year: Number ``` ## [](#description)Description Extract the year from the instance date. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Year field of the calling date object. | ## [](#examples)Examples ```fql Date('2099-02-10').year ``` ``` 2099 ``` # `Date()` Construct a [Date](../../../fql/types/#date) from a ISO 8601 date [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Date(date: String) => Date ``` ## [](#description)Description The `Date()` method converts a `YYYY-MM-DD` [String](../../../fql/types/#string) to a [Date](../../../fql/types/#date). The method accepts only a date [String](../../../fql/types/#string) and returns an error if time information is included in the [String](../../../fql/types/#string). [Date](../../../fql/types/#date) objects render to date strings in query responses. This method is equivalent to the [`Date.fromString()`](../fromstring/) method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | date | String | true | Date String in the YYYY-MM-DD format. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Date | Date representation of the string. | ## [](#examples)Examples Convert a date string to a [Date](../../../fql/types/#date): ```fql Date("2099-10-20") ``` ``` Date("2099-10-20") ``` # `Date.fromString()` Construct a [Date](../../../fql/types/#date) from a date [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Date.fromString(date: String) => Date ``` ## [](#description)Description The `Date.fromString()` method converts a `YYYY-MM-DD` date [String](../../../fql/types/#string) to a [Date](../../../fql/types/#date). The method accepts only a date [String](../../../fql/types/#string) and returns an error if time information is included in the [String](../../../fql/types/#string). [Date](../../../fql/types/#date) objects render to date strings in query responses. This method is equivalent to the [`Date.fromString()`](./) method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | date | String | true | Date String in the form yyyy-MM-dd. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Date | Date converted from string representation of the date. | ## [](#examples)Examples Convert a date string to a [Date](../../../fql/types/#date): ```fql Date.fromString("2099-10-20") ``` ``` Date("2099-10-20") ``` # `Date.today()` Get the current UTC [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig Date.today() => Date ``` ## [](#description)Description The `Date.today()` method gets the current [Date](../../../fql/types/#date). The returned [Date](../../../fql/types/#date) is the current [UTC](https://www.itu.int/dms_pubrec/itu-r/rec/tf/R-REC-TF.460-6-200202-I!!PDF-E.pdf) date. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Date | Object representing the Current year, month, and day, in UTC. | ## [](#examples)Examples Get the current date: ```fql Date.today() ``` ``` Date("2099-06-24") ``` # `date.add()` Add number of days to a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig add(amount: Number, unit: String) => Date ``` ## [](#description)Description Adds a number of days to a [Date](../../../fql/types/#date), returning the resulting [Date](../../../fql/types/#date). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Number of units to add to the given date. | | unit | Number | true | Unit for the operation. Must be days (case-sensitive). | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Date | Date with the added days. | ## [](#examples)Examples ```fql Date('2099-02-10').add(19, 'days') ``` ``` Date("2099-03-01") ``` # `date.difference()` Get the difference between two [Date](../../../fql/types/#date)s. ## [](#signature)Signature ```fql-sig difference(start: Date) => Number ``` ## [](#description)Description Subtract a date from the instance date to get the difference in number of days. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | start | Date | true | Date to subtract from the instance date. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Difference between instance date and the provided start date, in days. | ## [](#examples)Examples ```fql Date('2099-02-10').difference(Date('2099-01-01')) ``` ``` 40 ``` # `date.subtract()` Subtract number of days from a [Date](../../../fql/types/#date). ## [](#signature)Signature ```fql-sig subtract(amount: Number, unit: String) => Date ``` ## [](#description)Description Subtracts a provided number of days from a [Date](../../../fql/types/#date). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Number of units to subtract from the given date. | | unit | Number | true | Unit for the operation. Must be days (case-sensitive). | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Date | Resulting date | ## [](#examples)Examples ```fql Date('2099-02-10').subtract(41, 'days') ``` ``` Date("2098-12-31") ``` # `date.toString()` Convert a [Date](../../../fql/types/#date) to a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description Converts the calling [Date](../../../fql/types/#date) to an ISO 8601 [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String representation of the calling Date. | ## [](#examples)Examples ```fql let d = Date("2099-10-20") d.toString() ``` ``` "2099-10-20" ``` # Document | Learn: Documents | | --- | --- | --- | You add data to Fauna as JSON-like [documents](../../../learn/data-model/documents/), stored in [collections](../../../learn/data-model/collections/). ## [](#doc-fields)Document fields All documents contain the `id`, `coll`, `ts`, and optional `ttl` [metadata fields](../../../learn/data-model/documents/#meta). Documents in user-defined collections also typically contain user-defined fields. For example: ``` { id: "392886847463751746", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), ttl: Time("2099-04-15T16:50:12.850Z"), name: "key limes", description: "Conventional, 16 oz bag", price: 299, stock: 100, category: Category("401610017107607625") } ``` | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | id | ID | true | | ID for the document. The ID is a string-encoded, 64-bit unsigned integer in the 253-1 range. The ID is unique within the collection.IDs are assigned at document creation. To create a document with a user-provided id using collection.create(), you must use a secret with the create_with_id privilege. If not provided, Fauna generates the id. | | coll | Collection | true | | Name of the document’s collection. he coll field can’t be indexed. | | ts | Time | true | | Last time the document was created or updated. | | ttl | Time or null | | | Time-to-live (TTL) for the document. Only present if set. If not present or set to null, the document persists indefinitely. | | | Any supported data type | | | User-defined document field.Schema method names and schema metadata field names are reserved and can’t be used as a field name but can be used in nested objects.You can enforce typing and constraints for user-defined fields in a collection using collection schema. | | data | Object | | true | A reserved field that contains all user-defined fields and their values.By default, the data field isn’t returned in query results. However, if typechecking is disabled, you can project the field to return it.The data field does not contain computed fields or metadata fields, such as id, coll, ts, or ttl.You can use the data field to safely nest user-defined fields that have reserved field names, such as id or ttl, in a document. See Data field and Avoid conflicts with reserved fields in the v10 migration docs. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage a document in FQL. | Method | Description | | --- | --- | --- | --- | | document.delete() | Delete a collection document. | | document.exists() | Test if a collection document exists. | | document.replace() | Replace all fields in a collection document. | | document.replaceData() | Replace a collection document using an object that may contain metadata fields. | | document.update() | Update a collection document's fields. | | document.updateData() | Update a collection document using an object that may contain metadata fields. | # `document.delete()` | Learn: Documents | | --- | --- | --- | Delete a [collection document](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig delete() => NullA ``` ## [](#description)Description Deletes a [collection document](../../../../learn/data-model/documents/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullDoc | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples The document exists: ```fql // Uses the `Product` collection's `byName()` index and // the `first()` method to get a single document. let product = Product.byName("cups").first() product!.delete() ``` ``` Product("111") /* deleted */ ``` The document doesn’t exist: ```fql Product.byId("12345")!.delete() ``` ``` document_not_found: Collection `Product` does not contain document with id 12345. error: Collection `Product` does not contain document with id 12345. at *query*:1:13 | 1 | Product.byId("12345")!.delete() | ^^^^^^^^^^ | ``` # `document.exists()` | Learn: Documents | | --- | --- | --- | Test if a [collection document](../../../../learn/data-model/documents/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description The `exists()` method tests if a document instance exists. Use `exists()` to find if the document can be read. If `exists()` returns `false`, there is a corresponding `cause` field that indicates the reason that the document can’t be read. Possible reasons are: * Not found. * Permission denied. If the exists field isn’t present, the document may or may not exist. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | true = The document exists.false = The document doesn’t exist. | ## [](#examples)Examples ```fql // Uses the `Product` collection's `byName()` index and // the `first()` method to get a single document. let product = Product.byName("cups").first() product?.exists() ``` ``` true ``` # `document.replace()` | Learn: Documents | | --- | --- | --- | Replace all fields in a [collection document](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig replace(data: { ttl: Time | Null, data: Null, *: Any }) => A ``` ## [](#description)Description Replaces all fields in an collection document with fields from a provided data object. Fields not present in the data object, excluding the `id`, `coll`, `ts`, and `data` metadata fields, are removed. ### [](#metadata-fields)Metadata fields You can’t use this method to replace the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` ### [](#reserved-fields)Reserved fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the collection document. Fields not present in the object, excluding the id, coll, ts, and data metadata fields, are removed.The object can’t include the following metadata fields:idcolltsdata | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | Collection document with replaced fields. | ## [](#examples)Examples ### [](#basic)Basic Given the following document: ``` { id: "777", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), name: "limes", description: "Conventional, 16 oz bag", price: 2_99, stock: 30, category: Category("789") } ``` Call `replace()` with a replacement document object: ```fql Product.byId("777")?.replace({ name: "limes", description: "2 ct", price: 99, stock: 50, category: Category.byId("789") }) ``` ``` { id: "777", coll: Product, ts: Time("2099-04-10T17:54:37.670Z"), name: "limes", description: "2 ct", price: 99, stock: 50, category: Category("789") } ``` ### [](#default)Default values A [field definition](../../../../learn/schema/#field-definitions) can set a [default field value](../../../fsl/field-definitions/#default) for documents in a collection: ```fsl collection Customer { // `name` accepts `String` and `Null` values. // If missing, defaults to `unknown`. name: String? = "unknown" email: String } ``` If you don’t provide a value during document replacement, the document uses the default value: ```fql // Replaces a `Customer` document. Customer.byId("111")?.replace({ // The `name` field is missing. email: "john.doe@example.com" }) ``` ``` { id: "111", coll: Customer, ts: Time("2099-02-19T14:53:53.940Z"), cart: Order("413002506150347264"), orders: "hdW...", email: "john.doe@example.com", // `name` defaulted to `unknown`. name: "unknown" } ``` If you provide an explicit `null` value, the field is `null`. Fields with `null` values aren’t stored or returned. ```fql Customer.byId("111")?.replace({ // `name` is an explicit `null`. name: null, email: "jane.doe@example.com" }) ``` ``` { id: "111", coll: Customer, ts: Time("2099-02-19T14:53:53.940Z"), cart: Order("413002506150347264"), orders: "hdW...", // `name` is not stored or returned. email: "jane.doe@example.com" } ``` # `document.replaceData()` | Learn: Documents | | --- | --- | --- | Replace a [collection document](../../../../learn/data-model/documents/) using an object that may contain [metadata fields](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig replaceData(data: { *: Any }) => A ``` ## [](#description)Description Replaces all fields in an collection document with fields from a provided data object. Fields not present in the data object, excluding the `id`, `coll`, `ts`, and `data` metadata fields, are removed. This method differs from [`document.replace()`](../replace/) in how it handles reserved fields. See [Reserved fields](#reserved). ### [](#reserved)Reserved fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` If the provided data object contains field names that conflict with these [metadata fields](../../../../learn/data-model/documents/#meta), the method safely nests values for fields with reserved names in the `data` field. See [Examples](#examples). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the collection document. Fields not present in the object, excluding the id, coll, ts, and data metadata fields, are removed.If the object contains field names that conflict with these metadata fields, the method safely nests values for fields with reserved names in the data field. See Examples. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | Collection document with replaced fields. | ## [](#examples)Examples Given the following document: ``` { id: "777", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), name: "limes", description: "Conventional, 16 oz bag", price: 2_99, stock: 30, category: Category("789") } ``` Call `replaceData()` with `id` and `coll` fields in the replacement document object. These fields have the same name as reserved [metadata fields](../../../../learn/data-model/documents/). ```fql Product.byId("777")?.replaceData({ id: "12345", coll: "Product", name: "limes", description: "2 ct", price: 99, stock: 50, category: Category.byId("789") }) ``` ``` { id: "777", coll: Product, ts: Time("2099-04-10T17:54:37.670Z"), name: "limes", description: "2 ct", price: 99, stock: 50, category: Category("789"), data: { coll: "Product", id: "12345" } } ``` Rather than return an error, `replaceData()` treats any field with a reserved name as a document field and nests it in the document’s `data` property. # `document.update()` | Learn: Documents | | --- | --- | --- | Update a [collection document](../../../../learn/data-model/documents/)'s fields. ## [](#signature)Signature ```fql-sig update(data: { ttl: Time | Null, data: Null, *: Any }) => A ``` ## [](#description)Description Updates a collection document with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#default-values)Default values A [field definition](../../../../learn/schema/#field-definitions) can set a [default field value](../../../fsl/field-definitions/#default) for documents in a collection. Default values are not inserted for missing or `null` fields during a document update. ### [](#reserved-fields)Reserved fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Object with the updated document fields.The object can’t include the following metadata fields:idcolltsdata | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | The updated collection document. | ## [](#examples)Examples Given the following document: ``` { id: "777", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), name: "limes", description: "Conventional, 16 oz bag", price: 2_99, stock: 30, category: Category("789") } ``` Call `update()` with an object containing updated document fields: ```fql Product.byId("777")?.update({ name: "key limes", stock: 100 }) ``` ``` { id: "777", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), name: "key limes", description: "Conventional, 16 oz bag", price: 299, stock: 100, category: Category("789") } ``` ### [](#remove-a-field-2)Remove a field To remove a document field, set its value to `null`. Fields with `null` values aren’t stored or returned. ```fql Product.byId("777")?.update({ stock: null }) ``` ``` { id: "777", coll: Product, ts: Time("2099-04-10T17:59:50.970Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, category: Category("789") } ``` # `document.updateData()` | Learn: Documents | | --- | --- | --- | Update a [collection document](../../../../learn/data-model/documents/) using an object that may contain [metadata fields](../../../../learn/data-model/documents/). ## [](#signature)Signature ```fql-sig updateData(data: { *: Any }) => A ``` ## [](#description)Description Updates a collection document with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. This method differs from [`document.update()`](../update/) in how it handles reserved fields. See [Reserved fields](#reserved). ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#default-values)Default values A [field definition](../../../../learn/schema/#field-definitions) can set a [default field value](../../../fsl/field-definitions/#default) for documents in a collection. Default values are not inserted for missing or `null` fields during a document update. ### [](#reserved)Reserved fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` * `data` If the provided data object contains field names that conflict with these [metadata fields](../../../../learn/data-model/documents/#meta), the method safely nests values for fields with reserved names in the `data` field. See [Examples](#examples). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Object with the updated document fields.If the object contains field names that conflict with these metadata fields, the method safely nests values for fields with reserved names in the data field. See Examples. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Document | The updated collection document. | ## [](#examples)Examples Given the following document: ``` { id: "392886847463751746", coll: Product, ts: Time("2099-04-10T16:50:12.850Z"), name: "limes", description: "Conventional, 16 oz bag", price: 299, stock: 30, category: Category("401610017107607625") } ``` Call `updateData()` with the `id` and `coll` fields in the object. These fields have the same name as reserved [metadata fields](../../../../learn/data-model/documents/). ```fql Product.byId("777")?.updateData({ id: "12345", coll: "Products", name: "key limes", stock: 100 }) ``` ``` { id: "777", coll: Product, ts: Time("2099-04-10T17:02:43.846Z"), cart: null, orders: "hdW...", name: "key limes", description: "Conventional, 16 oz bag", price: 299, stock: 100, category: Category("789"), data: { coll: "Products", id: "12345" } } ``` Rather than return an error, `updateData()` treats any field with a reserved name as a document field and nests it in the document’s `data` property. # EventSource | Learn: Event Feeds and Event Streams | | --- | --- | --- | An [event source](../../../learn/cdc/) emits an event when tracked changes occur in a database. ## [](#create-an-event-source)Create an event source To create an event source, append [`set.eventSource()`](../set/eventsource/) or [`set.eventsOn()`](../set/eventson/) to a [supported Set](../../../learn/cdc/#sets): ```fql // Tracks all changes to the `Product` collection. Product.all().eventSource() // Tracks all changes to the `name`, `price`, // and `stock` fields in `Product` documents. Product.all().eventsOn(.name, .price, .stock) ``` The query returns a string-encoded token that represents the event source. The token has the [EventSource](../../fql/types/#event-source) type: ```json "g9WD1YPG..." ``` When consumed as an [Event Feed or Event Stream](../../../learn/cdc/), the event source emits JSON events when a tracked change occurs: ```json { "type": "add", "data": { "@doc": { "id": "392914348360597540", "coll": { "@mod": "Product" }, "ts": { "@time": "2099-03-20T21:46:12.580Z" }, "name": "cups", ... } }, "txn_ts": 1710968002310000, "cursor": "gsGabc123", "stats": { "read_ops": 8, "storage_bytes_read": 208, "compute_ops": 1, "processing_time_ms": 0, "rate_limits_hit": [] } } ``` For event properties, see [event schema](../../../learn/cdc/#event-schema). ## [](#consume-an-event-source)Consume an event source Applications can consume an event source in two ways: * **[Event Feeds](../../../learn/cdc/#event-feeds)** : Asynchronous requests that poll the event source for paginated events. * **[Event Streams](../../../learn/cdc/#event-streaming)**: Real-time subscriptions that push events from the event source to your application using an open connection to Fauna. ## [](#instance-methods)Instance methods You can call the following instance methods on [event sources](../../../learn/cdc/) in FQL. | Method | Description | | --- | --- | --- | --- | | eventSource.map() | Apply an anonymous function to each element of an event source's tracked Set. | | eventSource.toString() | Get "[event source]" as a string. | | eventSource.where() | Create an event source that emits events for a subset of another event source’s tracked Set. | # `eventSource.map()` | Learn: Event Feeds and Event Streams | | --- | --- | --- | Apply an [anonymous function](../../../fql/functions/) to each element of an [event source](../../../../learn/cdc/)'s [tracked Set](../../../../learn/cdc/#sets). ## [](#signature)Signature ```fql-sig map(mapper: (A => B)) => EventSource ``` ## [](#description)Description `map()` applies an anonymous, read-only [function](../../../fql/functions/) to each element of an existing [event source](../../../../learn/cdc/)'s [tracked Set](../../../../learn/cdc/#sets). `map()` returns a new event source. The new event source emits events that contain transformed elements in the event’s [`data` property](../../../../learn/cdc/#event-schema). `map()` does not change the calling event source. ### [](#use-cases)Use cases Common uses for `map()` include: * Transforming document structures for specific client needs * Combining multiple fields into a single value * Formatting data for external systems ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | mapper | Function | true | Anonymous, read-only function that operates on an existing event source's tracked Set elements.Writes are not permitted in the function. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | EventSource | String-encoded token for the new event source. The event source emits events for the original tracked Set. The emitted events contain transformations from the provided function. | ## [](#examples)Examples ### [](#basic-example)Basic example `Customer` collection documents have the following structure: ``` { id: "111", coll: Customer, ts: Time("2099-06-25T12:14:29.440Z"), cart: Order("412653216549831168"), orders: "hdW...", name: 'Alice Appleseed', email: 'alice.appleseed@example.com', address: { street: '87856 Mendota Court', city: 'Washington', state: 'DC', postalCode: '20220', country: 'US' } } ``` The following query uses `map()` to transform the document structure in events: ```fql Customer.all() .eventSource() .map( customer => { name: customer.name, // Transformation. Combines `address.city` and `address.state` // into a single `city` string. city: "#{customer.address.city}, #{customer.address.state}" } ) ``` ``` // String-encoded token for the new event source "g9WD1YPG..." ``` When consumed as an [Event Feed or Event Stream](../../../../learn/cdc/), the event source emits events with the transformed value in the `data` property: ``` { "type": "update", // The `data` prop contains transformed // `city` values. "data": { "name": "Alice Appleseed", "city": "Washington, DC" }, "txn_ts": 1730318669480000, "cursor": "gsG...", "stats": { "read_ops": 2, "storage_bytes_read": 738, "compute_ops": 1, "processing_time_ms": 9, "rate_limits_hit": [] } } ``` # `eventSource.toString()` | Learn: Event Feeds and Event Streams | | --- | --- | --- | Get `"[event source]"` as a string. ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description `toString()` returns `"[event source]"` as a string. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "[event source]" | ## [](#examples)Examples ```fql Customer.all().eventSource().toString() ``` ``` "[event source]" ``` # `eventSource.where()` | Learn: Event Feeds and Event Streams | | --- | --- | --- | Create an [event source](../../../../learn/cdc/) that emits events for a subset of another event source’s [tracked Set](../../../../learn/cdc/#sets). ## [](#signature)Signature ```fql-sig where(predicate: (A => Boolean | Null)) => EventSource ``` ## [](#description)Description The `where()` method returns an [event source](../../../../learn/cdc/). The event source emits [events](../../../../learn/cdc/#events) for a subset of another event source’s [tracked Set](../../../../learn/cdc/#sets). The subset’s elements must match a provided [predicate function](../../../fql/functions/#predicates). The predicate must return a [Boolean](../../../fql/types/#boolean) or [Null](../../../fql/types/#null). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Function | true | Anonymous predicate function that’s compared to an existing event source's Set elements. The function returns true for matches, false for mismatches, or Null. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | EventSource | String-encoded token for an event source. The event source emits events for Set elements that match the provided predicate function. | ## [](#examples)Examples ```fql // Only emit events for `Customer` documents // with an `.address.state` of `DC`. Customer.all() .eventSource() .where(.address.state == "DC") ``` ``` // String-encoded token for the new event source "g9WD1YPG..." ``` When consumed as an [Event Feed or Event Stream](../../../../learn/cdc/), the event source emits events for the subset matching the provided [predicate function](../../../fql/functions/#predicates): ``` // The new event source only emits events // for `Customer` documents with an // an `.address.state` of `DC`. { "type": "update", "data": { "@doc": { "id": "111", "coll": { "@mod": "Customer" }, "ts": { "@time": "2099-10-30T20:18:18.390Z" }, "cart": { "@ref": { "id": "413111684333305922", "coll": { "@mod": "Order" } } }, "orders": { "@set": "hdW..." }, "name": "Alice Appleseed", "email": "alice.appleseed@example.com", "address": { "street": "87857 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } }, "txn_ts": 1730319498390000, "cursor": "gsG...", "stats": { "read_ops": 3, "storage_bytes_read": 1049, "compute_ops": 1, "processing_time_ms": 50, "rate_limits_hit": [] } } ``` # FQL The `FQL` module provides access to all top-level FQL modules and functions. For example, you can use `FQL.Math` to access the [`Math`](../math/) module and its methods. `FQL.Math.abs(-3)` is equivalent to `Math.abs(-3)`. The `FQL` module also contains modules and functions that aren’t at the top level, such as [`FQL.Schema.defForIdentifier()`](schema-defforidentifier/). ## [](#static-methods)Static methods The following section covers `FQL` methods that aren’t available at the top level. ### [](#schema-methods)Schema methods The `Schema` module exists under the top-level `FQL` module. `Schema` has a single member: `defForIdentifier()`. | Method | Description | | --- | --- | --- | --- | | FQL.Schema.defForIdentifier() | Returns the definition for a user-defined collection or user-defined function (UDF) using the same rules as top-level identifier lookups. | # `FQL.Schema.defForIdentifier()` Returns the definition for a user-defined [collection](../../../../learn/data-model/collections/) or [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) using the same rules as top-level identifier lookups. ## [](#signature)Signature ```fql-sig FQL.Schema.defForIdentifier(ident: String) => Any ``` ## [](#description)Description `FQL.Schema.defForIdentifier()` returns the definition for a user-defined [collection](../../../../learn/data-model/collections/) or [UDF](../../../../learn/schema/user-defined-functions/) using the same rules as top-level identifier lookups. The lookup returns the first matching resource using the following precedence: 1. A user-defined collection where `.name == ` 2. A user-defined collection where `.alias == ` 3. A UDF where `.name == ` 4. A UDF where `.alias == ` The document is an FQL definition for the resource’s FSL schema. See: * [`Collection` documents](../../collection/#collection) * [`Function` documents](../../function/#collection) The method does not retrieve definitions for system collections or other resources. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | ident | String | true | Identifier for a user-defined collection or UDF. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | Definition for the resource. | ## [](#examples)Examples ### [](#get-a-user-defined-collections-definition)Get a user-defined collection’s definition ```fql // Gets the FQL definition for the `Product` collection. FQL.Schema.defForIdentifier('Product') ``` ``` { name: "Product", coll: Collection, ts: Time("2099-10-22T21:56:30.975Z"), history_days: 0, indexes: { byCategory: { terms: [ { field: ".category", mva: false } ], queryable: true, status: "complete" }, sortedByCategory: { values: [ { field: ".category", order: "asc", mva: false } ], queryable: true, status: "complete" }, byName: { terms: [ { field: ".name", mva: false } ], queryable: true, status: "complete" }, sortedByPriceLowToHigh: { values: [ { field: ".price", order: "asc", mva: false }, { field: ".name", order: "asc", mva: false }, { field: ".description", order: "asc", mva: false }, { field: ".stock", order: "asc", mva: false } ], queryable: true, status: "complete" } }, constraints: [ { unique: [ { field: ".name", mva: false } ], status: "active" }, { check: { name: "stockIsValid", body: "(product) => product.stock >= 0" } }, { check: { name: "priceIsValid", body: "(product) => product.price > 0" } } ], fields: { name: { signature: "String" }, description: { signature: "String" }, price: { signature: "Int" }, category: { signature: "Ref" }, stock: { signature: "Int" } } } ``` ### [](#get-a-udfs-definition)Get a UDF’s definition ```fql // Gets the FQL definition for the `validateOrderStatusTransition()` UDF. FQL.Schema.defForIdentifier('validateOrderStatusTransition') ``` ``` { name: "validateOrderStatusTransition", coll: Function, ts: Time("2024-10-28T15:11:25.460Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END } ``` # Function | Learn: User-defined functions (UDFs) | | --- | --- | --- | A [user-defined function (UDF)](../../../learn/schema/user-defined-functions/) is a set of one or more FQL statements stored as a reusable resource in a Fauna database. Like a stored procedure in SQL, a UDF can accept parameters, perform operations, and return results. ## [](#collection)`Function` collection Fauna stores UDFs as documents in the `Function` system collection. These documents have the [FunctionDef](../../fql/types/#functiondef) type and are an FQL version of the FSL [function schema](../../fsl/function/). `Function` documents have the following FQL structure: ``` { name: "getOrCreateCart", coll: Function, ts: Time("2099-09-25T21:53:08.780Z"), role: "server", body: <<-END (id) => { let customer = Customer.byId(id)! if (customer!.cart == null) { Order.create({ status: "cart", customer: Customer.byId(id), createdAt: Time.now(), payment: { } }) } else { customer!.cart } } END } ``` | Field | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | name | String | | true | Name of the function.Can’t be documents, events, self, sets, or a single underscore _, and can’t include a space character. | | coll | String | true | | Collection name: Function. | | ts | Time | true | | Last time the document was created or updated. | | role | String | | | Role to use when the function is called. Only included if role is provided when the UDF is created.Can be a built-in role, admin, server, or server-readonly, or a user-defined role that grants write privilege for Functions. | | body | String | | true | FQL function body. | | data | Object | | | Arbitrary user-defined metadata for the document. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Function` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Function() | Call a user-defined function (UDF) by its name. | | Function.all() | Get a Set of all user-defined functions (UDFs). | | Function.byName() | Get a user-defined function (UDF) by its name. | | Function.create() | Create a user-defined function (UDF). | | Function.firstWhere() | Get the first user-defined function (UDF) that matches a provided predicate. | | Function.toString() | Get "Function" as a String. | | Function.where() | Get a Set of user-defined functions (UDFs) that match a provided predicate. | ## [](#instance-properties)Instance properties `Function` documents have the following properties. You access the property using an existing UDF’s name. | Property | Description | | --- | --- | --- | --- | | function.definition | Get or update a user-defined function (UDF)'s definition, represented as a Function document. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage function definitions, represented as `Function` documents, in FQL. You call the methods on a [FunctionDef](../../fql/types/#functiondef). | Method | Description | | --- | --- | --- | --- | | functionDef.delete() | Delete a user-defined function (UDF). | | functionDef.exists() | Test if a user-defined function (UDF) exists. | | functionDef.replace() | Replace a user-defined function (UDF). | | functionDef.update() | Update a user-defined function (UDF). | # `function.definition` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get or update a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/)'s definition, represented as a [`Function` document](../#collection). ## [](#signature)Signature ```fql-sig .definition: FunctionDef ``` ## [](#description)Description The `definition` property is a [user-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/)'s schema, represented as a [`Function` document](../#collection) with the [FunctionDef](../../../fql/types/#functiondef) type. The document is an FQL version of the FSL [function schema](../../../fsl/function/). You access the property using an existing UDF’s name. ### [](#definition-properties)Definition properties You can use [dot or bracket notation](../../../fql/dot-notation/#dot-notation-field-accessor) to access specific fields in the definition. See [Access definition properties](#access). ### [](#definition-methods)Definition methods The `definition` property supports [function instance methods](../#instance-methods). ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | FunctionDef | Definition for the UDF, represented as a Function document. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Get the definition for // the `getOrCreateCart()` UDF. getOrCreateCart.definition ``` ``` { name: "getOrCreateCart", coll: Function, ts: Time("2099-10-03T20:30:59.360Z"), body: <<-END (id) => { let customer = Customer.byId(id)! if (customer!.cart == null) { Order.create({ status: "cart", customer: Customer.byId(id), createdAt: Time.now(), payment: { } }) } else { customer!.cart } } END } ``` ### [](#access)Access definition properties Use [dot or bracket notation](../../../fql/dot-notation/#dot-notation-field-accessor) to access specific fields in the definition: ```fql // Access the `body` field for // the `getOrCreateCart()` UDF. getOrCreateCart.definition.body ``` ``` // Only returns the `body` field. <<-END (id) => { let customer = Customer.byId(id)! if (customer!.cart == null) { Order.create({ status: "cart", customer: Customer.byId(id), createdAt: Time.now(), payment: { } }) } else { customer!.cart } } END ``` # `Function()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Call a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) by its name. ## [](#signature)Signature ```fql-sig Function(function: String) => Any ``` ## [](#description)Description Calls a [UDF](../../../../learn/schema/user-defined-functions/) by its name. You can pass arguments to the UDF. See [Examples](#examples). ### [](#errors)Errors If you attempt to call a UDF that doesn’t exist, Fauna returns a query runtime error with an `invalid_argument` [error code](../../../http/reference/errors/) and a 400 HTTP status code: ``` invalid_argument error: invalid argument `function`: No such user function `Foo`. at *query*:1:9 | 1 | Function("Foo") | ^^^^^^^ | ``` ### [](#comparison-to-functionname)Comparison to `` Calling `Function()` is similar to accessing `` directly, except `Function()` returns an [Any](../../../fql/types/#any) value. This difference only affects static typing, not runtime behavior. In most cases, you should use ``. However, `Function()` is useful if you need to iterate through a list of UDF calls. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | function | String | true | Function to call | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | Results of the function call. | ## [](#examples)Examples Get the function by passing the function name to `Function()`: ```fql // Call function named `getOrCreateCart` Function("getOrCreateCart") ``` ``` "[function getOrCreateCart]" ``` To call the function, pass arguments in parentheses: ```fql // Calls the `getOrCreateCart()` function on // a `Customer` document with an `id` of `111`. Function("getOrCreateCart")('111') ``` ``` { id: "412998994633949261", coll: Order, ts: Time("2024-10-28T14:23:03.966Z"), items: "hdW...", total: 5392, status: "cart", customer: Customer("111"), createdAt: Time("2024-10-28T14:23:03.795981Z"), payment: {} } ``` # `Function.all()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get a Set of all [user-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ## [](#signature)Signature ```fql-sig Function.all() => Set Function.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [UDFs](../../../../learn/schema/user-defined-functions/), represented as [`Function` documents](../), for the database. To limit the returned Set, you can provide an optional range. `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). If `Function.all()` is the last value in a query, the first page of the [Set](../../../fql/types/#set) is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Function documents in the form { from: start, to: end }.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all UDFs are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Function document. | | to | Any | | End of the range (inclusive). Must be an Function document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Function documents in the provided range. If a range is omitted, all UDFs are returned.The Set is empty if:The database has no UDFs.There are no UDFs in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ```fql Function.all() ``` ``` { data: [ { name: "validateOrderStatusTransition", coll: Function, ts: Time("2024-10-25T17:49:28.145Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END }, ... ] } ``` # `Function.byName()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) by its name. ## [](#signature)Signature ```fql-sig Function.byName(name: String) => NamedRef ``` ## [](#description)Description Gets a [UDF](../../../../learn/schema/user-defined-functions/), represented as an [`Function` document](../), by its name. `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | name | String | true | name of the Function document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NamedRef | Resolved reference to the Function document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Function.byName("validateOrderStatusTransition") ``` ``` { name: "validateOrderStatusTransition", coll: Function, ts: Time("2024-10-25T17:49:28.145Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END } ``` # `Function.create()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Create a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/). ## [](#signature)Signature ```fql-sig Function.create(data: { name: String, alias: String | Null, signature: String | Null, role: String | Null, body: String, data: { *: Any } | Null }) => FunctionDef ``` ## [](#description)Description Creates an [UDF](../../../../learn/schema/user-defined-functions/) with the provided document fields. Fauna stores UDFs as documents in the [`Function` system collection](../). `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method adds a function to the staged schema, not the active schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the new Function document.For supported document fields, see Function collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | FunctionDef | The new Function document. | ## [](#examples)Examples 1. Create a UDF: ```fql Function.create({ name: 'hello', body: '(x) => "Hello #{x}!"' }) ``` ``` { name: "hello", coll: Function, ts: Time("2099-10-25T17:56:30.150Z"), body: "(x) => \"Hello \#{x}!\"" } ``` 2. Call the UDF: ```fql hello("World") ``` ``` "Hello World!" ``` 1. Use heredoc syntax to avoid interpolation until the function executes: ```fql Function.create({ name: "hello2", body: <<-EOB name => "Hello to you, #{name}!" EOB }) ``` ``` { name: "hello2", coll: Function, ts: Time("2099-11-03T17:06:02.790Z"), body: <<-END name => "Hello to you, #{name}!" END } ``` 2. Call the UDF: ```fql hello2("World") ``` ``` "Hello to you, World!" ``` Create a UDF with the `admin` role: ```fql Function.create({ name: 'Doublex', body: '(x) => x + x', role: 'admin', }) ``` ``` { name: "Doublex", coll: Function, ts: Time("2099-06-25T15:03:14.060Z"), body: "(x) => x + x", role: "admin" } ``` Create a UDF with a `data` metadata field: ```fql Function.create({ name: "square", body: "x => x * x", data: { version: "1.0" } }) ``` ``` { name: "square", coll: Function, ts: Time("2099-01-08T20:30:50.090Z"), body: "x => x * x", data: { version: "1.0" } } ``` # `Function.firstWhere()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get the first [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Function.firstWhere(pred: (FunctionDef => Boolean)) => FunctionDef | Null ``` ## [](#description)Description Gets the first [UDF](../../../../learn/schema/user-defined-functions/), represented as an [`Function` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Function document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Function document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | FunctionDef | First Function document that matches the predicate. | | Null | No Function document matches the predicate. | ## [](#examples)Examples Get the first UDF when at least one matching UDF document exists and is accessible: ```fql Function.firstWhere(.name.includes('validate')) ``` ``` { name: "validateOrderStatusTransition", coll: Function, ts: Time("2099-10-25T17:49:28.145Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END } ``` # `Function.toString()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get `"Function"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Function.toString() => String ``` ## [](#description)Description Returns the name of the [`Function` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Function" | ## [](#examples)Examples ```fql Function.toString() ``` ``` "Function" ``` # `Function.where()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Get a Set of [user-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Function.where(pred: (FunctionDef => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [UDFs](../../../../learn/schema/user-defined-functions/), represented as [`Function` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). If `Function.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Function document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Function documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Function documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Function.where(.name.includes('validate')) ``` ``` { data: [ { name: "validateOrderStatusTransition", coll: Function, ts: Time("2099-10-25T17:49:28.145Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END } ] } ``` # `functionDef.delete()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Delete a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/). ## [](#signature)Signature ```fql-sig delete() => NullFunctionDef ``` ## [](#description)Description Deletes a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/), represented as a [`Function` document](../). `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#staged-schema)Staged schema You can’t delete a function while a database has [staged schema](../../../../learn/schema/manage-schema/#staged). If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullFunctionDef | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql Function.byName("checkout")?.delete() ``` ``` Function.byName("checkout") /* deleted */ ``` # `functionDef.exists()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Test if a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if an [UDF](../../../../learn/schema/user-defined-functions/), represented as an [`Function` document](../), exists. Fauna stores UDFs as documents in the [`Function` system collection](../). `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Function document exists. If false, the Function document doesn’t exist. | ## [](#examples)Examples ```fql Function.byName("checkout").exists() ``` ``` true ``` # `functionDef.replace()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Replace a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => FunctionDef ``` ## [](#description)Description Replaces all fields in a [UDF](../../../../learn/schema/user-defined-functions/), represented as an [`Function` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `coll` and `ts` metadata fields, are removed. `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a function while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the Function document. Fields not present, excluding the coll and ts metadata fields, in the object are removed.For supported document fields, see Function collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | FunctionDef | Function document with replaced fields. | ## [](#examples)Examples ```fql Function.byName("validateOrderStatusTransition")?.replace({ name: "validateOrderStatusTransition", role: "server", body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END }) ``` ``` { name: "validateOrderStatusTransition", coll: Function, ts: Time("2099-10-28T15:11:25.460Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END, role: "server" } ``` # `functionDef.update()` | Learn: User-defined functions (UDFs) | | --- | --- | --- | Update a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => FunctionDef ``` ## [](#description)Description Updates a [UDF](../../../../learn/schema/user-defined-functions/), represented as an [`Function` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. `Function` documents are FQL versions of a database’s FSL [function schema](../../../fsl/function/). `Function` documents have the [FunctionDef](../../../fql/types/#functiondef) type. See [User-defined functions (UDFs)](../../../../learn/schema/user-defined-functions/). ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a function while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the Function document.For supported document fields, see Function collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | FunctionDef | The updated Function document. | ## [](#examples)Examples ```fql Function.byName("validateOrderStatusTransition")?.update({ name: "validateOrderStatusTransition", body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END, role: "server" }) ``` ``` { name: "validateOrderStatusTransition", coll: Function, ts: Time("2099-10-25T18:16:27.725Z"), body: <<-END (oldStatus, newStatus) => { if (oldStatus == "cart" && newStatus != "processing") { abort("Invalid status transition.") } else if (oldStatus == "processing" && newStatus != "shipped") { abort("Invalid status transition.") } else if (oldStatus == "shipped" && newStatus != "delivered") { abort("Invalid status transition.") } } END, role: "server" } ``` # Key | Learn: Keys | | --- | --- | --- | A [key](../../../learn/security/keys/) is a type of [authentication secret](../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../learn/security/tokens/), keys are not associated with an identity. ## [](#collection)`Key` collection Fauna stores keys scoped to a database as documents in the database’s `Key` system collection. `Key` documents have the following FQL structure: ``` { id: "371460335192768546", coll: Key, ts: Time("2099-07-28T02:23:51.300Z"), ttl: Time("2099-07-29T02:23:51.189192Z"), role: "admin", database: "child_db", data: { name: "System-generated dashboard key" }, secret: "fn..." } ``` | Field name | Type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | id | ID | | | ID for the Key document. The ID is a string-encoded, 64-bit unsigned integer in the 253-1 range. The ID is unique within the collection.IDs are assigned at document creation. To create a key with a user-provided id using Key.create(), you must use a secret with the create_with_id privilege for the Key collection. If not provided, Fauna generates the id. | | coll | Collection | true | | Collection name: Key. | | ts | Long | true | | Last time the document was created or updated. | | role | String | | true | Role assigned to the key. Can be a user-defined role or one of the following built-in roles:adminserverserver-readonlyIf you specify a user-defined role and a child database, the role must be defined in the specified child database. | | database | String | Null | | | Child database to which the key is scoped. The child database must be directly nested under the database scoped to query’s authentication secret.If not present, the key is scoped to the same database as the authentication secret. | | ttl | Time | | | Time-to-live (TTL) for the document. Only present if set. If not present or set to null, the document persists indefinitely. | | data | { *: Any } | Null | | | Arbitrary user-defined metadata for the document. | | secret | String | | | The secret is a randomly generated cryptographic hash. This field isn’t stored in the document. The secret is only accessible in the Key.create() return. A caller obtains the secret from this return and stores it for subsequent queries. Fauna can’t recover a discarded or lost secret. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Key` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Key.all() | Get a Set of all keys. | | Key.byId() | Get a key by its document id. | | Key.create() | Create a key. | | Key.firstWhere() | Get the first key that matches a provided predicate. | | Key.toString() | Get "Key" as a String. | | Key.where() | Get a Set of keys that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `Key` documents in FQL. | Method | Description | | --- | --- | --- | --- | | key.delete() | Delete a key. | | key.exists() | Test if a key exists. | | key.replace() | Replace a key. | | key.update() | Update a key. | ## [](#dashboard)Dashboard-created keys The [Fauna Dashboard](https://dashboard.fauna.com/) automatically creates a temporary key when you: * Log in to the Dashboard. This key has the built-in `admin` role. * Use the Dashboard Shell’s authentication drop-down to run a query using a role other than **Admin**. ![Run a query as a role](../../../learn/_images/run-as-role.png) Dashboard-created keys have a 15-minute [`ttl` (time-to-live)](../../../learn/security/keys/#ttl) and are scoped to their specific database. Related `Key` documents include a `data` field with related metadata: ``` { id: "414467050449141793", coll: Key, ts: Time("2099-11-13T19:17:11.020Z"), ttl: Time("2099-11-13T19:32:09.915Z"), data: { name: "System-generated dashboard key" }, role: "admin" } ``` The Dashboard surfaces this metadata in the database’s **Keys** tab on the **Explorer** page. ![Key’s tab in the Fauna Dashboard](../../../learn/_images/keys-tab.png) # `Key.all()` | Learn: Keys | | --- | --- | --- | Get a Set of all [keys](../../../../learn/security/keys/). ## [](#signature)Signature ```fql-sig Key.all() => Set Key.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [keys](../../../../learn/security/keys/), represented as [`Key` documents](../), for the database. To limit the returned Set, you can provide an optional range. If `Key.all()` is the last value in a query, the first page of the [Set](../../../fql/types/#set) is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Key documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Key.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all Key documents are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Key document. | | to | Any | | End of the range (inclusive). Must be an Key document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Key documents in the provided range. If a range is omitted, all Key documents are returned.The Set is empty if:The database has no keys.There are no keys in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all keys for the database: ```fql Key.all() ``` ``` { data: [ { id: "111", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "admin", data: { desc: "Admin key for prod app database" } }, { id: "222", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "server", data: { desc: "Server key for prod app database" } }, { id: "333", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "server-readonly", data: { desc: "Server-readonly key for prod app database" } } ] } ``` 2. Get a Set of `Key` documents from ID `111` (inclusive) to ID `222` (inclusive): ```fql Key.all({ from: Key.byId("111"), to: Key.byId("222") }) ``` ``` { data: [ { id: "111", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "admin", data: { desc: "Admin key for prod app database" } }, { id: "222", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "server", data: { desc: "Server key for prod app database" } } ] } ``` 3. Get a Set of keys up to ID `222` (inclusive): ```fql Key.all({ to: Key.byId("222") }) ``` ``` { data: [ { id: "111", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "admin", data: { desc: "Admin key for prod app database" } }, { id: "222", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "server", data: { desc: "Server key for prod app database" } } ] } ``` # `Key.byId()` | Learn: Keys | | --- | --- | --- | Get a [key](../../../../learn/security/keys/) by its [document `id`](../../../../learn/data-model/documents/#meta). ## [](#signature)Signature ```fql-sig Key.byId(id: ID) => Ref ``` ## [](#description)Description Gets a [key](../../../../learn/security/keys/), represented as an [`Key` document](../), by its [document `id`](../../../../learn/data-model/documents/#meta). A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | id | String | true | ID of the Key document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Ref | Resolved reference to the Key document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Key.byId("412655134325080576") ``` ``` { id: "412655134325080576", coll: Key, ts: Time("2099-08-01T02:45:50.490Z"), role: "admin", data: { desc: "Admin key for prod app database" } } ``` # `Key.create()` | Learn: Keys | | --- | --- | --- | Create a [key](../../../../learn/security/keys/). ## [](#signature)Signature ```fql-sig Key.create(data: { role: String, database: String | Null, ttl: Time | Null, data: { *: Any } | Null }) => Key ``` ## [](#description)Description Creates a [key](../../../../learn/security/keys/) with the provided document fields. Fauna stores keys as documents in the [`Key` system collection](../). A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the new Key document.For supported document fields, see Key collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Key | The new Key document. Includes the key’s secret, which you can use to authenticate with Fauna.A key’s secret is shown once — when you create the key. You can’t recover or regenerate a lost key secret. Instead, delete the key and create a new one. | ## [](#examples)Examples Create a key with a user-defined role and which expires tomorrow: ```fql Key.create({role: "admin", ttl: Time.now().add(1, "day")}) ``` ``` { id: "412655134325080576", coll: Key, ts: Time("2099-07-28T02:23:51.300Z"), ttl: Time("2099-07-29T02:23:51.189192Z"), secret: "fn...", role: "admin" } ``` # `Key.firstWhere()` | Learn: Keys | | --- | --- | --- | Get the first [key](../../../../learn/security/keys/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Key.firstWhere(pred: (Key => Boolean)) => Key | Null ``` ## [](#description)Description Gets the first [key](../../../../learn/security/keys/), represented as a [`Key` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Key document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Key document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Key | First Key document that matches the predicate. | | Null | No Key document matches the predicate. | ## [](#examples)Examples ```fql Key.firstWhere(.role == "admin") ``` ``` { id: "412655134325080576", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "admin", data: { desc: "Admin key for prod app database" } } ``` # `Key.toString()` | Learn: Keys | | --- | --- | --- | Get `"Key"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Key.toString() => String ``` ## [](#description)Description Returns the name of the [`Key` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Key" | ## [](#examples)Examples ```fql Key.toString() ``` ``` "Key" ``` # `Key.where()` | Learn: Keys | | --- | --- | --- | Get a Set of [keys](../../../../learn/security/keys/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Key.where(pred: (Key => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [keys](../../../../learn/security/keys/), represented as [`Key` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. If `Key.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Key document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Key documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Key documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Key.where(.data != null) ``` ``` { data: [ { id: "412655134325080576", coll: Key, ts: Time("2099-07-19T20:53:15.250Z"), role: "admin", data: { desc: "Admin key for prod app database" } }, { id: "412655134325080577", coll: Key, ts: Time("2099-07-28T02:25:35.050Z"), role: "server", data: { desc: "Server key for prod app database" } } ] } ``` # `key.delete()` | Learn: Keys | | --- | --- | --- | Delete a [key](../../../../learn/security/keys/). ## [](#signature)Signature ```fql-sig delete() => NullKey ``` ## [](#description)Description Deletes a [key](../../../../learn/security/keys/), represented as a [`Key` document](../). A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullKey | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ### [](#basic-ex)Basic example ```fql Key.byId("412655134325080576")!.delete() ``` ``` Key("412655134325080576") /* deleted */ ``` ### [](#delete-all-keys)Delete all keys To [avoid throttling](../../../../learn/data-model/databases/#delete-cons), you can incrementally delete all keys for a database before deleting the database itself. To stay within [transaction size limits](../../../requirements-limits/#glimits), use [`set.paginate()`](../../set/paginate/) to perform the deletions over several queries instead of one. ```fql // Gets all `Key` system collection documents. // Uses `pageSize()` to limit the page size. // Uses `paginate()` to project the after cursor. let page = Key.all().pageSize(200).paginate() // `paginate()` returns an object. The object's `data` property // contains an Array of `Key` documents. let data = page.data // Use `forEach()` to delete each `Key` document in the // `data` Array. data.forEach(doc => doc.delete()) // Project the `after` cursor returned by `paginate()`. // Use the cursor to iterate through the remaining pages. page { after } ``` ``` { after: "hdWDxoq..." } ``` Subsequent queries use the cursor and [`Set.paginate()`](../../set/static-paginate/) to iterate through the remaining pages: ```fql // Uses `Set.paginate()` to iterate through pages. let page = Set.paginate("hdW...") let data = page.data data.forEach(doc => doc.delete()) page { after } ``` # `key.exists()` | Learn: Keys | | --- | --- | --- | Test if a [key](../../../../learn/security/keys/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if an [key](../../../../learn/security/keys/), represented as an [`Key` document](../), exists. A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Key document exists. If false, the Key document doesn’t exist. | ## [](#examples)Examples ```fql Key.byId("412655134325080576")!.exists() ``` ``` true ``` # `key.replace()` | Learn: Keys | | --- | --- | --- | Replace a [key](../../../../learn/security/keys/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => Key ``` ## [](#description)Description Replaces all fields in a [key](../../../../learn/security/keys/), represented as an [`Key` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `id`, `coll`, and `ts` metadata fields, are removed. A key is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used for anonymous access to a Fauna database. Unlike [tokens](../../../../learn/security/tokens/), keys are not associated with an identity. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the Key document. Fields not present, excluding the id, coll, and ts metadata fields, in the object are removed.For supported document fields, see Key collection.The object can’t include the following metadata fields:* id * coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Key | Key document with replaced fields. | ## [](#examples)Examples ```fql Key.byId("412655134325080576")!.replace({ role: "server", data: { desc: "Server key for prod app database" } }) ``` ``` { id: "412655134325080576", coll: Key, ts: Time("2099-07-28T02:25:07.910Z"), role: "server", data: { desc: "Server key for prod app database" } } ``` # `key.update()` | Learn: Keys | | --- | --- | --- | Update a [key](../../../../learn/security/keys/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => Key ``` ## [](#description)Description Updates a [key](../../../../learn/security/keys/), represented as an [`Key` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the Key document.For supported document fields, see Key collection.The object can’t include the following metadata fields:* id * coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Key | The updated Key document. | ## [](#examples)Examples ```fql Key.byId("412655134325080576")!.update({ data: { desc: "Admin key for prod app database" } }) ``` ``` { id: "412655134325080576", coll: Key, ts: Time("2099-07-11T14:17:49.890Z"), role: "admin", data: { desc: "Admin key for prod app database" } } ``` # Math `Math` methods and properties. ## [](#description)Description `Math` is a built-in object that has methods for performing mathematical operations. ## [](#properties)Properties | Property | Description | | --- | --- | --- | --- | | Math.E | Get the Euler’s number mathematical constant (℮). | | Math.Infinity | String value representing infinity. | | Math.NaN | Value representing Not-a-Number. | | Math.PI | Get the mathematical constant pi (π). | ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Math.abs() | Get the absolute value of a Number. | | Math.acos() | Get the inverse cosine in radians of a Number. | | Math.asin() | Get the inverse sine in radians of a Number. | | Math.atan() | Get the inverse tangent in radians of a Number. | | Math.ceil() | Round up a Number. | | Math.cos() | Get the cosine of a Number in radians. | | Math.cosh() | Get the hyperbolic cosine of a Number. | | Math.degrees() | Convert radians to degrees. | | Math.exp() | Get the value of ℮ raised to the power of a Number. | | Math.floor() | Round down a Number. | | Math.hypot() | Get the hypotenuse of a right triangle. | | Math.log() | Get the natural logarithm, base e, of a Number. | | Math.log10() | Get the base 10 logarithm of a Number. | | Math.max() | Get the larger of two Numbers. | | Math.mean() | Get the arithmetic mean of an Array or Set of Numbers. | | Math.min() | Get the smaller of the input parameter Numbers. | | Math.pow() | Get the value of a base raised to a power. | | Math.radians() | Convert the value of a Number in degrees to radians. | | Math.round() | Get the value of a Number rounded to the nearest integer. | | Math.sign() | Get the sign of a Number. | | Math.sin() | Get the sine of a Number in radians. | | Math.sinh() | Get the hyperbolic sine of a Number. | | Math.sqrt() | Get the square root of a Number. | | Math.sum() | Get the sum of an Array or Set of Numbers. | | Math.tan() | Get the tangent of a Number in radians. | | Math.tanh() | Get the hyperbolic tangent of a Number. | | Math.trunc() | Truncate a Number to a given precision. | # `Math.E` Get the Euler’s number mathematical constant (℮). ## [](#signature)Signature ```fql-sig Math.E: Number ``` ## [](#description)Description Returns Euler’s constant. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of Euler’s constant. | ## [](#examples)Examples ```fql Math.E ``` ``` 2.718281828459045 ``` # `Math.Infinity` String value representing infinity. ## [](#signature)Signature ```fql-sig Math.Infinity: Number ``` ## [](#description)Description `Math.Infinity` represents a double precision floating point number that is greater than any other number. `-Math.Infinity` represents a floating point number that is less than any other number. See [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754). ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Math.Infinity or -Math.Infinity | ## [](#examples)Examples ```fql "1.7976931348623159e308".parseNumber() ``` ``` Math.Infinity ``` ```fql -1.0 / 0.0 ``` ``` -Math.Infinity ``` # `Math.NaN` Value representing Not-a-Number. ## [](#signature)Signature ```fql-sig Math.NaN: Number ``` ## [](#description)Description NaN stands for Not-a-Number and `Math.NaN` represents a double precision floating point number that is undefined or can’t be represented. See [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) and [NaN](https://en.wikipedia.org/wiki/NaN). ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Math.NaN | ## [](#examples)Examples ```fql 0.0 / 0.0 ``` ``` Math.NaN ``` # `Math.PI` Get the mathematical constant pi (π). ## [](#signature)Signature ```fql-sig Math.PI: Number ``` ## [](#description)Description Gets the mathematical constant pi, which is the ratio of the circumference of a circle to its diameter. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of pi. | ## [](#examples)Examples ```fql let radius = 5 Math.PI * (radius + radius) ``` ``` 31.41592653589793 ``` # `Math.abs()` Get the absolute value of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.abs(x: Number) => Number ``` ## [](#description)Description The `Math.abs()` method returns the absolute value of a provided [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number for which you want the absolute value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Absolute value of the provided number. | ## [](#examples)Examples 1. Get the absolute value of an integer: ```fql Math.abs(5) ``` ``` 5 ``` 2. Get the absolute value of a negative integer: ```fql Math.abs(-5) ``` ``` 5 ``` 3. Get the absolution value of a real number: ```fql Math.abs(-5.1) ``` ``` 5.1 ``` # `Math.acos()` Get the inverse cosine in radians of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.acos(x: Number) => Number ``` ## [](#description)Description Gets the inverse cosine in radians of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Inverse cosine in radians of the provided number. | ## [](#examples)Examples ```fql Math.acos(0.5) ``` ``` 1.0471975511965979 ``` # `Math.asin()` Get the inverse sine in radians of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.asin(x: Number) => Number ``` ## [](#description)Description Return the inverse sine in radians of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Inverse sine in radians of the provided number. | ## [](#examples)Examples ```fql Math.asin(0.5) ``` ``` 0.5235987755982989 ``` # `Math.atan()` Get the inverse tangent in radians of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.atan(x: Number) => Number ``` ## [](#description)Description Gets the inverse tangent in radians of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Inverse tangent in radians of the provided number. | ## [](#examples)Examples ```fql Math.atan(1) ``` ``` 0.7853981633974483 ``` # `Math.ceil()` Round up a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.ceil(x: Number) => Number ``` ## [](#description)Description Gets the value of a provided [Number](../../../fql/types/#number) rounded up. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number to round up. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of the provided number rounded up. | ## [](#examples)Examples ```fql Math.ceil(7.004) ``` ``` 8.0 ``` # `Math.cos()` Get the cosine of a [Number](../../../fql/types/#number) in radians. ## [](#signature)Signature ```fql-sig Math.cos(x: Number) => Number ``` ## [](#description)Description Gets the cosine of a [Number](../../../fql/types/#number) in radians. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number representing an angle in radians. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Cosine of the provided number between -1 and 1, inclusive. | ## [](#examples)Examples ```fql Math.cos(2 * Math.PI) ``` ``` 1.0 ``` # `Math.cosh()` Get the hyperbolic cosine of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.cosh(x: Number) => Number ``` ## [](#description)Description Gets the hyperbolic cosine of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Hyperbolic cosine of the provided number. | ## [](#examples)Examples ```fql Math.cosh(1) ``` ``` 1.543080634815244 ``` # `Math.degrees()` Convert radians to degrees. ## [](#signature)Signature ```fql-sig Math.degrees(x: Number) => Number ``` ## [](#description)Description Return the value of a [Number](../../../fql/types/#number) in radians converted to degrees. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number in radians. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of the provided number converted to degrees. | ## [](#examples)Examples ```fql Math.degrees(0.017453293) ``` ``` 1.0000000275052232 ``` # `Math.exp()` Get the value of ℮ raised to the power of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.exp(x: Number) => Number ``` ## [](#description)Description Gets the value of _℮_ raised to the power of a provided [Number](../../../fql/types/#number). See [`Math.E`](../e/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Non-negative number representing ℮ to the power of a provided number, where ℮ is the base of the natural logarithm. | ## [](#examples)Examples ```fql let num = Math.exp(1) Math.trunc(num, 15) ``` ``` 2.718281828201507 ``` # `Math.floor()` Round down a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.floor(x: Number) => Number ``` ## [](#description)Description Gets the value of the provided [Number](../../../fql/types/#number) rounded down. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number to round down. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of the provided number rounded down. | ## [](#examples)Examples ```fql Math.floor(-45.95) ``` ``` -46.0 ``` # `Math.hypot()` Get the hypotenuse of a right triangle. ## [](#signature)Signature ```fql-sig Math.lypot(x: Number, y: Number) => Number ``` ## [](#description)Description Return the hypotenuse of a right triangle or the square root of the sum of squares. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number to be squared and added to the square of y. | | y | Number | true | A number to be squared and added to the square of x. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Hypotenuse of a right triangle or the sum of the squares of x and y. | ## [](#examples)Examples ```fql Math.hypot(3, 4) ``` ``` 5.0 ``` # `Math.log()` Get the natural logarithm, base e, of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.log(x: Number) => Number ``` ## [](#description)Description Gets the natural logarithm, base e, of a provided [Number](../../../fql/types/#number). The [Number](../../../fql/types/#number) must be greater than or equal to zero. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number greater than or equal to zero. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Natural logarithm, base e, of the provided number. | ## [](#examples)Examples ```fql Math.log(10) ``` ``` 2.302585092994046 ``` # `Math.log10()` Get the base 10 logarithm of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.log10(x: Number) => Number ``` ## [](#description)Description Gets the base 10 logarithm of a provided [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number greater than or equal to zero. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Base 10 logarithm of the provided number. | ## [](#examples)Examples ```fql Math.log10(2) ``` ``` 0.3010299956639812 ``` # `Math.max()` Get the larger of two [Number](../../../fql/types/#number)s. ## [](#signature)Signature ```fql-sig Math.max(x: Number, y: Number) => Number ``` ## [](#description)Description Gets the larger of two provided [Number](../../../fql/types/#number)s. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | | y | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Greater of the provided numbers. | ## [](#examples)Examples ```fql Math.max(10, 33) ``` ``` 33 ``` # `Math.mean()` Get the arithmetic mean of an [Array](../../../fql/types/#array) or [Set](../../../fql/types/#set) of [Numbers](../../../fql/types/#number). ## [](#signatures)Signatures ```fql-sig Math.mean(numbers: Array) => Number Math.mean(numbers: Set) => Number ``` ## [](#description)Description Gets the arithmetic mean of an [Array](../../../fql/types/#array) or [Set](../../../fql/types/#set) of [Numbers](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | numbers | Array | Set | true | Numbers to average. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Arithmetic mean of the numbers. | ## [](#examples)Examples ### [](#average-an-array-of-numbers)Average an Array of numbers ```fql Math.mean([1, 2, 3, 4, 4]) ``` ``` 2.8 ``` ### [](#average-a-set-of-numbers)Average a Set of numbers ```fql // Converts an array to a Set. let set = [1, 2, 3, 4, 4.0].toSet() Math.mean(set) ``` ``` 2.8 ``` # `Math.min()` Get the smaller of the input parameter [Number](../../../fql/types/#number)s. ## [](#signature)Signature ```fql-sig Math.min(x: Number, y: Number) => Number ``` ## [](#description)Description Compare the input parameter [Number](../../../fql/types/#number)s and return the smaller [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | | y | Number | true | A number | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Smaller of the provided numbers. | ## [](#examples)Examples ```fql let a = 20; let b = 5; Math.min(a, b) ``` ``` 5 ``` # `Math.pow()` Get the value of a base raised to a power. ## [](#signature)Signature ```fql-sig Math.pow(x: Number, power: Number) => Number ``` ## [](#description)Description Gets the value of a base raised to a power. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Base number. | | power | Number | true | Exponent number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Number representing the provided base number taken to the power of the specified exponent. | ## [](#examples)Examples ```fql Math.pow(2, 8) ``` ``` 256.0 ``` # `Math.radians()` Convert the value of a [Number](../../../fql/types/#number) in degrees to radians. ## [](#signature)Signature ```fql-sig Math.radians(x: Number) => Number ``` ## [](#description)Description Gets the value of a [Number](../../../fql/types/#number) in degrees, in radians. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number of degrees. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of the provided degrees converted to radians. | ## [](#examples)Examples ```fql Math.radians(1) ``` ``` 0.017453292519943295 ``` # `Math.round()` Get the value of a [Number](../../../fql/types/#number) rounded to the nearest integer. ## [](#signature)Signature ```fql-sig Math.round(x: Number, precision: Number) => Number ``` ## [](#description)Description Gets the value of a [Number](../../../fql/types/#number) rounded to the nearest integer. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number to round. | | precision | Number | true | Number of decimal places to round to. If precision is negative, the method rounds to the left of the decimal point by the specified number of places. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Value of x rounded to the specified precision. | ## [](#examples)Examples ```fql Math.round(19.51555, 2) ``` ``` 19.52 ``` # `Math.sign()` Get the sign of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.sign(x: Number) => Number ``` ## [](#description)Description Gets the sign of a provided [Number](../../../fql/types/#number). If the [Number](../../../fql/types/#number) is positive, returns `1`. If the [Number](../../../fql/types/#number) is negative, returns `-1`. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | A number representing the sign of the provided number:1 = The number is positive.-1 = The number is negative. | ## [](#examples)Examples ```fql Math.sign(-3) ``` ``` -1 ``` # `Math.sin()` Get the sine of a [Number](../../../fql/types/#number) in radians. ## [](#signature)Signature ```fql-sig Math.sin(x: Number) => Number ``` ## [](#description)Description Gets the sine of a [Number](../../../fql/types/#number) in radians. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number representing an angle in radians. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | The sine of the provided number. | ## [](#examples)Examples ```fql Math.sin(1) ``` ``` 0.8414709848078965 ``` # `Math.sinh()` Get the hyperbolic sine of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.sinh(x: Number) => Number ``` ## [](#description)Description Gets the hyperbolic sine of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Hyperbolic sine of the provided number. | ## [](#examples)Examples ```fql Math.sinh(1) ``` ``` 1.1752011936438014 ``` # `Math.sqrt()` Get the square root of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.sqrt(x: Number) => Number ``` ## [](#description)Description Gets the square root of a [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number greater than or equal to zero. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Square root of the provided number. | ## [](#examples)Examples ```fql Math.sqrt(2) ``` ``` 1.4142135623730951 ``` # `Math.sum()` Get the sum of an [Array](../../../fql/types/#array) or [Set](../../../fql/types/#set) of [Number](../../../fql/types/#number)s. ## [](#signatures)Signatures ```fql-sig Math.sum(numbers: Array) => Number Math.sum(numbers: Set) => Number ``` ## [](#description)Description Get the sum of an [Array](../../../fql/types/#array) or [Set](../../../fql/types/#set) of [Number](../../../fql/types/#number)s. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | numbers | Array or Set of Numbers | true | Numbers to sum. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Sum of the provided numbers. | ## [](#examples)Examples ### [](#sum-an-array-of-numbers)Sum an Array of numbers ```fql Math.sum([1, 2, 3]) ``` ``` 6 ``` ### [](#sum-a-set-of-numbers)Sum a Set of numbers ```fql // `toSet()` converts the Array of numbers to a Set. let set = [1, 2, 3].toSet() Math.sum(set) ``` ``` 6 ``` # `Math.tan()` Get the tangent of a [Number](../../../fql/types/#number) in radians. ## [](#signature)Signature ```fql-sig Math.tan(x: Number) => Number ``` ## [](#description)Description Gets the tangent of a [Number](../../../fql/types/#number) in radians. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | Number representing an angle in radians. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Tangent of the provided number. | ## [](#examples)Examples ```fql Math.tan(1) ``` ``` 1.5574077246549023 ``` # `Math.tanh()` Get the hyperbolic tangent of a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig Math.tanh(x: Number) => Number ``` ## [](#description)Description Gets the hyperbolic tangent of a provided [Number](../../../fql/types/#number). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Hyperbolic tangent of the provided number. | ## [](#examples)Examples ```fql Math.tanh(1) ``` ``` 0.7615941559557649 ``` # `Math.trunc()` Truncate a [Number](../../../fql/types/#number) to a given precision. ## [](#signature)Signature ```fql-sig Math.trunc(x: Number, precision: Number) => Number ``` ## [](#description)Description Returns a provided [Number](../../../fql/types/#number), truncated to a specified precision, depending on the underlying representation of the floating point number. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | x | Number | true | A number. | | precision | Number | true | Precision to truncate to. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | The provided number, truncated to the specified precision. | ## [](#examples)Examples ```fql Math.trunc(12.123, 1) ``` ``` 12.1 ``` Note that the result might reflect the underlying imprecision of the representation of a floating point number: ```fql Math.trunc(12.123, 3) ``` ``` 12.122 ``` # Object FQL [Objects](../../fql/types/#object) are collections of key-value pairs, similar to JSON Objects. The FQL API’s Object module contains methods that let you manage and manipulate Objects. ## [](#static-methods)Static methods You can use the following static methods to manage and manipulate Objects in FQL. | Method | Description | | --- | --- | --- | --- | | Object.assign() | Copies properties from a source Object to a destination Object. | | Object.entries() | Convert an Object to an Array of key-value pairs. | | Object.fromEntries() | Convert an Array of key-value pairs to an Object. | | Object.hasPath() | Test if an Object has a property. | | Object.keys() | Get an Object's top-level property keys as an Array. | | Object.select() | Get an Object property’s value by its path. | | Object.toString() | Convert an Object to a String. | | Object.values() | Get an Object's property values as an Array. | # `Object.assign()` Copies properties from a source [Object](../../../fql/types/#object) to a destination [Object](../../../fql/types/#object). ## [](#signature)Signature ```fql-sig Object.assign(destination: { *: A }, source: { *: B }) => { *: A | B } ``` ## [](#description)Description `Object.assign()` copies properties from a source Object to a destination Object. If the source and destination Object have a property with the same key, the value from the source Object is used. If a property in the source Object doesn’t exist in the destination Object, the property is added to the destination Object. `Object.assign()` doesn’t remove `null` properties. ### [](#convert-documents-to-objects)Convert documents to Objects You can use `Object.assign()` to convert a [document](../../../../learn/data-model/documents/) into an Object. This can be useful for transforming results and manipulating document data without mutating the underlying document. See [Convert a document to an Object](#doc-to-obj). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | destination | Object containing fields of Any type. | true | The destination Object that the source’s properties are copied to. | | source | Object containing fields of Any type. | true | Source Object containing properties to copy to the destination Object. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | Updated destination Object. | ## [](#examples)Examples ### [](#basic-example)Basic example The following examples copies properties from a source Object to an empty destination Object: ```fql Object.assign({ }, { a: 0, b: 'x' }) ``` ``` { a: 0, b: "x" } ``` ### [](#merge-properties)Merge properties You can use `Object.assign()` to merge the properties of the source and destination Object: ```fql Object.assign({ a: 0 }, { b: 'x' }) ``` ``` { a: 0, b: "x" } ``` ### [](#doc-to-obj)Convert a document to an Object You can use `Object.assign()` to convert a [document type](../../../../learn/data-model/documents/#document-type) into an [Object](../../../fql/types/#object): ```fql // Get a Category collection document. let category: Any = Category.byName("frozen").first() // Convert the Category document to an Object. Object.assign({ }, category) ``` The query returns an Object, not a document type: ``` { id: "456", coll: Category, ts: Time("2099-10-02T22:37:39.583Z"), products: { data: [ { id: "333", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") } ] }, name: "frozen", description: "Frozen Foods" } ``` # `Object.entries()` Convert an [Object](../../../fql/types/#object) to an [Array](../../../fql/types/#array) of key-value pairs. ## [](#signature)Signature ```fql-sig Object.entries(object: { *: A }) => Array<[String, A]> ``` ## [](#description)Description `Object.entries()` gets an Object’s properties as Array elements. You can then iterate through the Array using one of the following methods: * [`array.forEach()`](../../array/foreach/) * [`array.map()`](../../array/map/) * [`array.flatMap()`](../../array/flatmap/) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Object containing fields of Any type. | true | Object to convert to an Array | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of the Object’s key-value pairs. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Object containing the name and stock quantity // of various products. let products = { bananas: 300, limes: 200, lemons: 500 } // Convert the Object to an Array. Object.entries(products) ``` ``` [ [ "bananas", 300 ], [ "limes", 200 ], [ "lemons", 500 ] ] ``` ### [](#iterate-through-an-object)Iterate through an Object You can use the following methods to iterate through the Array returned by `Object.entries()`: * [`array.forEach()`](../../array/foreach/) * [`array.map()`](../../array/map/) * [`array.flatMap()`](../../array/flatmap/) Extending the previous example: ```fql // Object containing the name and stock quantity // of various products. let products = { bananas: 300, limes: 200, lemons: 500 } // Convert the Object to an Array. let prodArray = Object.entries(products) // Iterate through the Array. prodArray.map(product => { // Concatenate each product's name and stock. product[0] + ": " + product[1].toString() }) ``` ``` [ "bananas: 300", "limes: 200", "lemons: 500" ] ``` ### [](#obj-transform)Transform Objects You can use [`Object.entries()`](./), [`Object.fromEntries()`](../fromentries/), and [Array methods](../../array/) to transform objects: ```fql // This query multiplies each Number in an Object // by 2. // An object containing various Numbers. let nums = { a: 1, b: 2, c: 3 } // Convert the Array to an Object. let numArray = Object.entries(nums) // Iterate through the Array, multiplying // each value and outputting an Object. Object.fromEntries( numArray.map(elem => { let key = elem[0] let value = elem[1] [ key, value * 2 ] }) ); ``` ``` { a: 2, b: 4, c: 6 } ``` # `Object.fromEntries()` Convert an [Array](../../../fql/types/#array) of key-value pairs to an [Object](../../../fql/types/#object). ## [](#signature)Signature ```fql-sig Object.fromEntries(entries: Array<[String, A]>) => { *: A } ``` ## [](#description)Description `Object.fromEntries()` creates an Object from an Array of key-value pairs. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | entries | Array | true | An Array containing nested Arrays of key-value pairs. Each nested Array represents an Object property and should have two elements:0: A String representing the property key.1: The property value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Object | Object with properties from the entries Array. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Array containing the name and stock quantity // of various products. let products = [ [ "bananas", 300 ], [ "limes", 200 ], [ "lemons", 500 ] ] // Convert the Array to an Object. Object.fromEntries(products) ``` ``` { bananas: 300, limes: 200, lemons: 500 } ``` ### [](#obj-transform)Transform Objects You can use [`Object.entries()`](../entries/), [`Object.fromEntries()`](./), and [Array methods](../../array/) to transform objects: ```fql // This query multiplies each Number in an Object // by 2. // An object containing various Numbers. let nums = { a: 1, b: 2, c: 3 } // Convert the Array to an Object. let numArray = Object.entries(nums) // Iterate through the Array, multiplying // each value and outputting an Object. Object.fromEntries( numArray.map(elem => { let key = elem[0] let value = elem[1] [ key, value * 2 ] }) ); ``` ``` { a: 2, b: 4, c: 6 } ``` # `Object.hasPath()` Test if an [Object](../../../fql/types/#object) has a property. ## [](#signature)Signature ```fql-sig Object.hasPath(object: { *: Any }, path: Array) => Boolean ``` ## [](#description)Description `Object.hasPath()` tests if an Object contains a property based on a provided path. The path is defined as an [Array](../../../fql/types/#array) of [Strings](../../../fql/types/#string), where each String represents a property key in the Object’s hierarchy. The method traverses the Object structure following the path to search for the property. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Object containing fields of Any type. | true | Object to test for a property. | | path | Array of Strings | true | Path to an Object property. Each element in the Array represents a level in the Object’s hierarchy. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Object contains the property. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Test if the Object contains the top-level `foo` property. Object.hasPath({ foo : 'bar' }, ['foo']) ``` ``` true ``` ### [](#property-that-doesnt-exist)Property that doesn’t exist ```fql // Test if the Object contains the top-level `baz` property. Object.hasPath({ foo : 'bar' }, ['baz']) ``` ``` false ``` ### [](#nested-property)Nested property ```fql // Defines an Object with customer data. let customer = { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } // Test if the customer Object contains the // nested `address.state` property. Object.hasPath(customer, ['address', 'state']) ``` ``` true ``` ### [](#nested-property-that-doesnt-exist)Nested property that doesn’t exist ```fql // Defines an Object with customer data. let customer = { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } // Test if the customer Object contains the // nested `address.zipCode` property. Object.hasPath(customer, ['address', 'zipCode']) ``` ``` false ``` # `Object.keys()` Get an [Object](../../../fql/types/#object)'s top-level property keys as an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig Object.keys(object: Any) => Array ``` ## [](#description)Description `Object.keys()` returns an Array with the top-level property keys of a provided Object. The Array does not contain keys for nested properties. `Object.keys()` does not change the original object. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Object | true | Object to extract keys from. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array of Strings | An array containing the keys of the Object as Strings. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql Object.keys({ bananas: 300, limes: 200, lemons: 500 }) ``` ``` [ "bananas", "limes", "lemons" ] ``` ### [](#nested-object-properties)Nested Object properties `Object.keys()` only extracts an Object’s top-level property keys. It doesn’t extract nested property keys. ```fql Object.keys({ bananas: 300, limes: 200, lemons: { organic: 500 } }) ``` ``` // The results don't includes the nested `lemons.organic` // property key. [ "bananas", "limes", "lemons" ] ``` # `Object.select()` Get an [Object](../../../fql/types/#object) property’s value by its path. ## [](#signature)Signature ```fql-sig Object.select(object: { *: Any }, path: Array) => Any ``` ## [](#description)Description `Object.select()` gets an [Object](../../../fql/types/#object) property’s value by its path. The path is defined as an [Array](../../../fql/types/#array) of [Strings](../../../fql/types/#string), where each String represents a property key in the Object’s hierarchy. The method traverses the Object structure following the path to retrieve the desired value. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Object containing fields of Any type | true | Object to extract the property from. | | path | Array of Strings | true | Path to a property in the Object. Each element in the Array represents a level in the Object’s hierarchy. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | Value of the property at the path. If the path doesn’t exist or is undefined, the value is null. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Gets the value of the top-level `foo` property. Object.select({ foo : 'bar' }, ['foo']) ``` ``` "bar" ``` ### [](#nested-property)Nested property ```fql // Defines an Object with customer data. let customer = { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } // Gets the customer's nested `address.state` property. Object.select(customer, ['address', 'state']) ``` ``` "DC" ``` ### [](#retrieve-a-nested-object)Retrieve a nested Object ```fql // Defines an Object with customer data. let customer = { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "street": "87856 Mendota Court", "city": "Washington", "state": "DC", "postalCode": "20220", "country": "US" } } // Gets the customer's nested `address` property, // which is an Object. Object.select(customer, ['address']) ``` ``` { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } ``` # `Object.toString()` Convert an [Object](../../../fql/types/#object) to a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Object.toString(object: Any) => String ``` ## [](#description)Description `Object.toString()` creates a String representation of a provided Object. This method is useful for debugging, logging, or when you need a String representation of complex Objects. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Any | true | Object to convert to a String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String representation of the Object. Special characters are properly escaped. | ## [](#examples)Examples ```fql Object.toString({a: "test"}) ``` ``` "{ a: \"test\" }" ``` ### [](#nested-object)Nested Object ```fql // Defines an Object with customer data. let customer = { "name": "Ruby Von Rails", "email": "ruby@example.com", "address": { "city": "Washington", "state": "DC" } } Object.toString(customer) ``` ``` "{ name: \"Ruby Von Rails\", email: \"ruby@example.com\", address: { city: \"Washington\", state: \"DC\" } }" ``` ### [](#object-with-multiple-data-types)Object with Multiple Data Types ```fql // Defines an Object. let data = { string: "Hello", number: 42, boolean: true, null: null, array: [1, 2, 3] } Object.toString(data) ``` ``` "{ string: \"Hello\", number: 42, boolean: true, null: null, array: [1, 2, 3] }" ``` ### [](#objects-containing-document-references)Objects containing document references ```fql // Defines an Object. let data = { // Contains a reference to a Category // collection document. category: Category.byName("produce").first(), } Object.toString(data) ``` ``` "{ category: { id: ID(\"789\"), coll: Category, ts: Time(\"2099-10-02T22:37:39.583Z\"), products: [set], name: \"produce\", description: \"Fresh Produce\" } }" ``` ### [](#objects-containing-set-references)Objects containing Set references ```fql // Defines an Object. let data = { // Contains a reference to a Set of all // Category collection documents. category: Category.all(), } Object.toString(data) ``` ``` "{ category: [set] }" ``` # `Object.values()` Get an [Object](../../../fql/types/#object)'s property values as an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig Object.values(object: { *: A }) => Array ``` ## [](#description)Description `Object.values()` returns an [Array](../../../fql/types/#array) containing an Object’s property values. `Object.values()` does not change the original Object. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | object | Object containing fields of Any type. | true | Object to get property values from. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of values extracted from the Object. | ## [](#examples)Examples ## [](#basic-example)Basic example ```fql Object.values({ a: 0, b: 1 }) ``` ``` [ 0, 1 ] ``` ## [](#objects-with-non-scalar-values)Objects with non-scalar values Any nested Arrays in the original Object are left intact, resulting in a multi-dimensional Array. For example: ```fql Object.values({ a: [1, 2], b: 'foo' }) ``` ``` [ [ 1, 2 ], "foo" ] ``` Similarly, any nested Objects in the original Object are left intact: ```fql Object.values({ a: { x: 1, y: 2 }, b: 'foo' }) ``` ``` [ { x: 1, y: 2 }, "foo" ] ``` # Query ## [](#description)Description The `Query` namespace has security functions that return access information about a caller. ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Query.identity() | Get the identity document for the query’s authentication token. | | Query.isEnvProtected() | Test if the queried database is in protected mode. | | Query.isEnvTypechecked() | Test if the queried database is typechecked. | | Query.token() | Get the Token document or JWT payload for the query’s authentication secret. | # `Query.identity()` | Learn: Attribute-based access control (ABAC) | | --- | --- | --- | Get the [identity document](../../../../learn/security/tokens/#identity-document) for the query’s [authentication token](../../../../learn/security/tokens/). ## [](#signature)Signature ```fql-sig Query.identity() => { *: Any } | Null ``` ## [](#description)Description Gets the [identity document](../../../../learn/security/tokens/#identity-document) for the query’s [authentication token](../../../../learn/security/tokens/). You can call `identity()` in role-related predicates used for [attribute-based access control (ABAC)](../../../../learn/security/abac/). If the query is authenticated using a [JWT](../../../../learn/security/access-providers/) or [key](../../../../learn/security/keys/), the method returns `null`. JWTs and keys aren’t tied to an identity document. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Object | identity document for the authentication token. | | Null | No identity document is associated with the authentication secret. | ## [](#examples)Examples ```fql Query.identity() ``` ``` { id: "111", coll: Customer, ts: Time("2099-06-21T18:39:00.735Z"), cart: Order("413090255209497088"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } } ``` # `Query.isEnvProtected()` Test if the queried database is in [protected mode](../../../../learn/schema/#protected-mode). ## [](#signature)Signature ```fql-sig Query.isEnvProtected() => Boolean ``` ## [](#description)Description Tests if the queried database is in [protected mode](../../../../learn/schema/#protected-mode), which prohibits destructive operations on a database’s collections. The method checks the database to which the query’s [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the database is in protected mode. Otherwise, false. | ## [](#examples)Examples Call `isEnvProtected()` with built-in `Admin` role, on an unprotected database: ```fql Query.isEnvProtected() ``` ``` false ``` Calling `isEnvProtected()` with built-in `Server` role fails: ```fql Query.isEnvProtected() ``` ``` permission_denied: Insufficient privileges to perform the action. error: Insufficient privileges to perform the action. at *query*:1:21 | 1 | Query.isEnvProtected() | ^^ | ``` # `Query.isEnvTypechecked()` Test if the queried database is [typechecked](../../../../learn/query/static-typing/). ## [](#signature)Signature ```fql-sig Query.isEnvTypechecked() => Boolean ``` ## [](#description)Description Tests if the queried database is [typechecked](../../../../learn/query/static-typing/). The method checks the database to which the query’s [authentication secret](../../../../learn/security/authentication/#secrets) is scoped. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the database is in typechecked. Otherwise, false. | ## [](#examples)Examples ```fql Query.isEnvTypechecked() ``` ``` true ``` # `Query.token()` Get the [`Token` document](../../../../learn/security/tokens/) or [JWT payload](../../../../learn/security/access-providers/) for the query’s [authentication secret](../../../../learn/security/authentication/#secrets). ## [](#signature)Signature ```fql-sig Query.token() => { *: Any } | Null ``` ## [](#description)Description Gets the [`Token` document](../../../../learn/security/tokens/) or [JWT payload](../../../../learn/security/access-providers/) for the query’s [authentication secret](../../../../learn/security/authentication/#secrets). If the secret is a [token](../../../../learn/security/tokens/), the method returns the token’s [`Token` system collection document](../../token/). This token document is distinct from the token’s [identity document](../../../../learn/security/tokens/#identity-document). If the secret is a [JWT](../../../../learn/security/access-providers/), the method returns the JWT’s payload. If the secret is a [key](../../../../learn/security/keys/), the method returns `null`. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Object | Token document or JWT payload. | | Null | The authentication secret is a key. | ## [](#examples)Examples ```fql Query.token() ``` ``` { id: "412664453937496576", coll: Token, ts: Time("2099-07-06T19:11:13.570Z"), document: Customer("111") } ``` # Role | Learn: Roles | | --- | --- | --- | Fauna uses [secrets](../../../learn/security/authentication/#secrets) for authentication and authorization. Roles determine a secret’s privileges, which control data access. ## [](#collection)`Role` collection Fauna stores user-defined roles as documents in the `Role` system collection. These documents are an FQL version of the FSL [role schema](../../fsl/role/). `Role` documents have the following FQL structure: ``` { name: "customer", coll: Role, ts: Time("2099-07-31T12:37:05.280Z"), privileges: [ { resource: "Product", actions: { read: true } }, { resource: "Order", actions: { read: "(ref) => Query.identity() == ref.customer" } }, { resource: "Customer", actions: { read: "(ref) => Query.identity() == ref" } }, { resource: "getOrCreateCart", actions: { call: "(id) => Query.identity()?.id == id" } }, { resource: "checkout", actions: { call: "(name) => true" } } ], membership: [ { resource: "Customer" } ], data: { desc: "End user customer role" } } ``` | Field name | Value type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | name | String | | true | Unique name for the role in the database.Must begin with a letter. Can only include letters, numbers, and underscores. admin, server, and server-readonly are reserved and can’t be used. | | coll | Collection | true | | Collection name: Role. | | ts | Time | true | | Last time the document was created or updated. | | privileges | Array | | | Allows one or more actions on a resource. See Privileges definition. | | membership | Array | | | Assigns the role to tokens based on the token’s identity document. See Membership definition. | | data | Object | | | Arbitrary user-defined metadata for the document. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Role` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Role.all() | Get a Set of all user-defined roles. | | Role.byName() | Get a user-defined role by its name. | | Role.create() | Create a user-defined role. | | Role.firstWhere() | Get the first user-defined role matching a provided predicate. | | Role.toString() | Get "Role" as a String. | | Role.where() | Get a Set of user-defined roles that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `Role` documents in FQL. | Method | Description | | --- | --- | --- | --- | | role.delete() | Delete a user-defined role. | | role.exists() | Test if a user-defined role exists. | | role.replace() | Replace a user-defined role. | | role.update() | Update a user-defined role. | # `Role.all()` | Learn: Roles | | --- | --- | --- | Get a Set of all [user-defined roles](../../../../learn/security/roles/). ## [](#signature)Signature ```fql-sig Role.all() => Set Role.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [user-defined roles](../../../../learn/security/roles/), represented as [`Role` documents](../), for the database. To limit the returned Set, you can provide an optional range. `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). If this method is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Role documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Role.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all roles are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Role document. | | to | Any | | End of the range (inclusive). Must be an Role document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Role documents in the provided range. If a range is omitted, all roles are returned.The Set is empty if:The database has no roles.There are no roles in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all roles for the database: ```fql Role.all() ``` ``` { data: [ { name: "manager", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] }, { name: "customer", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] } ] } ``` 2. Given the previous Set, get all roles starting with `manager` (inclusive): ```fql Role.all({ from: Role.byName("manager") }) ``` ``` { data: [ { name: "manager", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] }, { name: "customer", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] } ] } ``` 3. Get a Set of roles from `manager` (inclusive) to `customer` (inclusive): ```fql Role.all({ from: Role.byName("manager"), to: Role.byName("customer") }) ``` ``` { data: [ { name: "manager", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] }, { name: "customer", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] } ] } ``` 4. Get a Set of roles up to `customer` (inclusive): ```fql Role.all({ to: Role.byName("customer") }) ``` ``` { data: [ { name: "manager", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] }, { name: "customer", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ ... ], membership: [ ... ] } ] } ``` # `Role.byName()` | Learn: Roles | | --- | --- | --- | Get a [user-defined role](../../../../learn/security/roles/) by its name. ## [](#signature)Signature ```fql-sig Role.byName(name: String) => NamedRef ``` ## [](#description)Description Gets a [user-defined role](../../../../learn/security/roles/), represented as an [`Role` document](../), by its name. `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | name | String | true | name of the Role document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NamedRef | Resolved reference to the Role document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Role.byName("manager") ``` ``` { name: "manager", coll: Role, ts: Time("2099-10-28T16:01:40.805Z"), privileges: [ { resource: "OrderItem", actions: { create: true, read: true, write: true, delete: true } }, { resource: "Customer", actions: { read: true } }, { resource: "Manager", actions: { read: "(doc) => Query.identity() == doc && Date.today().dayOfWeek < 6" } }, { resource: "getOrCreateCart", actions: { call: true } }, { resource: "checkout", actions: { call: <<-END (args) => { let order = Order.byId(args[0])! order?.customer == Query.identity() } END } } ], membership: [ { resource: "Manager" }, { resource: "User", predicate: "(user) => user.accessLevel == \"manager\"" } ] } ``` # `Role.create()` | Learn: Roles | | --- | --- | --- | Create a [user-defined role](../../../../learn/security/roles/). ## [](#signature)Signature ```fql-sig Role.create(data: { name: String, privileges: Any | Null, membership: Any | Null, data: { *: Any } | Null }) => Role ``` ## [](#description)Description Creates a [user-defined role](../../../../learn/security/roles/) with the provided document fields. Fauna stores user-defined roles as documents in the [`Role` system collection](../). `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method adds a role to the staged schema, not the active schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the new Role document.For supported document fields, see Role collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Role | The new Role document. | ## [](#role-create-example)Examples ```fql Role.create({ name: "customer", privileges: [ { resource: "Product", actions: { read: true } }, { resource: "Order", actions: { read: "(ref) => Query.identity() == ref.customer" } }, { resource: "Customer", actions: { read: "(ref) => Query.identity() == ref" } }, { resource: "getOrCreateCart", actions: { call: "(id) => Query.identity()?.id == id" } }, { resource: "checkout", actions: { call: "(name) => true" } } ], membership: [ { resource: "Customer" } ], data: { desc: "End user customer role" } }) ``` ``` { name: "customer", coll: Role, ts: Time("2099-07-31T12:37:05.280Z"), privileges: [ { resource: "Product", actions: { read: true } }, { resource: "Order", actions: { read: "(ref) => Query.identity() == ref.customer" } }, { resource: "Customer", actions: { read: "(ref) => Query.identity() == ref" } }, { resource: "getOrCreateCart", actions: { call: "(id) => Query.identity()?.id == id" } }, { resource: "checkout", actions: { call: "(name) => true" } } ], membership: [ { resource: "Customer" } ], data: { desc: "End user customer role" } } ``` # `Role.firstWhere()` | Learn: Roles | | --- | --- | --- | Get the first [user-defined role](../../../../learn/security/roles/) matching a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Role.firstWhere(pred: (Role => Boolean)) => Role | Null ``` ## [](#description)Description Gets the first [user-defined role](../../../../learn/security/roles/), represented as a [`Role` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Role document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Role document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Role | First Role document that matches the predicate. | | Null | No Role document matches the predicate. | ## [](#examples)Examples ```fql Role.firstWhere(.name.includes("manager")) ``` ``` { name: "manager", coll: Role, ts: Time("2099-10-28T16:01:40.805Z"), privileges: [ { resource: "OrderItem", actions: { create: true, read: true, write: true, delete: true } }, { resource: "Customer", actions: { read: true } }, { resource: "Manager", actions: { read: "(doc) => Query.identity() == doc && Date.today().dayOfWeek < 6" } }, { resource: "getOrCreateCart", actions: { call: true } }, { resource: "checkout", actions: { call: <<-END (args) => { let order = Order.byId(args[0])! order?.customer == Query.identity() } END } } ], membership: [ { resource: "Manager" }, { resource: "User", predicate: "(user) => user.accessLevel == \"manager\"" } ] } ``` # `Role.toString()` | Learn: Roles | | --- | --- | --- | Get `"Role"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Role.toString() => String ``` ## [](#description)Description Returns the name of the [`Role` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Role" | ## [](#examples)Examples ```fql Role.toString() ``` ``` "Role" ``` # `Role.where()` | Learn: Roles | | --- | --- | --- | Get a Set of [user-defined roles](../../../../learn/security/roles/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Role.where(pred: (Role => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [user-defined roles](../../../../learn/security/roles/), represented as [`Role` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). If `Role.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Role document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Role documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Role documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Role.where(.name.includes("manager")) ``` ``` { data: [ { name: "manager", coll: Role, ts: Time("2099-10-28T16:01:40.805Z"), privileges: [ { resource: "OrderItem", actions: { create: true, read: true, write: true, delete: true } }, { resource: "Customer", actions: { read: true } }, { resource: "Manager", actions: { read: "(doc) => Query.identity() == doc && Date.today().dayOfWeek < 6" } }, { resource: "getOrCreateCart", actions: { call: true } }, { resource: "checkout", actions: { call: <<-END (args) => { let order = Order.byId(args[0])! order?.customer == Query.identity() } END } } ], membership: [ { resource: "Manager" }, { resource: "User", predicate: "(user) => user.accessLevel == \"manager\"" } ] } ] } ``` # `role.delete()` | Learn: Roles | | --- | --- | --- | Delete a [user-defined role](../../../../learn/security/roles/). ## [](#signature)Signature ```fql-sig delete() => NullRole ``` ## [](#description)Description Deletes a [user-defined role](../../../../learn/security/roles/), represented as a [`Role` document](../). `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#staged-schema)Staged schema You can’t delete a role while a database has [staged schema](../../../../learn/schema/manage-schema/#staged). If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullRole | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql Role.byName("customer")!.delete() ``` ``` Role.byName("customer") /* deleted */ ``` # `role.exists()` | Learn: Roles | | --- | --- | --- | Test if a [user-defined role](../../../../learn/security/roles/) exists. ## [](#signature)Signature ```fql-sig exists() => Boolean ``` ## [](#description)Description Tests if a [UDF](../../../../learn/security/roles/), represented as an [`Role` document](../), exists. `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Role document exists. If false, the Role document doesn’t exist. | ## [](#examples)Examples ```fql Role.byName("manager").exists() ``` ``` true ``` # `role.replace()` | Learn: Roles | | --- | --- | --- | Replace a [user-defined role](../../../../learn/security/roles/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => Role ``` ## [](#description)Description Replaces all fields in a [user-defined role](../../../../learn/security/roles/), represented as an [`Role` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `coll` and `ts` metadata fields, are removed. `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a role while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Fields for the Role document. Fields not present, excluding the coll and ts metadata fields, in the object are removed.For supported document fields, see Role collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Role | Role document with replaced fields. | ## [](#examples)Examples ```fql Role.byName("manager")?.replace({ name: "manager", privileges: [ { resource: "OrderItem", actions: { create: true, read: true, write: true, delete: true } }, { resource: "Customer", actions: { read: true } }, { resource: "Manager", actions: { read: "(doc) => Query.identity() == doc && Date.today().dayOfWeek < 6" } }, { resource: "getOrCreateCart", actions: { call: true } }, { resource: "checkout", actions: { call: <<-END (args) => { let order = Order.byId(args[0])! order?.customer == Query.identity() } END } } ], membership: [ { resource: "Manager" }, { resource: "User", predicate: "(user) => user.accessLevel == \"manager\"" } ] }) ``` ``` { name: "manager", coll: Role, ts: Time("2099-10-28T16:14:20.640Z"), privileges: [ { resource: "OrderItem", actions: { create: true, read: true, write: true, delete: true } }, { resource: "Customer", actions: { read: true } }, { resource: "Manager", actions: { read: "(doc) => Query.identity() == doc && Date.today().dayOfWeek < 6" } }, { resource: "getOrCreateCart", actions: { call: true } }, { resource: "checkout", actions: { call: <<-END (args) => { let order = Order.byId(args[0])! order?.customer == Query.identity() } END } } ], membership: [ { resource: "Manager" }, { resource: "User", predicate: "(user) => user.accessLevel == \"manager\"" } ] } ``` # `role.update()` | Learn: Roles | | --- | --- | --- | Update a [user-defined role](../../../../learn/security/roles/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => Role ``` ## [](#description)Description Updates a [user-defined role](../../../../learn/security/roles/), represented as an [`Role` document](../../accessprovider/), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. `Role` documents are FQL versions of a database’s FSL [role schema](../../../fsl/role/). See [Roles](../../../../learn/security/roles/). ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `coll` * `ts` ### [](#staged-schema)Staged schema If a database has [staged schema](../../../../learn/schema/manage-schema/#staged), this method interacts with the database’s staged schema, not the active schema. You can’t rename a role while a database has staged schema. If the database has no staged schema, using this method is equivalent to making an [unstaged schema change](../../../../learn/schema/manage-schema/#unstaged). Changes are applied immediately to the database’s active schema. #### [](#concurrent)Avoid concurrent schema changes Concurrent [unstaged schema changes](../../../../learn/schema/manage-schema/#unstaged) can cause [contended transactions](../../../../learn/transactions/contention/), even if the changes affect different resources. This includes unstaged changes made using: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) A schema change triggers a [transaction that validates the entire database schema](../../../../learn/schema/#validation). To avoid errors, do one of the following instead: * Run [staged schema changes](../../../../learn/schema/manage-schema/#staged) * Perform unstaged schema changes sequentially ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the Role document.For supported document fields, see Role collection.The object can’t include the following metadata fields:* coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Role | The updated Role document. | ## [](#examples)Examples ```fql Role.byName("manager")?.update({ membership: [ { resource: "Manager" } ], privileges: [ { resource: "Order", actions: { create: false, delete: false, read: true, write: false } }, { resource: "Product", actions: { create: true } } ], data: { custom: "some data" } }) ``` ``` { name: "manager", coll: Role, ts: Time("2099-07-27T22:40:32.735Z"), privileges: [ { resource: "Order", actions: { create: false, delete: false, read: true, write: false } }, { resource: "Product", actions: { create: true } } ], membership: [ { resource: "Manager" } ], data: { custom: "some data" } } ``` # Set | Learn: Sets | | --- | --- | --- | [Set](../../fql/types/#set) methods and properties. ## [](#description)Description A [Set](../../fql/types/#set) represents a group of values, for example, documents in a [Collection](../../fql/types/#collection). When a [Set](../../fql/types/#set) is returned from a query, it is materialized into a page of results that includes a subset of the [Set](../../fql/types/#set) with a pagination cursor. ## [](#eager)Lazy vs. Eager loading To minimize resource consumption, Set methods use lazy loading where possible. These methods defer the materialization of the calling Set and related computations until the data is explicitly needed. Other Set methods, such as [`set.includes()`](includes/), require eager loading. These methods materialize the entire calling Set upfront, even if not all data is returned in the results. For unindexed document Sets, this requires a read of each document in the Set. ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Set.paginate() | Get a page of paginated results using an after cursor. | | Set.sequence() | Create an ordered Set of Numbers given start and end values. | | Set.single() | Create a Set containing a single provided element. | ## [](#instance-methods)Instance methods | Method | Description | | --- | --- | --- | --- | | set.aggregate() | Aggregate all elements of a Set. | | set.any() | Test if any element of a Set matches a provided predicate. | | set.changesOn() | Create an event source that tracks changes to specified document fields in a supported Set. | | set.concat() | Concatenate two Sets. | | set.count() | Get the number of elements in a Set. | | set.distinct() | Get the unique elements of a Set. | | set.drop() | Drop the first N elements of a Set. | | set.eventsOn() | Create an event source that tracks changes to specified document fields in a supported Set. | | set.eventSource() | Create an event source that tracks changes to documents in a supported Set. | | set.every() | Test if every element of a Set matches a provided predicate. | | set.first() | Get the first element of a Set. | | set.firstWhere() | Get the first element of a Set that matches a provided predicate. | | set.flatMap() | Apply a provided function to each Set element and flatten the resulting Set by one level. | | set.fold() | Reduce the Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. | | set.foldRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. | | set.forEach() | Run a provided function on each element of a Set. Can perform writes. | | set.includes() | Test if the Set includes a provided element. | | set.isEmpty() | Test if a Set is empty. | | set.last() | Get the last element of a Set. | | set.lastWhere() | Get the last element of a Set that matches a provided predicate. | | set.map() | Apply a provided function to each element of a Set. Can’t perform writes. | | set.nonEmpty() | Test if a Set is not empty. | | set.order() | Sort a Set's elements. | | set.pageSize() | Set the maximum elements per page in paginated results. | | set.paginate() | Convert a Set to an Object with pagination. | | set.reduce() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from left to right. Uses the first element as the initial value. | | set.reduceRight() | Reduce a Set to a single, accumulated value by applying a provided function to each element. Iterates through elements from right to left. Uses the first element as the initial value. | | set.reverse() | Reverse the order of a Set's elements. | | set.take() | Get the first N elements of a Set. | | set.toArray() | Convert a Set to an Array. | | set.toStream() | Create an event source that tracks changes to documents in a supported Set. | | set.toString() | Return the string "[set]". | | set.where() | Get the elements of a Set that match a provided predicate. | # `Set.paginate()` | Learn: Sets | | --- | --- | --- | Get a page of [paginated results](../../../../learn/query/pagination/) using an `after` cursor. ## [](#signature)Signature ```fql-sig Set.paginate(cursor: String | SetCursor) => { data: Array, after: String | Null } Set.paginate(cursor: String | SetCursor, size: Number) => { data: Array, after: String | Null } ``` ## [](#description)Description Gets a page of [paginated results](../../../../learn/query/pagination/) using an [`after` cursor](../../../../learn/query/pagination/#cursor). The default page size of 16 can be changed using the [`set.paginate()`](../paginate/) or [`set.pageSize()`](../pagesize/) method, in the range 1 to 16000 (inclusive). The cursor is stable in the sense that pagination through a Set is done for a fixed snapshot time, giving you a view of your data as it existed across the whole Set at the instant you started paginating. For example, given Set \[_a_, _b_, _c_\] when you start paginating, one item at a time, even if you delete item _c_ after you started reading the Set, item _c_ is returned. The exception is if the history is no longer available for the deleted item because `history_days` is set to the default value of `0` or is less than the minimum valid time needed. In that case, the deleted item is not returned with the paginated results and an error is returned: `Requested timestamp ``` ## [](#description)Description Creates a [Set](../../../fql/types/#set) containing a single element. The element is passed to the method as an argument. You can use an event source to track changes to a [Set](../../../fql/types/#set) containing a single document. These event sources only emit events when the document changes. You typically use `Set.single()` to create a [Set](../../../fql/types/#set) from a [Document](../../../fql/types/#document) for a [document event source](../../../../learn/cdc/#doc). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Value for the returned Set's element. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing the provided element. | ## [](#examples)Examples The following uses `single()` to creates a [Set](../../../fql/types/#set) from a single document. ```fql // Uses the `Product` collection's `byName()` index and // the `first()` method to get a single document. let product = Product.byName("cups").first() Set.single(product) ``` ``` { data: [ { id: "111", coll: Product, ts: Time("2099-03-21T19:40:45.430Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") } ] } ``` You can call [`set.eventsOn()`](../eventson/) or [`set.eventSource()`](../eventsource/) on the [Set](../../../fql/types/#set) to create a [document event sources](../../../../learn/cdc/#doc). ```fql let product = Product.byName("cups").first() Set.single(product).eventSource() ``` The query returns an event source: ``` "g9WD1YPG..." ``` # `set.aggregate()` | Learn: Sets | | --- | --- | --- | Aggregate all elements of a Set. ## [](#signature)Signature ```fql-sig aggregate(seed: A, combiner: (A, A) => A) => A ``` ## [](#description)Description Aggregates all elements of the calling Set. There is no ordering expectation. The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `aggregate()` to sum stock counts let stockCounts = Product.all().map(doc => doc.stock ) stockCounts.aggregate(0, (a, b) => a + b) ``` Emits the following hint: ``` performance_hint: full_set_read - Using aggregate() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:22 | 3 | stockCounts.aggregate(0, (a, b) => a + b) | ^^^^^^^^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let stockCounts = Product.all().take(20).map(doc => doc.stock ) stockCounts.aggregate(0, (a, b) => a + b) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Number | true | Initial state value. | | combiner | Function | true | Anonymous FQL function that aggregates the elements. | ### [](#combiner-function-parameters)Combiner function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | | Value returned by the previous invocation. | | current | Generic | | Current Set value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Aggregate of the iterable. If the iterable is empty, the seed is returned. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3, 4].toSet() set.aggregate(0, (a, b) => a + b) ``` ``` 10 ``` # `set.any()` | Learn: Sets | | --- | --- | --- | Test if any element of a Set matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig any(predicate: (A => Boolean | Null)) => Boolean ``` ## [](#description)Description Tests if any element of the calling Set matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts a Set element as its only argument. Supports shorthand-syntax for objects and documents.Returns Boolean or Null.The method returns true if the predicate is true for any element in the Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the predicate is true for one or more elements in the Set. Otherwise, false. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.any(v => v == 2) ``` ``` true ``` # `set.concat()` | Learn: Sets | | --- | --- | --- | Concatenate two [Set](../../../fql/types/#set)s. | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig concat(other: Set) => Set ``` ## [](#description)Description Creates a [Set](../../../fql/types/#set) by copying the calling Set to a new Set and appending another Set. The calling Set and the other Set aren’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | other | Set | true | Set to append to the calling Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | New Set composed of the concatenated Sets. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let setA = [1, 2, 3].toSet() let setB = [4, 5, 6].toSet() setA.concat(setB) ``` ``` { data: [ 1, 2, 3, 4, 5, 6 ] } ``` # `set.count()` | Learn: Sets | | --- | --- | --- | Get the number of elements in a [Set](../../../fql/types/#set). ## [](#signature)Signature ```fql-sig count() => Number ``` ## [](#description)Description Gets the number of elements in the calling [Set](../../../fql/types/#set). ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `count()` to get a count of all products Product.all().count() ``` Emits the following hint: ``` performance_hint: full_set_read - Using count() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:2:20 | 2 | Product.all().count() | ^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` Product.all().take(99).count() ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-use-on-large-sets)Avoid use on large sets This method scans the full [Set](../../../fql/types/#set), which can cause many reads and might time out for large [Set](../../../fql/types/#set)s. ### [](#considerations)Considerations A document update stores a new version of the document for which counter data is poorly suited for database storage. If a frequently updated counter is essential, an event-sourcing technique is recommended to reduce database contention and reduce unnecessary database operations. If the event sourcing pattern isn’t suitable, the following improvements might be considered: * Set the collection’s [`history_days` setting](../../../../learn/doc-history/) to a small value, with a zero value recommended. Document history continues to be collected, but is removed sooner than the default zero days. * Periodically, run a query to explicitly remove document history. * Instead of attempting to implement a real-time counter, consider storing countable documents as a cache and periodically analyzing cache contents to update a reporting document. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Count of values in the Set. | ## [](#examples)Examples Get a count `Product` documents with a `name` of `limes`: ```fql Product.all().count() ``` ``` 9 ``` # `set.distinct()` | Learn: Sets | | --- | --- | --- | Get the unique elements of a [Set](../../../fql/types/#set). ## [](#signature)Signature ```fql-sig distinct() => Set ``` ## [](#description)Description Gets the unique elements of the calling [Set](../../../fql/types/#set). The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `distinct()` to get all unique products Product.all().distinct() ``` Emits the following hint: ``` performance_hint: full_set_read - Using distinct() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:2:23 | 2 | Product.all().distinct() | ^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` Product.all().take(20).distinct() ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-use-on-large-sets)Avoid use on large Sets Avoid using `distinct()` on large or unbounded Sets that contain 16,000 or more documents. If a Set contains 16,000 or more documents, the query requires pagination. [`array.distinct()`](../../array/distinct/) would only be able to extract unique elements from each page of results. Instead, retrieve all field values and process them on the client side. See [Get unique field values](../../../../learn/query/patterns/get-unique-values/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Unique elements in the Set. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // `toSet()` converts an Array to a Set. let set = [1, 1, 2, 3, 3].toSet() set.distinct() ``` ``` { data: [ 1, 2, 3 ] } ``` ### [](#get-unique-products-ordered-by-a-customer)Get unique products ordered by a customer In this example, you’ll use `distinct()` to get a Set of unique products ordered by a specific customer. The example uses the `Order` collection. `Order` collection documents have the following structure: ``` { id: "12345", coll: Order, ts: Time("2099-07-31T12:42:19Z"), // `items` contains a Set of `OrderItem` documents. items: { data: [ { id: "112233", coll: OrderItem, ts: Time("2099-07-31T12:42:19Z"), order: Order("12345"), product: Product("111"), quantity: 2 }, ... ] }, total: 5392, status: "cart", // `customer` contains a `Customer` document. customer: { id: "111", coll: Customer, ts: Time("2099-07-31T12:42:19Z"), cart: Order("412483941752112205"), // `orders` contains a Set of `OrderItem` documents. orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, createdAt: Time("2099-07-31T12:42:18.774426Z"), payment: {} } ``` The query: ```fql // Uses the `Customer` collection's `byEmail()` index to // get `Customer` collection documents by `email` field value. // In the `Customer` collection, `email` field values are unique // so return the `first()` (and only) document. let customer = Customer.byEmail("alice.appleseed@example.com").first() // Uses the `Order` collection's `byCustomer()` index to // get `Order` collection documents for the previous customer. Order.byCustomer(customer) // `Order` documents include a `items` field that contains a Set // of `OrderItem` documents. Each `OrderItem` document includes a // `product` field. This `flatMap()` call extracts the `id` and // `name` of each product, and flattens the resulting Set. .flatMap(.items.map(.product) { id, name } ) // Deduplicates the Set of product `id` and `name` values so that // it only returns unique elements. .distinct() ``` ``` { data: [ { id: "111", name: "cups" }, { id: "222", name: "donkey pinata" }, { id: "333", name: "pizza" } ] } ``` # `set.drop()` | Learn: Sets | | --- | --- | --- | Drop the first _N_ elements of a [Set](../../../fql/types/#set). | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig drop(amount: Number) => Set ``` ## [](#description)Description Drops a provided number of elements from a Set, beginning at element\[0\]. This lets you "skip" the elements. The calling Set isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Number of elements to drop. If this value is greater than the Set length, an empty Set is returned. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | A Set with the elements dropped. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3, 4, 5].toSet() set.drop(2) ``` ``` { data: [ 3, 4, 5 ] } ``` # `set.eventsOn()` | Learn: Sets | | --- | --- | --- | Create an [event source](../../../../learn/cdc/) that tracks changes to specified document fields in a [supported Set](../../../../learn/cdc/#sets). ## [](#signature)Signature ```fql-sig eventsOn(fields: ...A => Any) => EventSource ``` ## [](#description)Description Creates an [event source token](../../../../learn/cdc/) that tracks changes to specified document fields in a [Set](../../../fql/types/#set). The token has the [EventSource](../../../fql/types/#event-source) type: ``` "g9WD1YPG..." ``` You can only call `eventsOn()` on a [supported Set](../../../../learn/cdc/#sets). The exact behavior of the method depends on this source. The calling Set isn’t changed. [Sets](../../../fql/types/#set) for event sources support a limited number of [transformations and filters](../../../../learn/cdc/#transformations-filters). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | fields | Any | true | Comma-separated list of document field accessors (using dot notation). The event source tracks changes to the values of these document field. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | EventSource | A string-encoded token that represents the event source. Use the token to consume events as an Event Feed or Event Stream. | ## [](#examples)Examples ### [](#collection-event-sources)Collection event sources You can use `eventsOn()` to only track changes to specific fields for documents in a collection. ```fql Product.all().eventsOn(.description) ``` The query returns an event source. ```json "g9WD1YPG..." ``` ### [](#index-event-sources)Index event sources Event sources for indexes only send events for changes to the index’s `terms` or `values` fields. For example, the following `Product` collection’s `byName()` index has: * A `terms` field of `name` * `values` fields of `name` and `price` ```fsl collection Product { *: Any index byName { terms [.name] values [desc(.stock)] } ... } ``` When called on an index, `eventsOn()` only accepts the index’s `terms` or `values` fields as arguments. For example, in the following query, `eventsOn()` only accepts `.name` and `.stock` as arguments. ```fql Product.byName("limes").eventsOn(.name, .stock) ``` ### [](#document-event-sources)Document event sources You can use `eventsOn()` to track changes to a [Set](../../../fql/types/#set) containing a single document. The following query only tracks changes to the `name` or `price` field of a single document. ```fql let product = Product.byId("111")! Set.single(product).eventsOn(.name, .price) ``` ## [](#see-also)See also * [`set.eventSource()`](../eventsource/) * [Event Feeds and Event Streams](../../../../learn/cdc/) # `set.eventSource()` | Learn: Sets | | --- | --- | --- | Create an [event source](../../../../learn/cdc/) that tracks changes to documents in a [supported Set](../../../../learn/cdc/#sets). ## [](#signature)Signature ```fql-sig eventSource() => EventSource ``` ## [](#description)Description Creates an [event source token](../../../../learn/cdc/) that tracks changes to documents in a [supported Set](../../../../learn/cdc/#sets). The token has the [EventSource](../../../fql/types/#event-source) type: ``` "g9WD1YPG..." ``` You can only call `eventSource()` on a [supported Set](../../../../learn/cdc/#sets). The exact behavior of the method depends on this source. The calling [Set](../../../fql/types/#set) isn’t changed. Source [Set](../../../fql/types/#set)s for event sources support a limited number of [transformations and filters](../../../../learn/cdc/#transformations-filters). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | EventSource | A string-encoded token that represents the event source. Use the token to consume events as an Event Feed or Event Stream. | ## [](#examples)Examples ### [](#collection-event-sources)Collection event sources Calling `eventSource()` directly on [`collection.all()`](../../collection/instance-all/) tracks any change to any document in the collection. ```fql Product.all().eventSource() ``` The query returns an event source: ``` "g9WD1YPG..." ``` ### [](#index-event-sources)Index event sources Event sources for indexes only send events for changes to the index’s `terms` or `values` fields. For example, the following `Product` collection’s `byName()` index has: * A `terms` field of `name` * `values` fields of `name` and `price` ```fsl collection Product { *: Any index byName { terms [.name] values [.name, .price] } ... } ``` The following query only tracks changes to the `name` or `price` fields for `Product` documents with a `name` of `limes`. ```fql Product.byName("limes").eventSource() ``` ### [](#document-event-sources)Document event sources You can use event sources to track changes to a [Set](../../../fql/types/#set) containing a single document. These event sources are only sent events when the document changes. ```fql // Uses the `Product` collection's `byName()` index and // the `first()` method to get a single document. let product = Product.byName("cups").first() Set.single(product).eventSource() ``` ## [](#see-also)See also * [`set.eventsOn()`](../eventson/) * [Event Feeds and Event Streams](../../../../learn/cdc/) # `set.every()` | Learn: Sets | | --- | --- | --- | Test if every element of a Set matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig every(predicate: (A => Boolean | Null)) => Boolean ``` ## [](#description)Description Tests if every element of the calling Set matches a provided [predicate function](../../../fql/functions/#predicates). ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `every()` to get all products with // more than 20 items in stock. Product.all().every(.stock > 20) ``` Emits the following hint: ``` performance_hint: full_set_read - Using every() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:20 | 3 | Product.all().every(.stock > 20) | ^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` Product.all().take(20).every(.stock > 20) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts a Set element as its only argument. Supports shorthand-syntax for objects and documents.Returns Boolean or Null.The method returns true if the predicate is true for every element in the Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the predicate evaluates to true for every element of the Set. Otherwise, false. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, -2, 3].toSet() set.every(v => v > 0) ``` ``` false ``` # `set.first()` | Learn: Sets | | --- | --- | --- | Get the first element of a [Set](../../../fql/types/#set). ## [](#signature)Signature ```fql-sig first() => A | Null ``` ## [](#description)Description Gets the first element of the calling [Set](../../../fql/types/#set). ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | First element of the calling Set. | | Null | Returned if the Set is empty. | ## [](#examples)Examples Get the first Customers document: ```fql Customer.all().first() ``` ``` { id: "111", coll: Customer, ts: Time("2099-07-31T12:42:19Z"), cart: Order("412483941752112205"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } } ``` # `set.firstWhere()` | Learn: Sets | | --- | --- | --- | Get the first element of a [Set](../../../fql/types/#set) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig firstWhere(predicate: (A => Boolean | Null)) => A | Null ``` ## [](#description)Description Gets the first element of the calling Set that matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts a Set element as its only argument. Supports shorthand-syntax for objects and documents.Returns Boolean or Null.The method returns the first Set element for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | First element of the Set that matches the predicate. | | Null | Returned if no Set element matches the predicate or the Set is empty. | ## [](#examples)Examples Get the first Customers document where the `state` property is `DC`: ```fql Customer.all().firstWhere(.address.state == 'DC') ``` ``` { id: "111", coll: Customer, ts: Time("2099-07-31T12:42:19Z"), cart: Order("412571379960906240"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } } ``` # `set.flatMap()` | Learn: Sets | | --- | --- | --- | Apply a provided [function](../../../fql/functions/) to each [Set](../../../fql/types/#set) element and flatten the resulting Set by one level. | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig flatMap(mapper: (A => Set)) => Set ``` ## [](#description)Description Creates a [Set](../../../fql/types/#set) by invoking a provided mapper [function](../../../fql/functions/) on each element of the calling Set and flattening the resulting Set one level. The [Set](../../../fql/types/#set) elements are passed as a parameter to the mapper function, sequentially. The calling Set isn’t changed. ### [](#iterator-methods)Iterator methods FQL provides several methods for iterating over a Set. [`set.forEach()`](../foreach/), [`set.map()`](../map/), [`set.flatMap()`](./) are similar but used for different purposes: | Method | Primary use | Notes | | --- | --- | --- | --- | --- | | set.forEach() | Perform in-place writes on Set elements. | Doesn’t return a value. | | set.map() | Returns a new Set. | Can’t perform writes. | | set.flatMap() | Similar to set.map(), but flattens the resulting Set by one level. | Can’t perform writes. | For examples, see: * [`set.forEach()` vs. `set.map()`](../map/#foreach-vs-map) * [`set.map()` vs. `set.flatMap()`](#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | mapper | Function | true | Function to invoke on each element of the calling Set. Each element is passed to the mapper function as an argument. The function must return a Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing the result of invoking the mapper function on each element of the calling Set. The resulting Set is flattened by one level. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Returns a Set let topCustomer = Customer.byEmail("alice.appleseed@example.com") // Returns a flattened Set topCustomer.flatMap((customer) => Order.byCustomer(customer)) ``` ``` { data: [ { id: "410674590662000717", coll: Order, ts: Time("2099-10-02T22:37:39.583Z"), items: "hdW...", total: 5392, status: "cart", customer: Customer("111"), createdAt: Time("2099-10-02T22:37:39.434810Z"), payment: {} } ] } ``` ### [](#map-vs-flatmap)`set.map()` vs. `set.flatMap()` [`set.flatMap()`](./) is similar to [`set.map()`](../map/), except [`set.flatMap()`](./) also flattens the resulting Set by one level. In the following example, [`set.map()`](../map/) returns a two-dimensional Set: ```fql // Get a Set of all `Category` collection documents. let categories = Category.all() // Use `map()` to get a Set of `Product` documents // for each category. categories.map(category => { Product.byCategory(category) }) ``` ``` // Two-dimensional Set. { data: [ { data: [ { id: "111", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, ... ] }, { data: [ { id: "333", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") } ] }, { data: [ { id: "444", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") }, ... ] } ] } ``` To flatten the result to a one-dimensional array, use [`set.flatMap()`](./) instead: ```fql // Get a Set of all `Category` collection documents. let categories = Category.all() // Use `flatMap()` to get a Set of `Product` documents // for each category. Then flatten the resulting Set. categories.flatMap(category => { Product.byCategory(category) }) ``` ``` // One-dimensional Set. { data: [ { id: "111", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, ... { id: "333", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") }, ... { id: "444", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] } ``` # `set.fold()` | Learn: Sets | | --- | --- | --- | Reduce the [Set](../../../fql/types/#set) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from left to right. Uses a provided seed as the initial value. ## [](#signature)Signature ```fql-sig fold(seed: B, reducer: (B, A) => B) => B ``` ## [](#description)Description Iterates through each element in a Set to perform a rolling operation. For example, you can use `fold()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `fold()` calls a reducer callback function on every element of the Set from left to right. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. For the first iteration, a seed value serves as the initial accumulator. * The current element’s value from the Set. The method returns the result of the last iteration. The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `fold()` to sum stock counts let stockCounts = Product.all().map(doc => doc.stock) stockCounts.fold(0, (a, b) => a + b) ``` Emits the following hint: ``` performance_hint: full_set_read - Using fold() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:17 | 3 | stockCounts.fold(0, (a, b) => a + b) | ^^^^^^^^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let stockCounts = Product.all().take(20).map(doc => doc.stock) stockCounts.fold(0, (a, b) => a + b) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce a Set to a single value. These methods include: * [`set.fold()`](./) * [`set.foldRight()`](../foldright/) * [`set.reduce()`](../reduce/) * [`set.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`set.fold()`](./) and [`set.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`set.reduce()`](../reduce/) and [`set.reduceRight()`](../reduceright/) use the Set’s first element as the initial _accumulator_. * [`set.fold()`](./) and [`set.reduce()`](../reduce/) iterate through the Set’s elements from left to right. [`set.foldRight()`](../foldright/) and [`set.reduceRight()`](../reduceright/) iterate through the Set’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Generic | true | Initial accumulator value provided to the reducer function. | | reducer | Function | true | Anonymous FQL function to call on each element of the Set. | ### [](#reducer-function-arguments)Reducer function arguments: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. For an empty Set, the seed is returned. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.fold(100, (value, elem) => value + elem) ``` ``` 106 ``` ### [](#group-by-operation)Group by operation [FQL](../../../../learn/query/) doesn’t provide a built-in `GROUP BY` operation. However, you use `fold()` in an [anonymous FQL function](../../../fql/functions/) or a [user-defined function (UDF)](../../../../learn/schema/user-defined-functions/) to achieve the same result. As an FQL function: ```fql // Defines an anonymous `groupBy()` function. // `groupBy()` two arguments: // * `set`: Set or Array containing data to group // * `key_fn`: Grouping key for each element let groupBy = (set, key_fn) => { // Calls the `fold()` function on the `set` // Set or Array. set.fold( // Start with an empty object. {}, (acc, val) => { // For each value, get a key using the `key_fn` arg. let key = key_fn(val) let existing_group = acc[key] ?? [] // Append the current value to the Set or // Array for that key. let new_group = existing_group.append(val) let new_entry = Object.fromEntries([ [key, new_group] ]) // Return an object with grouped results. Object.assign(acc, new_entry) } ) } // Call the `groupBy()` function. // Groups `Product` documents by category name. groupBy(Product.all(), .category!.name) ``` You can also define a `groupBy()` UDF. This lets you reuse the function across multiple queries. You create and manage a UDF as an FSL [function schema](../../../fsl/function/): ```fsl // Defines the `groupBy()` UDF. // `groupBy()` two arguments: // * `set`: Set or Array containing data to group // * `key_fn`: Grouping key for each element function groupBy (set, key_fn) { // Calls the `fold()` function on the `set` // Set or Array. set.fold( // Start with an empty object. {}, (acc, val) => { // For each value, get a key using the `key_fn` arg. let key: String = key_fn(val) let existing_group = acc[key] ?? [] // Append the current value to the Set or // Array for that key. let new_group = existing_group.append(val) let new_entry = Object.fromEntries([ [key, new_group] ]) // Return an object with grouped results. Object.assign(acc, new_entry) } ) } ``` You can create and manage schema using any of the following: * The [Fauna CLI](../../../../learn/schema/manage-schema/#staged) * The [Fauna Dashboard](https://dashboard.fauna.com/) * The Fauna Core HTTP API’s [Schema endpoints](../../../http/reference/core-api/#tag/Schema) * [FQL schema methods](../../../../learn/schema/manage-schema/#fql) For additional examples using the `groupBy()` UDF, see [Group By: Aggregate data in Fauna](../../../../learn/query/patterns/group-by/). # `set.foldRight()` | Learn: Sets | | --- | --- | --- | Reduce a [Set](../../../fql/types/#set) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from right to left. Uses a provided seed as the initial value. ## [](#signature)Signature ```fql-sig foldRight(seed: B, reducer: (B, A) => B) => B ``` ## [](#description)Description Iterates through each element in a Set to perform a rolling operation. For example, you can use `foldRight()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `foldRight()` calls a reducer callback function on every element of the Set from right to left. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. For the first iteration, a seed value serves as the initial accumulator. * The current element’s value from the Set. The method returns the result of the last iteration. The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `foldRight()` to sum stock counts let stockCounts = Product.all().map(doc => doc.stock) stockCounts.foldRight(0, (a, b) => a + b) ``` Emits the following hint: ``` performance_hint: full_set_read - Using foldRight() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:22 | 3 | stockCounts.foldRight(0, (a, b) => a + b) | ^^^^^^^^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let stockCounts = Product.all().take(20).map(doc => doc.stock) stockCounts.foldRight(0, (a, b) => a + b) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce a Set to a single value. These methods include: * [`set.fold()`](../fold/) * [`set.foldRight()`](./) * [`set.reduce()`](../reduce/) * [`set.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`set.fold()`](../fold/) and [`set.foldRight()`](./) accept an initial _seed_ value and use it as the initial _accumulator_. [`set.reduce()`](../reduce/) and [`set.reduceRight()`](../reduceright/) use the Set’s first element as the initial _accumulator_. * [`set.fold()`](../fold/) and [`set.reduce()`](../reduce/) iterate through the Set’s elements from left to right. [`set.foldRight()`](./) and [`set.reduceRight()`](../reduceright/) iterate through the Set’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | seed | Generic | true | Initial accumulator value provided to the reducer function. | | reducer | Function | true | Anonymous FQL function to call on each element of the Set. | ### [](#reducer-function-arguments)Reducer function arguments: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. For an empty Set, the seed is returned. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.foldRight(100, (value, elem) => value + elem) ``` ``` 106 ``` # `set.forEach()` | Learn: Sets | | --- | --- | --- | Run a provided [function](../../../fql/functions/) on each element of a [Set](../../../fql/types/#set). Can perform writes. ## [](#signature)Signature ```fql-sig forEach(callback: (A => Any)) => Null ``` ## [](#description)Description Iterates over all elements in the [Set](../../../fql/types/#set) and executes a provided callback function on each element. It is used for mutations or writing documents based on each [Set](../../../fql/types/#set) element. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `forEach()` to increment each product's // stock count by 1. Product.all().forEach( doc => doc.stock + 1 ) ``` Emits the following hint: ``` performance_hint: full_set_read - Using forEach() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:22 | 3 | Product.all().forEach( | ______________________^ 4 | | doc => doc.stock + 1 5 | | ) | |_^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` Product.all().take(20).forEach( doc => doc.stock + 1 ) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-use-on-large-sets)Avoid use on large sets This method scans the full [Set](../../../fql/types/#set), which can cause many reads and might time out for large [Set](../../../fql/types/#set)s. ### [](#iterator-methods)Iterator methods FQL provides several methods for iterating over a Set. [`set.forEach()`](./), [`set.map()`](../map/), [`set.flatMap()`](../flatmap/) are similar but used for different purposes: | Method | Primary use | Notes | | --- | --- | --- | --- | --- | | set.forEach() | Perform in-place writes on Set elements. | Doesn’t return a value. | | set.map() | Returns a new Set. | Can’t perform writes. | | set.flatMap() | Similar to set.map(), but flattens the resulting Set by one level. | Can’t perform writes. | For examples, see: * [`set.forEach()` vs. `set.map()`](#foreach-vs-map) * [`set.map()` vs. `set.flatMap()`](../map/#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | callback | Function | true | Anonymous FQL function to call on each element of the Set. Each call returns Null. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Null | This method always returns Null. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Get a Set of `Customer` collection documents with an // `address` in the `state` of `DC`. let customers = Customer.where(.address?.state == "DC") // Use `forEach()` to update each document in the previous Set. customers.forEach(doc => doc.update({ address: { street: doc?.address?.street, city: doc?.address?.city, state: "District of Columbia", postalCode: doc?.address?.postalCode, country: doc?.address?.country, } })) // `forEach()` returns `null`. ``` ``` null ``` Although it returns `null`, [`set.forEach()`](./) still performed the requested operations. To verify: ```fql // Get all `Customer` collection documents Customer.all() ``` ``` // The results contain `Customer` documents updated by // the previous `forEach()` call. { data: [ { id: "111", coll: Customer, ts: Time("2099-10-02T21:50:14.555Z"), cart: Order("410671593745809485"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "District of Columbia", // `state` has been updated. postalCode: "20220", country: "US" } }, ... ] } ``` ### [](#foreach-vs-map)`set.forEach()` vs. `set.map()` You can use both [`set.forEach()`](./) and [`set.map()`](../map/) to iterate through a Set. Use [`set.forEach()`](./) to perform in-place writes on the calling Set: ```fql // Gets the frozen category. let frozen = Category.byName("frozen").first() // Uses `forEach()` to delete each product in // the frozen category. Product.byCategory(frozen).forEach(product => { product.delete() }) ``` ``` null ``` Although it returns `null`, [`set.forEach()`](./) still performs the requested operations. Unlike [`set.forEach()`](./), [`set.map()`](../map/) can’t perform writes: ```fql // Gets the produce category. let produce = Category.byName("produce").first() // Attempts to use `map()` to delete each product in // the produce category. Product.byCategory(produce).map(product => { product.delete() }) ``` ``` invalid_effect: `delete` performs a write, which is not allowed in set functions. error: `delete` performs a write, which is not allowed in set functions. at *query*:7:17 | 7 | product.delete() | ^^ | ``` Instead, you can use [`set.map()`](../map/) to output a new Set containing extracted or transformed values: ```fql // Gets the produce category. let produce = Category.byName("produce").first() // Uses `map()` to outputs a new Set containing products in // the produce category. The new Set transforms each product's // name. Product.byCategory(produce).map(product => { let product: Any = product { name: product.category.name + ": " + product.name, } }) ``` ``` { data: [ { name: "produce: avocados" }, { name: "produce: single lime" }, { name: "produce: organic limes" }, { name: "produce: limes" }, { name: "produce: cilantro" } ] } ``` # `set.includes()` | Learn: Sets | | --- | --- | --- | Test if the [Set](../../../fql/types/#set) includes a provided element. ## [](#signature)Signature ```fql-sig includes(element: A) => Boolean ``` ## [](#description)Description Tests if the [Set](../../../fql/types/#set) includes a provided element. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `includes()` to check whether the `Product` // collection includes a specific document. let limes: Any = Product.byId("777") Product.all().includes(limes) ``` Emits the following hint: ``` performance_hint: full_set_read - Using includes() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:4:23 | 4 | Product.all().includes(limes) | ^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let limes: Any = Product.byId("777") Product.all().take(20).includes(limes) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-filtering-using-includes)Avoid filtering using `includes()` In most cases, you should avoid using [`set.includes()`](./) to intersect results, including results from [covered index calls](../../../../learn/data-model/indexes/#covered-queries). [`set.includes()`](./) is a linear operation. The [compute costs](../../../../manage/plans-billing/billing/#tco) consumed by repeatedly iterating through results will typically exceed the [read costs](../../../../manage/plans-billing/billing/#tro) of directly reading documents. For example, the following query is inefficient and will likely incur high compute costs: ```fql // Each variable is a covered index call let limes = Product.byName("limes") let produce = Product.byCategory(Category.byName("produce").first()!) let under5 = Product.sortedByPriceLowToHigh({ to: 500 }) // Uses `includes()` to intersect the results from // covered index calls limes.where(doc => produce.includes(doc)) .where(doc => under5.includes(doc)) ``` Instead, use a [covered index call](../../../../learn/data-model/indexes/#covered-queries) and [`set.where()`](../where/) to filter the results as outlined in [Filter using `where()`](../../../../learn/query/patterns/sets/#where). For example, you can rewrite the previous query as: ```fql // Start with a covered index call. Product.byName("limes") // Layer on filters using `where()` .where(doc => doc.category == Category.byName("produce").first()!) .where(doc => doc.price < 500 ) ``` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | element | Generic | true | Element to check the Set for. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Set contains the provided element. Otherwise, false. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.includes(2) ``` ``` true ``` # `set.isEmpty()` | Learn: Sets | | --- | --- | --- | Test if a [Set](../../../fql/types/#set) is empty. ## [](#signature)Signature ```fql-sig isEmpty() => Boolean ``` ## [](#description)Description Tests if the calling [Set](../../../fql/types/#set) is empty and contains no elements. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Set is empty. Otherwise, false. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. // In thise case, it creates an empty Set. let set = [].toSet() set.isEmpty() ``` ``` true ``` # `set.last()` | Learn: Sets | | --- | --- | --- | Get the last element of a [Set](../../../fql/types/#set). ## [](#signature)Signature ```fql-sig last() => A | Null ``` ## [](#description)Description Returns the last element of the [Set](../../../fql/types/#set). The method reverses the Set and gets the first item. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Last element of the Set. | | Null | Returned if the Set is empty. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2].toSet() set.last() ``` ``` 2 ``` ## [](#see-also)See also [`set.first()`](../first/) [`set.reverse()`](../reverse/) # `set.lastWhere()` | Learn: Sets | | --- | --- | --- | Get the last element of a [Set](../../../fql/types/#set) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig lastWhere(predicate: (A => Boolean | Null)) => A | Null ``` ## [](#description)Description Gets the last element of the calling Set that matches a provided [predicate function](../../../fql/functions/#predicates). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | true | Anonymous predicate function that:Accepts a Set element as its only argument. Supports shorthand-syntax for objects and documents.Returns a Boolean value.The method returns the last Set element for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Last element of the Set that matches the predicate. | | Null | Returned if no Set element matches the predicate or the Set is empty. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3, 4].toSet() set.lastWhere(v => v > 2) ``` ``` 4 ``` # `set.map()` | Learn: Sets | | --- | --- | --- | Apply a provided [function](../../../fql/functions/) to each element of a [Set](../../../fql/types/#set). Can’t perform writes. | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig map(mapper: (A => B)) => Set ``` ## [](#description)Description Creates a [Set](../../../fql/types/#set) by applying a mapper function to each element in the calling [Set](../../../fql/types/#set). Writes are not permitted. The calling Set isn’t changed. If `map()` is the last value in a query, the first page of the new [Set](../../../fql/types/#set) is returned. ### [](#iterator-methods)Iterator methods FQL provides several methods for iterating over a Set. [`set.forEach()`](../foreach/), [`set.map()`](./), [`set.flatMap()`](../flatmap/) are similar but used for different purposes: | Method | Primary use | Notes | | --- | --- | --- | --- | --- | | set.forEach() | Perform in-place writes on Set elements. | Doesn’t return a value. | | set.map() | Returns a new Set. | Can’t perform writes. | | set.flatMap() | Similar to set.map(), but flattens the resulting Set by one level. | Can’t perform writes. | For examples, see: * [`set.forEach()` vs. `set.map()`](#foreach-vs-map) * [`set.map()` vs. `set.flatMap()`](#map-vs-flatmap) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | mapper | Function | true | Anonymous FQL function to call on each element of the calling Set. Each call returns a value that’s returned in the result Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing values returned by each mapper function call. | ## [](#examples)Examples ### [](#basic-example)Basic example For all Customer documents, combine the `address.city` and `address.state` properties into a single string: ```fql Customer.all().map( customer => { name: customer.name, city: "#{customer.address.city}, #{customer.address.state}" } ) ``` ``` { data: [ { name: "Alice Appleseed", city: "Washington, DC" }, { name: "Bob Brown", city: "Washington, DC" }, { name: "Carol Clark", city: "Washington, DC" } ] } ``` ### [](#project)Project Sets using `set.map()` You can use `set.map()` to project a Set, similar to using [Set projection](../../../fql/projection/#set). For example, the following projection query: ```fql Product.sortedByPriceLowToHigh() { name, description, price } ``` Is equivalent to the following `set.map()` query: ```fql Product.sortedByPriceLowToHigh().map(prod => { name: prod.name, description: prod.description, price: prod.price, }) ``` ### [](#foreach-vs-map)`set.forEach()` vs. `set.map()` You can use both [`set.forEach()`](../foreach/) and [`set.map()`](./) to iterate through a Set. Use [`set.forEach()`](../foreach/) to perform in-place writes on the calling Set: ```fql // Gets the frozen category. let frozen = Category.byName("frozen").first() // Uses `forEach()` to delete each product in // the frozen category. Product.byCategory(frozen).forEach(product => { product.delete() }) ``` ``` null ``` Although it returns `null`, [`set.forEach()`](../foreach/) still performs the requested operations. Unlike [`set.forEach()`](../foreach/), [`set.map()`](./) can’t perform writes: ```fql // Gets the produce category. let produce = Category.byName("produce").first() // Attempts to use `map()` to delete each product in // the produce category. Product.byCategory(produce).map(product => { product.delete() }) ``` ``` invalid_effect: `delete` performs a write, which is not allowed in set functions. error: `delete` performs a write, which is not allowed in set functions. at *query*:7:17 | 7 | product.delete() | ^^ | ``` Instead, you can use [`set.map()`](./) to output a new Set containing extracted or transformed values: ```fql // Gets the produce category. let produce = Category.byName("produce").first() // Uses `map()` to outputs a new Set containing products in // the produce category. The new Set transforms each product's // name. Product.byCategory(produce).map(product => { let product: Any = product { name: product.category.name + ": " + product.name, } }) ``` ``` { data: [ { name: "produce: avocados" }, { name: "produce: single lime" }, { name: "produce: organic limes" }, { name: "produce: limes" }, { name: "produce: cilantro" } ] } ``` ### [](#map-vs-flatmap)`set.map()` vs. `set.flatMap()` [`set.flatMap()`](../flatmap/) is similar to [`set.map()`](./), except [`set.flatMap()`](../flatmap/) also flattens the resulting Set by one level. In the following example, [`set.map()`](./) returns a two-dimensional Set: ```fql // Get a Set of all `Category` collection documents. let categories = Category.all() // Use `map()` to get a Set of `Product` documents // for each category. categories.map(category => { Product.byCategory(category) }) ``` ``` // Two-dimensional Set. { data: [ { data: [ { id: "111", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, ... ] }, { data: [ { id: "333", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") } ] }, { data: [ { id: "444", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") }, ... ] } ] } ``` To flatten the result to a one-dimensional array, use [`set.flatMap()`](../flatmap/) instead: ```fql // Get a Set of all `Category` collection documents. let categories = Category.all() // Use `flatMap()` to get a Set of `Product` documents // for each category. Then flatten the resulting Set. categories.flatMap(category => { Product.byCategory(category) }) ``` ``` // One-dimensional Set. { data: [ { id: "111", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, ... { id: "333", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") }, ... { id: "444", coll: Product, ts: Time("2099-10-02T22:37:39.583Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ] } ``` # `set.nonEmpty()` | Learn: Sets | | --- | --- | --- | Test if a [Set](../../../fql/types/#set) is not empty. ## [](#signature)Signature ```fql-sig nonEmpty() => Boolean ``` ## [](#description)Description Tests if the calling [Set](../../../fql/types/#set) is not empty. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Set is not empty. Otherwise, false. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. // In thise case, it creates an empty Set. let set = [].toSet() set.nonEmpty() ``` ``` false ``` # `set.order()` | Learn: Sets | | --- | --- | --- | Sort a [Set](../../../fql/types/#set)'s elements. ## [](#signature)Signature ```fql-sig order(ordering: ...(A => Any) & {}) => Set ``` ## [](#description)Description Creates a sorted [Set](../../../fql/types/#set) by applying one or more sorting criteria to the calling [Set](../../../fql/types/#set). You define each sorting criterion by wrapping `asc()` (ascending) or `desc()` (descending) around a [field accessor](../../../fql/dot-notation/) or a read-only [anonymous function](../../../fql/functions/). The first criterion has the highest sorting priority, with priority decreasing for each subsequent criterion. If `order()` is the last value in an expression, the first page of the new [Set](../../../fql/types/#set) is returned. See [Pagination](../../../../learn/query/pagination/). The calling Set remains unchanged. ### [](#using-order-with-indexes)Using `order()` with indexes Calling `order()` on an [index](../../../../learn/data-model/indexes/), including the built-in [`all()`](../../collection/instance-all/) index, requires a read of each document and [historical document snapshot](../../../../learn/data-model/indexes/#history) covered by the index. For example: ```fql // Calls `order` on the built-in `all()` index. // The query requires a read of each current `Product` // collection document and any historical document snapshots. Product.all().order(.price) { price } ``` Performance hint: `full_set_read` Queries that call `order()` on an index emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example: ``` performance_hint: full_set_read - Using order() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:4:20 | 4 | Product.all().order(.price) { price } | ^^^^^^^^ | ``` If you frequently run such queries, consider adding the fields used for ordering to an index definition’s [`values`](../../../../learn/data-model/indexes/#sort-documents). For example: ```fsl collection Product { ... // Adds `price` as an index value. index sortedByPriceLowToHigh { values [.price] } ... } ``` When you call the index, returned documents are sorted by the index’s values. Using index values can significantly reduce the number of [read ops](../../../../manage/plans-billing/plan-details/#tro) required to sort results. ```fql // Get `Product` documents by // Ascending `name`, then ... // Ascending `id` (default) // This is equivalent to the previous query. Product.sortedByPriceLowToHigh() { price } ``` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | ordering | Generic | | One or more sorting criteria, separated by commas.Each criterion is a field accessor or read-only anonymous function, optionally wrapped in asc() (ascending) or desc() (descending) to indicate sort order.If neither asc() or desc() is provided, asc() is used by default.The anonymous function is passed each Set element as an argument. For document Sets, each Set element is a Document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | New Set with elements in requested order. | ## [](#examples)Examples ### [](#sort-fields-in-ascending-order)Sort fields in ascending order ```fql // Sort `Customer` collection documents by `name` // in ascending order (default). Customer.all().order(.name) { name, email } ``` ``` { data: [ { name: "Alice Appleseed", email: "alice.appleseed@example.com" }, { name: "Bob Brown", email: "bob.brown@example.com" }, { name: "Carol Clark", email: "carol.clark@example.com" } ] } ``` ### [](#sort-fields-in-descending-order)Sort fields in descending order ```fql // Sort `Customer` collection documents by `name` // in descending order. Customer.all().order(desc(.name)) { name, email } ``` ``` { data: [ { name: "Carol Clark", email: "carol.clark@example.com" }, { name: "Bob Brown", email: "bob.brown@example.com" }, { name: "Alice Appleseed", email: "alice.appleseed@example.com" } ] } ``` ### [](#sort-fields-using-multiple-arguments)Sort fields using multiple arguments ```fql // Sort `Customer` collection documents by: // - Ascending `name` then... // - Ascending `address.street`. Customer.all().order(.name, .address.street) { name, address { street }, email } ``` ``` { data: [ { name: "Alice Appleseed", address: { street: "87856 Mendota Court" }, email: "alice.appleseed@example.com" }, { name: "Bob Brown", address: { street: "72 Waxwing Terrace" }, email: "bob.brown@example.com" }, { name: "Carol Clark", address: { street: "5 Troy Trail" }, email: "carol.clark@example.com" } ] } ``` ### [](#sort-fields-using-an-anonymous-function)Sort fields using an anonymous function In addition to using field accessors, you can use a read-only anonymous function as a sorting criterion: ```fql // Sort Customer collection documents by prioritizing // those where the email contains "example.com". Customer.all().order(asc( (doc) => if (doc.email.includes("example.com")) { // Prioritize these documents. // Lower numbers (`0`)` appear first when sorted // in ascending order. 0 // After that, sort the remaining documents by the // length of their email. } else { doc.email.length } )) { name, email } ``` ``` { data: [ { name: "Alice Appleseed", email: "alice.appleseed@example.com" }, { name: "Bob Brown", email: "bob.brown@example.com" }, { name: "Carol Clark", email: "carol.clark@example.com" }, { name: "Jane Doe", email: "12-fake@fauna.com" }, { name: "John Doe", email: "123-fake@fauna.com" } ] } ``` # `set.pageSize()` | Learn: Pagination | | --- | --- | --- | Set the maximum elements per page in [paginated results](../../../../learn/query/pagination/). | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig pageSize(size: Number) => Set ``` ## [](#description)Description Sets the maximum elements per page in [paginated results](../../../../learn/query/pagination/). If a subsequent page is available, the result includes an `after` cursor. To iterate through paginated results, pass the `after` cursor to [`Set.paginate()`](../static-paginate/). ### [](#method-chaining)Method chaining `pageSize()` should typically be the last method call in an FQL expression. `pageSize()` only affects the rendering of a Set, not subsequent operations. Methods chained to `pageSize()` access the entire calling Set, not a page of results. ### [](#after-cursor)`after` cursor See [Cursor state and expiration](../../../../learn/query/pagination/#cursor-state-expiration). ### [](#differences-with-paginate)Differences with `paginate()` The following table outlines differences between [`set.pageSize()`](./) and [`set.paginate()`](../paginate/): | Difference | set.pageSize() | set.paginate() | | --- | --- | --- | --- | --- | | Use case | Use in most cases. | Use when needing to access an 'after' cursor or paginated results within an FQL query. | | Return type | Returns a set. | Returns an object. | | Loading strategy | Lazy loading. Only fetches results as needed. | Eager loading. Fetches results instantly, even if the results aren’t returned or used. | | Client driver methods | Compatible with driver pagination methods. | Incompatible with driver pagination methods. | | Projection | Supports projections. | Doesn’t support projections. | | Set instance methods | Supports set instance methods. | Doesn’t support set instance methods. | ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | size | Int | true | Number of Set values to include in the returned page. Must be in the range 1 to 16000 (inclusive). | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set that includes the following field: FieldTypeDescriptionafterString | NullCursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | Field | Type | Description | after | String | Null | Cursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | | Field | Type | Description | | after | String | Null | Cursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql // Calls `pageSize()` with a size of `2`. Product.all().pageSize(2) ``` ``` { // The returned Set contains two elements or fewer. data: [ { id: "111", coll: Product, ts: Time("2099-07-31T12:58:51.680Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, { id: "222", coll: Product, ts: Time("2099-07-31T12:58:51.680Z"), name: "donkey pinata", description: "Original Classic Donkey Pinata", price: 2499, stock: 50, category: Category("123") } ], after: "hdW..." } ``` ### [](#paginate-in-reverse)Paginate in reverse Paginated queries don’t include a `before` cursor. Instead, you can use a range search and document IDs or other unique field values to paginate in reverse. For example: 1. Run an initial paginated query: ```fql Product.all().pageSize(2) ``` ``` { data: [ { id: "111", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, { id: "222", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "donkey pinata", description: "Original Classic Donkey Pinata", price: 2499, stock: 50, category: Category("123") } ], after: "hdW..." } ``` 2. Page forward until you find the document you want to start reversing from: ```fql Set.paginate("hdW...") ``` Copy the ID of the document: ``` { data: [ { id: "333", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") }, { // Begin reverse pagination from this doc ID. id: "444", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") } ], after: "hdW..." } ``` 3. To reverse paginate, run the original query with: * A range search with a `to` argument containing the previous document ID. * [`set.reverse()`](../reverse/): Append this to the query. * [`set.pageSize()`](./): If used, place it after [`set.reverse()`](../reverse/). ```fql // "444" is the ID of the document to reverse from. Product.all({ to: "444" }).reverse().pageSize(2) ``` ``` { data: [ { // The results of the previous query are reversed. id: "444", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "avocados", description: "Conventional Hass, 4ct bag", price: 399, stock: 1000, category: Category("789") }, { id: "333", coll: Product, ts: Time("2099-08-16T14:00:59.075Z"), name: "pizza", description: "Frozen Cheese", price: 499, stock: 100, category: Category("456") } ], after: "hdW..." } ``` To get historical snapshots of documents at the time of the original query, use an [`at` expression](../../../fql/statements/#at): ```fql // Time of the original query. let originalQueryTime = Time.fromString("2099-08-16T14:30:00.000Z") at (originalQueryTime) { // "444" is the ID of the document to reverse from. Product.all({ to: "444" }).reverse().pageSize(2) } ``` 4. Repeat the previous step to continue paginating in reverse: ```fql Product.all({ to: "333" }).reverse().pageSize(2) ``` ## [](#see-also)See also * [`set.paginate()`](../paginate/) * [`Set.paginate()`](../static-paginate/) # `set.paginate()` | Learn: Pagination | | --- | --- | --- | Convert a [Set](../../../fql/types/#set) to an [Object](../../../fql/types/#object) with [pagination](../../../../learn/query/pagination/). ## [](#signature)Signature ```fql-sig paginate() => { data: Array, after: String | Null } paginate(size: Number) => { data: Array, after: String | Null } ``` ## [](#description)Description Returns the calling [Set](../../../fql/types/#set) as an [Object](../../../fql/types/#object). If the Set is paginated and a subsequent page is available, the result includes an `after` cursor. To iterate through paginated results, pass the `after` cursor to [`Set.paginate()`](../static-paginate/). `paginate()` accepts an optional size argument to control page size. In most cases, you should not use `paginate()` in place of `pageSize()`. See [Differences with `pageSize()`](#differences-with-pagesize). ### [](#differences-with-pagesize)Differences with `pageSize()` The following table outlines differences between [`set.pageSize()`](../pagesize/) and [`set.paginate()`](./): | Difference | set.pageSize() | set.paginate() | | --- | --- | --- | --- | --- | | Use case | Use in most cases. | Use when needing to access an 'after' cursor or paginated results within an FQL query. | | Return type | Returns a set. | Returns an object. | | Loading strategy | Lazy loading. Only fetches results as needed. | Eager loading. Fetches results instantly, even if the results aren’t returned or used. | | Client driver methods | Compatible with driver pagination methods. | Incompatible with driver pagination methods. | | Projection | Supports projections. | Doesn’t support projections. | | Set instance methods | Supports set instance methods. | Doesn’t support set instance methods. | ### [](#after-cursor)`after` cursor See [Cursor state and expiration](../../../../learn/query/pagination/#cursor-state-expiration). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | size | Int | | Maximum number of Set elements to include in the returned page. The size parameter must be in the range 1 to 16000 (inclusive). | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Object | Object that includes the following fields: FieldTypeDescriptiondataArrayArray representing a page of elements from the calling Set. The number of elements is limited by the size parameter.afterString | NullCursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | Field | Type | Description | data | Array | Array representing a page of elements from the calling Set. The number of elements is limited by the size parameter. | after | String | Null | Cursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | | Field | Type | Description | | data | Array | Array representing a page of elements from the calling Set. The number of elements is limited by the size parameter. | | after | String | Null | Cursor for the next page of results. The cursor is valid for history_days plus 15 minutes.If no additional pages exist, after is Null. | ## [](#examples)Examples Queries are subject to [size limits](../../../requirements-limits/#glimits). If you’re performing bulk writes on a large dataset, you can use [`set.pageSize()`](../pagesize/) and `paginate()` to perform the write over several queries instead of one. The first query uses `paginate()` to fetch the results and generate an initial `after` cursor: ```fql // Get a Set of `Customer` collection documents with an // `address` in the `state` of `DC`. Use `pageSize()` // and`paginate()` to paginate results and // limit each page to two documents. let page = Customer.where( .address?.state == "DC" ) .pageSize(2).paginate() // `paginate()` returns an object. The object's `data` property // contains an Array of `Customer` documents. let data = page.data // Use `forEach()` to update each `Customer` document in the // `data` Array. data.forEach(doc => doc.update({ address: { state: "District of Columbia" } })) // Project the `after` cursor returned by `paginate()`. // You can use the cursor to iterate through the remaining // pages. page { after } ``` ``` { after: "hdWDxoq..." } ``` Subsequent queries use the cursor and [`Set.paginate()`](../static-paginate/) to iterate through the remaining pages: ```fql // Uses `Set.paginate()` to iterate through pages. let page = Set.paginate("hdWDxoq...") let data = page.data data.forEach(doc => doc.update({ address: { state: "District of Columbia" } })) page { after } ``` ## [](#see-also)See also * [`set.pageSize()`](../pagesize/) * [`Set.paginate()`](../static-paginate/) # `set.reduce()` | Learn: Sets | | --- | --- | --- | Reduce a [Set](../../../fql/types/#set) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from left to right. Uses the first element as the initial value. ## [](#signature)Signature ```fql-sig reduce(reducer: ((A, A) => A)) => A | Null ``` ## [](#description)Description Iterates through each element in a [Set](../../../fql/types/#set) to perform a rolling operation. For example, you can use `reduce()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `reduce()` calls a reducer callback function on every element of the Set from left to right. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. The first element in the Set serves as the initial accumulator. * The current element’s value. The method returns the result of the last iteration. The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `reduce()` to sum stock counts let stockCounts = Product.all().map(doc => doc.stock) stockCounts.reduce((a, b) => a + b) ``` Emits the following hint: ``` performance_hint: full_set_read - Using reduce() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:19 | 3 | stockCounts.reduce((a, b) => a + b) | ^^^^^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let stockCounts = Product.all().take(20).map(doc => doc.stock) stockCounts.reduce((a, b) => a + b) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-use-on-large-sets)Avoid use on large sets This method scans the full [Set](../../../fql/types/#set), which can cause many reads and might time out for large [Set](../../../fql/types/#set)s. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce a Set to a single value. These methods include: * [`set.fold()`](../fold/) * [`set.foldRight()`](../foldright/) * [`set.reduce()`](./) * [`set.reduceRight()`](../reduceright/) The methods are similar but have the following differences: * [`set.fold()`](../fold/) and [`set.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`set.reduce()`](./) and [`set.reduceRight()`](../reduceright/) use the Set’s first element as the initial _accumulator_. * [`set.fold()`](../fold/) and [`set.reduce()`](./) iterate through the Set’s elements from left to right. [`set.foldRight()`](../foldright/) and [`set.reduceRight()`](../reduceright/) iterate through the Set’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | reducer | Function | true | Anonymous FQL function to call on each element in the Set. | ### [](#reducer-function-parameters)Reducer function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. | | Null | Returns Null if the calling Set is empty. | ## [](#examples)Examples 1. Starting with the following product prices: ```fql // Gets a Set of the first nine `Product` collection // documents and projects the `price` field. Product.all().take(9) { price } ``` ``` { data: [ { price: 698 }, { price: 2499 }, { price: 499 }, { price: 399 }, { price: 35 }, { price: 349 }, { price: 299 }, { price: 149 }, { price: 2399 } ] } ``` 2. Use `reduce()` to find the maximum price in the Set: ```fql Product.all().take(9).reduce((s, v) => { if (v.price > s.price) { v } else { s } }) {price} ``` ``` { price: 2499 } ``` # `set.reduceRight()` | Learn: Sets | | --- | --- | --- | Reduce a [Set](../../../fql/types/#set) to a single, accumulated value by applying a provided [function](../../../fql/functions/) to each element. Iterates through elements from right to left. Uses the first element as the initial value. ## [](#signature)Signature ```fql-sig reduceRight(reducer: ((A, A) => A)) => A | Null ``` ## [](#description)Description Iterates through each element in a Set to perform a rolling operation. For example, you can use `reduceRight()` to calculate a rolling sum, concatenate elements, or perform complex transformations. `reduceRight()` calls a reducer callback function on every element of the Set from right to left. The reducer function takes two arguments: * The accumulator that holds the running result from previous iterations. The last element in the Set serves as the initial accumulator. * The current element’s value. The method returns the result of the last iteration. The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `reduceRight()` to sum stock counts let stockCounts = Product.all().map(doc => doc.stock) stockCounts.reduceRight((a, b) => a + b) ``` Emits the following hint: ``` performance_hint: full_set_read - Using reduceRight() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:24 | 3 | stockCounts.reduceRight((a, b) => a + b) | ^^^^^^^^^^^^^^^^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` let stockCounts = Product.all().take(20).map(doc => doc.stock) stockCounts.reduceRight((a, b) => a + b) ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#fold-family-methods)Fold family methods FQL supports several methods for [folds](https://en.wikipedia.org/wiki/Fold_\(higher-order_function\)), which iteratively reduce a Set to a single value. These methods include: * [`set.fold()`](../fold/) * [`set.foldRight()`](../foldright/) * [`set.reduce()`](../reduce/) * [`set.reduceRight()`](./) The methods are similar but have the following differences: * [`set.fold()`](../fold/) and [`set.foldRight()`](../foldright/) accept an initial _seed_ value and use it as the initial _accumulator_. [`set.reduce()`](../reduce/) and [`set.reduceRight()`](./) use the Set’s first element as the initial _accumulator_. * [`set.fold()`](../fold/) and [`set.reduce()`](../reduce/) iterate through the Set’s elements from left to right. [`set.foldRight()`](../foldright/) and [`set.reduceRight()`](./) iterate through the Set’s elements from right to left. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | reducer | Function | true | Anonymous FQL function to call on each element in the Set. | ### [](#reducer-function-parameters)Reducer function parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | accumulator | Generic | true | Value returned by the previous reducer function call. On the first call, seed is passed as the accumulator. | | current | Generic | true | The current element’s value. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Generic | Result of the last reducer function call. | | Null | Returns Null if the calling Set is empty. | ## [](#examples)Examples Reduce the [Set](../../../fql/types/#set) item, right to left: ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.reduceRight((acc, elem) => acc + elem) ``` ``` 6 ``` # `set.reverse()` | Learn: Sets | | --- | --- | --- | Reverse the order of a [Set](../../../fql/types/#set)'s elements. | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig reverse() => Set ``` ## [](#description)Description Reverses the order of the calling [Set](../../../fql/types/#set)'s elements. The calling Set isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing reversed elements. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2, 3].toSet() set.reverse() ``` ``` { data: [ 3, 2, 1 ] } ``` # `set.take()` | Learn: Sets | | --- | --- | --- | Get the first _N_ elements of a [Set](../../../fql/types/#set). | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig take(limit: Number) => Set ``` ## [](#description)Description Takes the first _N_ elements from the calling [Set](../../../fql/types/#set) and returns them as a new [Set](../../../fql/types/#set). If there are fewer values than _N_ elements in the [Set](../../../fql/types/#set), all elements are returned. The calling Set isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | limit | Number | true | Number of elements to return from the start of the Set. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing the requested elements. | ## [](#examples)Examples Get the first two documents in the [Set](../../../fql/types/#set) of `Product` documents: ```fql Product.all().take(2) ``` ``` { data: [ { id: "111", coll: Product, ts: Time("2099-10-22T21:56:31.260Z"), name: "cups", description: "Translucent 9 Oz, 100 ct", price: 698, stock: 100, category: Category("123") }, { id: "222", coll: Product, ts: Time("2099-10-22T21:56:31.260Z"), name: "donkey pinata", description: "Original Classic Donkey Pinata", price: 2499, stock: 50, category: Category("123") } ] } ``` # `set.toArray()` | Learn: Sets | | --- | --- | --- | Convert a [Set](../../../fql/types/#set) to an [Array](../../../fql/types/#array). ## [](#signature)Signature ```fql-sig toArray() => Array ``` ## [](#description)Description Converts the calling [Set](../../../fql/types/#set) to an [Array](../../../fql/types/#array). The calling Set isn’t changed. ### [](#eager-loading)Eager loading This method uses [eager loading](../#eager) and requires a read of each document in the calling Set. For large Sets, this may result in poor performance and high costs. Performance hint: `full_set_read` Queries that call this method on a document Set emit a [performance hint](../../../http/reference/query-summary/#perf), if enabled. For example, the following query: ```fql // Use `toArray()` to convert the `Product` collection // to an Array. Product.all().toArray() ``` Emits the following hint: ``` performance_hint: full_set_read - Using toArray() causes the full set to be read. See https://docs.fauna.com/performance_hint/full_set_read. at *query*:3:22 | 3 | Product.all().toArray() | ^^ | ``` To address the hint, use [`set.take()`](../take/) to explicitly limit the size of the calling Set to fewer than 100 documents: ```fql // Limit the doc Set's size using `take()` Product.all().take(20).toArray() ``` This applies even if the original, unbounded Set contains fewer than 100 documents. Alternatively, you can rewrite the query to avoid calling the method. ### [](#avoid-use-on-large-sets)Avoid use on large sets Because this method scans the full Set, it returns an error if there are more than 16,000 documents in the Set. This method can timeout for large Sets under that limit. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array representation of the Set instance. | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [1, 2].toSet() set.toArray() ``` ``` [ 1, 2 ] ``` # `set.toString()` | Learn: Sets | | --- | --- | --- | Return the string `"[set]"`. ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description Return the string `"[set]"`. The calling Set isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "[set]". | ## [](#examples)Examples ```fql // `toSet()` converts an Array to a Set. let set = [].toSet() set.toString() ``` ``` "[set]" ``` # `set.where()` | Learn: Sets | | --- | --- | --- | Get the elements of a [Set](../../../fql/types/#set) that match a provided [predicate](../../../fql/functions/#predicates). | Loading strategy: | Lazy loading | | --- | --- | --- | --- | ## [](#signature)Signature ```fql-sig where(predicate: (A => Boolean | Null)) => Set ``` ## [](#description)Description Returns a [Set](../../../fql/types/#set) of elements from the calling [Set](../../../fql/types/#set) that match a provided [predicate function](../../../fql/functions/#predicates). If `where()` is the last value in a query, the first page of the created [Set](../../../fql/types/#set) is returned. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | predicate | Predicate function | Yes | Anonymous predicate function that:Accepts a Set element as its only argument. Supports shorthand-syntax for objects and documents.Returns a Boolean or NullThe method returns a Set of elements for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set containing elements of the calling Set that match the predicate. If there are no matching elements, the Set is empty. | ## [](#examples)Examples ### [](#basic-example)Basic example ```fql Customer.all().where(.address.state == "DC") ``` ``` { data: [ { id: "111", coll: Customer, ts: Time("2099-10-22T21:56:31.260Z"), cart: Order("412483941752112205"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, ... ] } ``` ### [](#filter)Filter covered index values You can use [`set.where()`](./) to filter the results of an [index call](../../../../learn/data-model/indexes/#call). If the [`set.where()`](./) predicate only accesses fields defined in the index definition’s `terms` and `values`, the query is [covered](../../../../learn/data-model/indexes/#covered-queries). For example, given the following index definition: ```fsl collection Product { ... index byName { terms [.name] values [.price, .description] } ... } ``` The following query is covered: ```fql // Covered query. // Calls the `byName()` index. // Uses `where()` to filter the results of // the index call. The predicates only // access covered terms and values. Product.byName("limes") .where(.description.includes("Conventional")) .where(.price < 500) { name, description, price } ``` The following query is uncovered: ```fql Product.byName("limes") .where(.description.includes("Conventional")) // The `where()` predicate accesses the uncovered // `stock` field. .where(.stock < 100) .where(.price < 500) { name, description, price } ``` To cover the query, add the uncovered field to the index definition’s `values`: ```fsl collection Product { ... index byName { terms [.name] // Adds `stock` to the index's values values [.price, .description, .stock] } ... } ``` # String [String](../../fql/types/#string) methods and properties. ## [](#description)Description [String](../../fql/types/#string) methods and properties are provided for formatting and manipulating sequences of characters. ## [](#instance-properties)Instance properties | Property | Description | | --- | --- | --- | --- | | length | Get the length of a String. | ## [](#instance-methods)Instance methods | Method | Description | | --- | --- | --- | --- | | string.at() | Get the character at a specified index of a String. | | string.casefold() | Convert a String to lower case using a specified format. | | string.concat() | Concatenate two Strings. | | string.endsWith() | Test if a String ends with a provided suffix. | | string.includes() | Test if a String includes a provided substring. | | string.includesRegex() | Test if a String contains a substring that matches a provided regular expression. | | string.indexOf() | Get the index of the first matching substring within a String. | | string.indexOfRegex() | Get the index of the first substring matching a provided regular expression within a String. | | string.insert() | Insert a substring into a String at a specified index. | | string.lastIndexOf() | Get the index of the last matching substring within a String. | | string.matches() | Get the substrings in a String that match a provided regular expression. | | string.matchIndexes() | Get the indexes and substrings in a String that match a provided regular expression. | | string.parseDouble() | Convert a String to a Double. | | string.parseInt() | Convert a String to a Int. | | string.parseLong() | Convert a String to a Long. | | string.parseNumber() | Convert a String to a Number. | | string.replace() | Replace a specified number of occurrences of a substring in a String. | | string.replaceAll() | Replace all occurrences of a substring in a String. | | string.replaceAllRegex() | Replace all occurrences of substrings matching a regular expression in a String. | | string.replaceRegex() | Replace a specified number of occurrences of substrings matching a regular expression in a String. | | string.slice() | Get the substring between two indexes of a String. | | string.split() | Split a String at a provided separator. | | string.splitAt() | Split a String at a provided index. | | string.splitRegex() | Split a String using a provided regular expression. | | string.startsWith() | Test if a String starts with a provided prefix. | | string.toLowerCase() | Convert a String to lower case. | | string.toString() | Get a String representation of the value. | | string.toUpperCase() | Convert a String to upper case. | # `string.length` Get a [String](../../../fql/types/#string)'s length. ## [](#signature)Signature ```fql-sig .length: Number ``` ## [](#description)Description Returns the calling [String](../../../fql/types/#string)'s length. The length of an empty [String](../../../fql/types/#string) is `0`. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Int | Number of characters in the calling String. | ## [](#examples)Examples Get the length of a [String](../../../fql/types/#string): ```fql "HTTP/1.1 200 OK".length ``` ``` 15 ``` # `string.at()` Get the character at a specified index of a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig at(index: Number) => String ``` ## [](#description)Description Returns the UTF-16 character located at a zero-based offset index. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | index | Int | true | Zero-based index of the character to return. Must be less than the String's length. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Character located at the specified index. | ## [](#examples)Examples Return the character at index offset `9`: ```fql "HTTP/1.1 200 OK".at(9) ``` ``` "2" ``` # `string.casefold()` Convert a [String](../../../fql/types/#string) to lower case using a specified format. ## [](#signature)Signature ```fql-sig casefold() => String casefold(format: String) => String ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to lower case. This method is similar to [`string.toLowerCase()`](../tolowercase/) but uses an optionally specified format. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | format | String | | Unicode normalization form applied to the converted String: Normalization formDescriptionNFKCCaseFold(Default) Characters are decomposed by compatibility then recomposed by canonical equivalence.NFCCanonical decomposition followed by canonical composition. Characters are decomposed and then recomposed by canonical equivalence.NFDCanonical decomposition. Characters are decomposed by canonical equivalence, and multiple combining characters are arranged in order.NFKCCompatibility decomposition, followed by canonical composition. Characters are decomposed by compatibility then recomposed by canonical equivalence.NFKDCompatibility decomposition. Characters are decomposed by compatibility, and multiple combining characters are arranged in order.See also: Unicode Normalization Forms. | Normalization form | Description | NFKCCaseFold | (Default) Characters are decomposed by compatibility then recomposed by canonical equivalence. | NFC | Canonical decomposition followed by canonical composition. Characters are decomposed and then recomposed by canonical equivalence. | NFD | Canonical decomposition. Characters are decomposed by canonical equivalence, and multiple combining characters are arranged in order. | NFKC | Compatibility decomposition, followed by canonical composition. Characters are decomposed by compatibility then recomposed by canonical equivalence. | NFKD | Compatibility decomposition. Characters are decomposed by compatibility, and multiple combining characters are arranged in order. | | Normalization form | Description | | NFKCCaseFold | (Default) Characters are decomposed by compatibility then recomposed by canonical equivalence. | | NFC | Canonical decomposition followed by canonical composition. Characters are decomposed and then recomposed by canonical equivalence. | | NFD | Canonical decomposition. Characters are decomposed by canonical equivalence, and multiple combining characters are arranged in order. | | NFKC | Compatibility decomposition, followed by canonical composition. Characters are decomposed by compatibility then recomposed by canonical equivalence. | | NFKD | Compatibility decomposition. Characters are decomposed by compatibility, and multiple combining characters are arranged in order. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Lower case version of the calling String. | ## [](#examples)Examples 1. Convert an email address to lower case using the default NFKC normalization form: ```fql "john.doe@EXAMPLE.COM".casefold() ``` ``` "john.doe@example.com" ``` 2. Convert an email address to lower case using the NFC normalization form: ```fql "john.doe@EXAMPLE.COM".casefold("NFC") ``` ``` "john.doe@EXAMPLE.COM" ``` 3. Default convert Unicode sequence to lower case: ```fql "\uff21\u0030a\u0301".casefold() ``` ``` "a0á" ``` 4. Convert the same Unicode sequence using `NFCK` option: ```fql "\uff21\u0030a\u0301".casefold("NFKC") ``` ``` "A0á" ``` 5. Convert the same Unicode sequence using `NFC` option: ```fql "\uff21\u0030a\u0301".casefold("NFC") ``` ``` "A0á" ``` # `string.concat()` Concatenate two [String](../../../fql/types/#string)s. ## [](#signature)Signature ```fql-sig concat(other: String) => String ``` ## [](#description)Description Concatenates two provided [String](../../../fql/types/#string)s. This method is equivalent to using the `+` operator with [String](../../../fql/types/#string) operands. The input [String](../../../fql/types/#string)s aren’t modified. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | other | String | true | String to concatenate to the calling String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | The resulting concatenated String. | ## [](#examples)Examples Concatenate the calling [String](../../../fql/types/#string) with the [String](../../../fql/types/#string) "SUCCESS": ```fql "HTTP/1.1 200 OK".concat(" SUCCESS") ``` ``` "HTTP/1.1 200 OK SUCCESS" ``` # `string.endsWith()` Test if a [String](../../../fql/types/#string) ends with a provided suffix. ## [](#signature)Signature ```fql-sig endsWith(suffix: String) => Boolean ``` ## [](#description)Description Tests if the calling [String](../../../fql/types/#string) ends with a provided suffix. An exact match returns `true`. Otherwise, the method returns `false`. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | suffix | String | true | Suffix to compare to the end of the calling String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the calling String ends with the suffix. Otherwise, false. | ## [](#examples)Examples 1. Test whether a [String](../../../fql/types/#string) ends with `200 OK`: ```fql "HTTP/1.1 200 OK".endsWith("200 OK") ``` ``` true ``` 2. Test whether a [String](../../../fql/types/#string) ends with `200`: ```fql "HTTP/1.1 200 OK".endsWith("200") ``` ``` false ``` # `string.includes()` Test if a [String](../../../fql/types/#string) includes a provided substring. ## [](#signature)Signature ```fql-sig includes(pattern: String) => Boolean ``` ## [](#description)Description Tests if the calling [String](../../../fql/types/#string) contains a provided substring. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Substring to search for in this String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the calling String contains the provided substring. Otherwise, false. | ## [](#examples)Examples 1. Test if the calling string includes the [String](../../../fql/types/#string) `200`: ```fql "HTTP/1.1 200 OK".includes("200") ``` ``` true ``` 2. Test if the calling string includes the [String](../../../fql/types/#string) `400`: ```fql "HTTP/1.1 200 OK".includes("400") ``` ``` false ``` # `string.includesRegex()` Test if a [String](../../../fql/types/#string) contains a substring that matches a provided regular expression. ## [](#signature)Signature ```fql-sig includesRegex(regex: String) => Boolean ``` ## [](#description)Description Tests if the calling [String](../../../fql/types/#string) contains a substring that matches a provided regular expression. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression used to match a substring in the calling String. Supports Java regex. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the calling String contains a substring that matches the provided regular expression. Otherwise, false. | ## [](#examples)Examples ```fql 'foo'.includesRegex('[a-z]') ``` ``` true ``` # `string.indexOf()` Get the index of the first matching substring within a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig indexOf(pattern: String) => Number | Null indexOf(pattern: String, start: Number) => Number | Null ``` ## [](#description)Description Returns the zero-based offset index for the first occurrence of a provided substring within the calling [String](../../../fql/types/#string). Starts at an optional start position in the calling [String](../../../fql/types/#string). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Substring to find the first occurrence of within the calling String. | | start | Int | | Zero-based index of the character to start searching for matches. Defaults to 0. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Int | Zero-based index of the first matching occurrence in the calling String. | | Null | No match not found. | ## [](#examples)Examples 1. Get the starting location of the [String](../../../fql/types/#string) `200`, starting from the beginning of the calling string: ```fql "HTTP/1.1 200 OK".indexOf("200", 0) ``` ``` 9 ``` 2. Get the starting location of the [String](../../../fql/types/#string) `200`, starting at a location after the length of the calling string: ```fql "HTTP/1.1 200 OK".indexOf("200", 10) ``` ``` null ``` # `string.indexOfRegex()` Get the index of the first substring matching a provided regular expression within a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig indexOfRegex(regex: String) => Number | Null indexOfRegex(regex: String, start: Number) => Number | Null ``` ## [](#description)Description Returns the zero-based offset index for the first occurrence of a substring matching a provided regular expression within the calling [String](../../../fql/types/#string). Starts at an optional start position in the calling [String](../../../fql/types/#string). == Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression used to match substrings in the calling String. Supports Java regex. | | start | Number | | Zero-based index of the character to start searching for matches. Defaults to 0. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Int | Zero-based index of the first matching occurrence in the calling String. | | Null | No match not found. | ## [](#examples)Examples ```fql 'foo 123'.indexOfRegex('[0-9]') ``` ``` 4 ``` ```fql 'foo 123 abc 5678'.indexOfRegex('[0-9]', 10) ``` ``` 12 ``` # `string.insert()` Insert a substring into a [String](../../../fql/types/#string) at a specified index. ## [](#signature)Signature ```fql-sig insert(index: Number, other: String) => String ``` ## [](#description)Description Inserts a substring into the calling [String](../../../fql/types/#string) at a provided zero-based offset index position. Returns a new [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | index | Number | true | Zero-based index position to insert the substring at. | | insert | String | true | Substring to insert. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String with the inserted substring. | ## [](#examples)Examples ```fql 'foo'.insert(0, 'bar') ``` ``` "barfoo" ``` # `string.lastIndexOf()` Get the index of the last matching substring within a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig lastIndexOf(pattern: String) => Number | Null lastIndexOf(pattern: String, end: Number) => Number | Null ``` ## [](#description)Description Returns the zero-based offset index for the last occurrence of a provided substring within the calling [String](../../../fql/types/#string). Ends at an optional end position in the calling [String](../../../fql/types/#string). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Substring to find the last occurrence of within the calling String. | | end | Int | true | Zero-based index of the character to end searching for matches, counting from left to right. Defaults to the last character of the calling String. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Int | Zero-based index of the last matching occurrence in the calling String, ending at the specified end character. | | Null | No match not found. | ## [](#examples)Examples 1. Get the location of the last occurrence of the [String](../../../fql/types/#string) "200" at or below index location 27: ```fql "HTTP/1.1 200 OK - SUCCESS (200)".lastIndexOf("200", 27) ``` ``` 27 ``` 2. Get the location of the last occurrence of the [String](../../../fql/types/#string) "200" at or below index location 20: ```fql "HTTP/1.1 200 OK - SUCCESS (200)".lastIndexOf("200", 20) ``` ``` 9 ``` 3. Get the location of the last occurrence of the [String](../../../fql/types/#string) "200" at or below index location 8, which fails because the [String](../../../fql/types/#string) isn’t found: ```fql "HTTP/1.1 200 OK - SUCCESS (200)".lastIndexOf("200", 8) ``` ``` null ``` # `string.matches()` Get the substrings in a [String](../../../fql/types/#string) that match a provided regular expression. ## [](#signature)Signature ```fql-sig matches(regex: String) => Array ``` ## [](#description)Description Returns an [Array](../../../fql/types/#array) of substrings in the calling [String](../../../fql/types/#string) that match a provided regular expression. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression to find matches for in the calling String. Supports Java regex. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Substrings that match the provided regular expression. | ## [](#examples)Examples ```fql 'foo bar baz'.matches('bar') ``` ``` [ "bar" ] ``` ```fql 'foo bar baz'.matches('[a-z]+') ``` ``` [ "foo", "bar", "baz" ] ``` # `string.matchIndexes()` Get the indexes and substrings in a [String](../../../fql/types/#string) that match a provided regular expression. ## [](#signature)Signature ```fql-sig matchIndexes(regex: String) => Array<[Number, String]> ``` ## [](#description)Description Returns an [Array](../../../fql/types/#array) of substrings and their indexes in the calling [String](../../../fql/types/#string) that match a provided regular expression. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression to find matches for in the calling String. Supports Java regex. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Index and substrings that matches the provided regular expression. | ## [](#examples)Examples ```fql 'foobarbaz'.matchIndexes('bar') ``` ``` [ [ 3, "bar" ] ] ``` ```fql 'foo bar baz'.matchIndexes('[a-z]+') ``` ``` [ [ 0, "foo" ], [ 4, "bar" ], [ 8, "baz" ] ] ``` # `string.parseDouble()` Convert a [String](../../../fql/types/#string) to a [Double](../../../fql/types/#double). ## [](#signature)Signature ```fql-sig parseDouble() => Number | Null ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to a numeric [Double](../../../fql/types/#double). The calling [String](../../../fql/types/#string) isn’t changed. ### [](#limitations)Limitations * Leading and trailing whitespace are allowed. * Exponential notation is allowed. * Comma separators aren’t allowed. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Double parsed from the calling string. | | Null | Unable to parse calling String. | ## [](#examples)Examples 1. Convert a simple numeric value: ```fql "2147483647".parseDouble() ``` ``` 2.147483647E9 ``` 2. Convert a value represented in exponential notation: ```fql "1.7976931348623158e308".parseDouble() ``` ``` 1.7976931348623157e+308 ``` # `string.parseInt()` Convert a [String](../../../fql/types/#string) to a [Int](../../../fql/types/#int). ## [](#signature)Signature ```fql-sig parseInt() => Number | Null parseInt(radix: Number) => Number | Null ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to a numeric [Int](../../../fql/types/#int). The calling [String](../../../fql/types/#string) isn’t changed. ### [](#limitations)Limitations * Leading and trailing whitespace and comma separators result in an error. * Exponential notation isn’t allowed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | radix | Number | | Value between 2 and 36 that represents the radix of the calling String. Default = 10. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Int parsed from the calling String. | | Null | Unable to parse calling String. | ## [](#examples)Examples Convert a value using the default, base 10 radix: ```fql "2147483647".parseInt() ``` ``` 2147483647 ``` # `string.parseLong()` Convert a [String](../../../fql/types/#string) to a [Long](../../../fql/types/#long). ## [](#signature)Signature ```fql-sig parseLong() => Number | Null parseLong(radix: Number) => Number | Null ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to a numeric [Long](../../../fql/types/#long). The calling [String](../../../fql/types/#string) isn’t changed. ### [](#limitations)Limitations * Leading and trailing whitespace and comma separators result in an error. * Exponential notation isn’t allowed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | radix | Number | | Value between 2 and 36 that represents the radix of the calling String. Default = 10. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Long parsed from the calling String. | | Null | Unable to parse calling String. | ## [](#examples)Examples Convert an email address to upper case: ```fql "10".parseLong() ``` ``` 10 ``` # `string.parseNumber()` Convert a [String](../../../fql/types/#string) to a [Number](../../../fql/types/#number). ## [](#signature)Signature ```fql-sig parseNumber() => Number | Null ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to a numeric [Number](../../../fql/types/#number). The method attempts to parse the calling [String](../../../fql/types/#string) in the following order: 1. [Int](../../../fql/types/#int) 2. [Long](../../../fql/types/#long) 3. [Double](../../../fql/types/#double) The calling [String](../../../fql/types/#string) isn’t changed. ### [](#limitations)Limitations * Leading and trailing whitespace are allowed. * Exponential notation is allowed. * Comma separators aren’t allowed. ## [](#parameters)Parameters None ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Number | Value parsed from the calling String. | | Null | Unable to parse calling String. | ## [](#examples)Examples 1. Convert an exponential value: ```fql "1.7976931348623158e308".parseNumber() ``` ``` 1.7976931348623157e+308 ``` 2. Convert the [String](../../../fql/types/#string) to a number larger than [Number](../../../fql/types/#number) can hold: ```fql "1.7976931348623159e308".parseNumber() ``` ``` Math.Infinity ``` # `string.replace()` Replace a specified number of occurrences of a substring in a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig replace(pattern: String, replacement: String) => String replace(pattern: String, replacement: String, amount: Number) => String ``` ## [](#description)Description Replaces the occurrences of a provided substring in the calling [String](../../../fql/types/#string) with a provided replacement for a specified number of times. Returns a new [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Substring to match in the calling String. | | replacement | String | true | Replacement for matching substrings in the calling String. | | amount | Number | | Number of replacements to make in the calling String. Defaults to 1. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Resulting String with replacements. | ## [](#examples)Examples ```fql 'foobar'.replace('foo', 'bar') ``` ``` "barbar" ``` # `string.replaceAll()` Replace all occurrences of a substring in a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig replaceAll(pattern: String, replacement: String) => String ``` ## [](#description)Description Replaces all occurrences of a provided substring in the calling [String](../../../fql/types/#string) with a provided replacement. Returns a new [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Substring to match in the calling String. | | replacement | String | true | Replacement for matching substrings in the calling String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Resulting String with replacements. | ## [](#examples)Examples ```fql 'foobar'.replaceAll('foo', 'bar') ``` ``` "barbar" ``` # `string.replaceAllRegex()` Replace all occurrences of substrings matching a regular expression in a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig replaceAllRegex(pattern: String, replacement: String) => String ``` ## [](#description)Description Replaces all occurrences of substrings matching a regular expression in the calling [String](../../../fql/types/#string) with a provided replacement. Returns a new [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pattern | String | true | Regular expression to match in the calling String. Supports Java regex. | | replacement | String | true | Replacement for matches in the calling String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Resulting String with replacements. | ## [](#examples)Examples ```fql "1234".replaceAllRegex('\\w', 'abc-') ``` ``` "abc-abc-abc-abc-" ``` # `string.replaceRegex()` Replace a specified number of occurrences of substrings matching a regular expression in a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig replaceRegex(regex: String, replacement: String) => String replaceRegex(regex: String, replacement: String, amount: Number) => String ``` ## [](#description)Description Replaces the occurrences of substrings matching a regular expression in the calling [String](../../../fql/types/#string) with a provided replacement for a specified number of times. Returns a new [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression to match in the calling String. Supports Java regex. | | replacement | String | true | Replacement for matching substrings in the calling String. | | amount | Number | | Number of replacements to make in the calling String. Defaults to 1. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Resulting String with replacements. | ## [](#examples)Examples ```fql 'foo bar'.replaceRegex('\\w', 'z', 2) ``` ``` "zzo bar" ``` # `string.slice()` Get the substring between two indexes of a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig slice(start: Number) => String slice(start: Number, end: Number) => String ``` ## [](#description)Description Extracts the substring between provided two zero-based offset indexes of the calling [String](../../../fql/types/#string). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | start | Int | true | Starting index of the substring to extract (inclusive). The index is a zero-based offset, counted from the left. If this start index is greater than or equal to the length of the String, the method returns an empty String. | | end | Int | true | Ending index of the substring to extract (exclusive). The index is a zero-based offset, counted from the left. If this end index is less than the start index, the method returns an empty String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Substring extracted from the calling String. | ## [](#examples)Examples Get the sub[String](../../../fql/types/#string) from index 9 up to, but not including, 15: ```fql "HTTP/1.1 200 OK".slice(9, 15) ``` ``` "200 OK" ``` # `string.split()` Split a [String](../../../fql/types/#string) at a provided separator. ## [](#signature)Signature ```fql-sig split(separator: String) => Array ``` ## [](#description)Description Splits the calling [String](../../../fql/types/#string) at every occurrence of a provided separator. Returns an array of the resulting [String](../../../fql/types/#string)s. The separator isn’t preserved in the results. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | separator | String | true | Separator to split the calling string[] at. Splits at every occurrence of the separator. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of Strings resulting from the split. The separator isn’t preserved in the results. | ## [](#examples)Examples ```fql 'foobarbaz'.split('b') ``` ``` [ "foo", "ar", "az" ] ``` # `string.splitAt()` Split a [String](../../../fql/types/#string) at a provided index. ## [](#signature)Signature ```fql-sig splitAt(index: Number) => [String, String] ``` ## [](#description)Description Splits the calling [String](../../../fql/types/#string) at a zero-based offset index. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | index | Number | true | Zero-based offset index to split the calling String at. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of Strings resulting from the split. | ## [](#examples)Examples ```fql 'foobar'.splitAt(3) ``` ``` [ "foo", "bar" ] ``` # `string.splitRegex()` Split a [String](../../../fql/types/#string) using a provided regular expression. ## [](#signature)Signature ```fql-sig splitRegex(regex: String) => Array ``` ## [](#description)Description Splits the calling [String](../../../fql/types/#string) at every occurrence of a provided regular expression, used as a delimiter string. The calling [String](../../../fql/types/#string) isn’t changed. Multiple, adjacent delimiters in the calling [String](../../../fql/types/#string) result in an empty element in the resulting [Array](../../../fql/types/#array). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | regex | String | true | Regular expression to split the calling string[] at. Splits at every matching substring. Supports Java regex. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Array | Array of Strings resulting from the split. | ## [](#examples)Examples ```fql 'foo bar baz'.splitRegex('\\W+') ``` ``` [ "foo", "bar", "baz" ] ``` # `string.startsWith()` Test if a [String](../../../fql/types/#string) starts with a provided prefix. ## [](#signature)Signature ```fql-sig startsWith(prefix: String) => Boolean ``` ## [](#description)Description Tests if the calling [String](../../../fql/types/#string) starts with a provided prefix. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | prefix | String | true | Prefix to compare to the end of the calling String. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the calling String ends with the prefix. Otherwise, false. | ## [](#examples)Examples 1. Test whether a [String](../../../fql/types/#string) starts with `HTTP`: ```fql "HTTP/1.1 200 OK".startsWith("HTTP") ``` ``` true ``` 2. Test whether a [String](../../../fql/types/#string) starts with `200`: ```fql "HTTP/1.1 200 OK".startsWith("200") ``` ``` false ``` # `string.toLowerCase()` Convert a [String](../../../fql/types/#string) to lower case. ## [](#signature)Signature ```fql-sig toLowerCase() => String ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to lower case. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Lower case version of the calling String. | ## [](#examples)Examples Convert an email address to lower case: ```fql "john.doe@EXAMPLE.COM".toLowerCase() ``` ``` "john.doe@example.com" ``` # `string.toString()` Get a [String](../../../fql/types/#string) representation of the value. ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description Returns a [String](../../../fql/types/#string) representation of the calling value. If the calling value is a [String](../../../fql/types/#string), it returns the calling [String](../../../fql/types/#string). The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String representation of the calling String. | ## [](#examples)Examples Confirm that the calling string type returns itself: ```fql 'foobar'.toString() ``` ``` "foobar" ``` Get the [String](../../../fql/types/#string) representation of a [`Time()`](../../time/time/) value: ```fql let t1 = Time.fromString("2099-10-20T21:15:09.890729Z") t1.toString() ``` ``` "2099-10-20T21:15:09.890729Z" ``` Get the [String](../../../fql/types/#string) representation of a floating point number: ```fql 1.5.toString() ``` ``` "1.5" ``` # `string.toUpperCase()` Convert a [String](../../../fql/types/#string) to upper case. ## [](#signature)Signature ```fql-sig toUpperCase() => String ``` ## [](#description)Description Converts the calling [String](../../../fql/types/#string) to upper case. The calling [String](../../../fql/types/#string) isn’t changed. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | Upper case version of the calling String. | ## [](#examples)Examples Convert an email address to upper case: ```fql "john.doe@example.com".toUpperCase() ``` ``` "JOHN.DOE@EXAMPLE.COM" ``` # Time [Time](../../fql/types/#time) methods and properties.. ## [](#description)Description [Time](../../fql/types/#time) methods are provided to represent an instantaneous point in time. ## [](#instance-properties)Instance properties | Method | Description | | --- | --- | --- | --- | | dayOfMonth | Get the day of the month from a Time. | | dayOfWeek | Get the day of the week from a Time. | | dayOfYear | Get the day of the year from a Time. | | hour | Get the hour of a Time. | | minute | Get the minute of a Time. | | month | Get the month of a Time. | | second | Get the second of a Time. | | year | Get the year of a Time. | ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | Time() | Construct a Time from an ISO 8601 timestamp String. | | Time.epoch() | Convert a Unix epoch timestamp to a Time. | | Time.fromString() | Construct a Time from an ISO 8601 timestamp String. | | Time.now() | Get the current UTC Time. | ## [](#instance-methods)Instance methods | Method | Description | | --- | --- | --- | --- | | time.add() | Add a time interval to a Time. | | time.difference() | Get the difference between two Times. | | time.subtract() | Subtract a time interval from a Time. | | time.toMicros() | Convert a Time to a Unix epoch timestamp in microseconds. | | time.toMillis() | Convert a Time to a Unix epoch timestamp in milliseconds. | | time.toSeconds() | Convert a Time to a Unix epoch timestamp in seconds. | | time.toString() | Convert a Time to a String. | # `dayOfMonth` Get the day of the month from a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig dayOfMonth: Number ``` ## [](#description)Description Get the day-of-month. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day-of-month field of the Time instance. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').dayOfMonth ``` ``` 10 ``` # `dayOfWeek` Get the day of the week from a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig dayOfWeek: Number ``` ## [](#description)Description Get the day-of-week. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day-of-week field of the Time instance:1 = Monday2 = Tuesday3 = Wednesday4 = Thursday5 = Friday6 = Saturday7 = Sunday | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').dayOfWeek ``` ``` 2 ``` # `dayOfYear` Get the day of the year from a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig dayOfYear: Number ``` ## [](#description)Description Get the day-of-year. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Day-of-year field of Time instance. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').dayOfYear ``` ``` 41 ``` # `hour` Get the hour of a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig hour: Number ``` ## [](#description)Description Get the [Time](../../../fql/types/#time) hour field. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Hour field of Time instance. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').hour ``` ``` 12 ``` # `minute` Get the minute of a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig minute: Number ``` ## [](#description)Description Get the [Time](../../../fql/types/#time) minute field. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Minutes field of the Time instance. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').minute ``` ``` 1 ``` # `month` Get the month of a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig month: Number ``` ## [](#description)Description Get the [Time](../../../fql/types/#time) month field. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | The month. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').month ``` ``` 2 ``` # `second` Get the second of a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig second: Number ``` ## [](#description)Description Get the [Time](../../../fql/types/#time) second field. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Seconds field of Time instance. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').second ``` ``` 19 ``` # `year` Get the year of a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig year: Number ``` ## [](#description)Description Get the [Time](../../../fql/types/#time) year field. ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | The year. | ## [](#examples)Examples ```fql Time('2099-02-10T12:01:19.000Z').year ``` ``` 2099 ``` # `Time()` Construct a [Time](../../../fql/types/#time) from an ISO 8601 timestamp [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Time(time: String) => Time ``` ## [](#description)Description Converts an ISO 8601 timestamp [String](../../../fql/types/#string) to a [Time](../../../fql/types/#time) value. Parameter fields: | Time field | Description | | --- | --- | --- | --- | | yyyy | Four-digit year. | | MM | Month, from 01 to 12. | | dd | Day, from 01 to 31. | | T | Date and time separator. | | hh | Hours, from 00 to 23. | | mm | Minutes, from 00 to 59. | | ss | Seconds, from 00 to 59, which can also be expressed as a decimal fraction to give nanosecond resolution. | | TZO | Timezone offset from UTC which can be one of: TimezoneDescriptionZUTC, no offset+hhmmPositive hour and minute offset from UTC.-hhmmNegative hour and minute offset from UTC. | Timezone | Description | Z | UTC, no offset | +hhmm | Positive hour and minute offset from UTC. | -hhmm | Negative hour and minute offset from UTC. | | Timezone | Description | | Z | UTC, no offset | | +hhmm | Positive hour and minute offset from UTC. | | -hhmm | Negative hour and minute offset from UTC. | This method is equivalent to the [`Time.fromString()`](../fromstring/) method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | time | String | true | Timestamp string in the form yyyy-MM-ddThh:mm:ssTZO. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | Time representation of the timestamp string. | ## [](#examples)Examples Convert a time [String](../../../fql/types/#string) to a [Time](../../../fql/types/#time) value: ```fql Time("2099-10-20T21:15:09.890729Z") ``` ``` Time("2099-10-20T21:15:09.890729Z") ``` Test if a document timestamp is equal to a given time: ```fql Customer.where(.ts == Time("2099-06-25T20:23:49.070Z")) ``` ``` { data: [ { id: "111", coll: Customer, ts: Time("2099-06-25T20:23:49.070Z"), cart: Order("412483941752112205"), orders: "hdW...", name: "Alice Appleseed", email: "alice.appleseed@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, ... ] } ``` # `Time.epoch()` Convert a Unix epoch timestamp to a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig Time.epoch(offset: Number, unit: String) => Time ``` ## [](#description)Description Converts a [Number](../../../fql/types/#number) representing a Unix epoch timestamp to a [Time](../../../fql/types/#time) value. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | offset | Number | true | Offset from the Unix epoch. | | unit | String | true | Time unit used to measure the offset from the Unix epoch.nanosecondsmicrosecondsmillisecondssecondsminuteshoursdays | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | Resulting Time, rounded to the nearest nanosecond. | ## [](#examples)Examples ```fql Time.epoch(1676030400, 'seconds') ``` ``` Time("2023-02-10T12:00:00Z") ``` # `Time.fromString()` Construct a [Time](../../../fql/types/#time) from an ISO 8601 timestamp [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Time.fromString(time: String) => Time ``` ## [](#description)Description Converts an ISO 8601 timestamp [String](../../../fql/types/#string) to a [Time](../../../fql/types/#time) value. Parameter fields: | Time field | Description | | --- | --- | --- | --- | | yyyy | Four-digit year. | | MM | Month, from 01 to 12. | | dd | Day, from 01 to 31. | | T | Date and time separator. | | hh | Hours, from 00 to 23. | | mm | Minutes, from 00 to 59. | | ss | Seconds, from 00 to 59, which can also be expressed as a decimal fraction to give nanosecond resolution. | | TZO | Timezone offset from UTC which can be one of: TimezoneDescriptionZUTC, no offset+hhmmPositive hour and minute offset from UTC.-hhmmNegative hour and minute offset from UTC. | Timezone | Description | Z | UTC, no offset | +hhmm | Positive hour and minute offset from UTC. | -hhmm | Negative hour and minute offset from UTC. | | Timezone | Description | | Z | UTC, no offset | | +hhmm | Positive hour and minute offset from UTC. | | -hhmm | Negative hour and minute offset from UTC. | This method is equivalent to the [`Time()`](../time/) method. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | time | String | true | Timestamp string in the form yyyy-MM-ddThh:mm:ssTZO. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | Time representation of the timestamp string. | ## [](#examples)Examples Convert a time [String](../../../fql/types/#string) to a [Time](../../../fql/types/#time) value: ```fql Time.fromString("2099-10-20T21:15:09.890729Z") ``` ``` Time("2099-10-20T21:15:09.890729Z") ``` # `Time.now()` Get the current UTC [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig Time.now() => Time ``` ## [](#description)Description The `Time.now()` method gets the start time of the current query. Calling `Time.now()` multiple times in a query returns the same value each time. The [Time](../../../fql/types/#time) object returned is in [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) and has nanosecond resolution. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | ISO 8601 time value representing the start time of the current query. | ## [](#examples)Examples Get the query start time: ```fql Time.now() ``` ``` Time("2099-10-07T14:43:33.469Z") ``` # `time.add()` Add a time interval to a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig add(amount: Number, unit: String) => Time ``` ## [](#description)Description Add a time interval to [Time](../../../fql/types/#time). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Number of units to add to the given time. | | unit | String | true | Unit for the operation. Accepts one of the following:nanosecondsmicrosecondsmillisecondssecondsminuteshoursdays | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | New time with the added time interval, rounded to the nearest nanosecond. | ## [](#examples)Examples ```fql Time('2099-02-10T12:00:00.000Z').add(19, 'minutes') ``` ``` Time("2099-02-10T12:19:00Z") ``` # `time.difference()` Get the difference between two [Time](../../../fql/types/#time)s. ## [](#signature)Signature ```fql-sig difference(start: Time, unit: String) => Number ``` ## [](#description)Description Get the difference between two times. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | start | Time | true | Time to subtract from instance Time. | | unit | String | true | Time units:nanosecondsmicrosecondsmillisecondssecondsminuteshoursdays | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Difference between the provided times, in units rounded to the nearest nanosecond. | ## [](#examples)Examples ```fql Time('2099-02-10T12:00:00.000Z').difference(Time('2099-02-01T12:00:00.000Z'), 'days') ``` ``` 9 ``` # `time.subtract()` Subtract a time interval from a [Time](../../../fql/types/#time). ## [](#signature)Signature ```fql-sig subtract(amount: Number, unit: String) => Time ``` ## [](#description)Description Subtract a time interval from [Time](../../../fql/types/#time). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | amount | Number | true | Count of number of units. | | unit | String | true | Time units:nanosecondsmicrosecondsmillisecondssecondsminuteshoursdays | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Time | Resulting time, rounded to the nearest nanosecond. | ## [](#examples)Examples ```fql Time('2099-02-10T12:00:00.000Z').add(19, 'minutes') ``` ``` Time("2099-02-10T12:19:00Z") ``` # `time.toMicros()` Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in microseconds. ## [](#signature)Signature ```fql-sig toMicros() => Number ``` ## [](#description)Description Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in microseconds. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Unix epoch timestamp in microseconds. | ## [](#examples)Examples ```fql Time("2099-02-10T12:01:19.000Z").toMicros() ``` ``` 4074408079000000 ``` # `time.toMillis()` Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in milliseconds. ## [](#signature)Signature ```fql-sig toMillis() => Number ``` ## [](#description)Description Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in milliseconds. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Unix epoch timestamp in milliseconds. | ## [](#examples)Examples ```fql Time("2099-02-10T12:01:19.000Z").toMillis() ``` ``` 4074408079000 ``` # `time.toSeconds()` Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in seconds. ## [](#signature)Signature ```fql-sig toSeconds() => Number ``` ## [](#description)Description Convert a [Time](../../../fql/types/#time) to a Unix epoch timestamp in seconds. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Number | Unix epoch timestamp in seconds. | ## [](#examples)Examples ```fql Time("2099-02-10T12:01:19.000Z").toSeconds() ``` ``` 4074408079 ``` # `time.toString()` Convert a [Time](../../../fql/types/#time) to a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig toString() => String ``` ## [](#description)Description Converts the calling [Time](../../../fql/types/#time) to an ISO 8601 [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | String representation of the calling Time. | ## [](#examples)Examples ```fql let t = Time("2099-10-20T21:15:09.890729Z") t.toString() ``` ``` "2099-10-20T21:15:09.890729Z" ``` # Token | Learn: Tokens | | --- | --- | --- | A [token](../../../learn/security/tokens/) is a type of [authentication secret](../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. You typically create and use tokens as part of a Fauna-based [end-user authentication system](../../../build/tutorials/auth/). ## [](#collection)`Token` collection Fauna stores tokens as documents in the `Token` system collection. `Token` documents have the following FQL structure: ``` { id: "401671202234433613", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), ttl: Time("2099-06-27T13:32:39.240Z"), document: Customer("401670531121676365"), secret: "fn..." } ``` | Field name | Value type | Read-only | Required | Description | | --- | --- | --- | --- | --- | --- | --- | | id | ID | | | ID for the Token document. The ID is a string-encoded, 64-bit unsigned integer in the 253-1 range. The ID is unique within the collection.IDs are assigned at document creation. To create a token with a user-provided id using Token.create(), you must use a secret with the create_with_id privilege for the Token collection. If not provided, Fauna generates the id. | | coll | Collection | true | | Collection name: Token. | | ts | Time | true | | Last time the document was created or updated. | | ttl | Time | | | Time-to-live (TTL) for the document. Only present if set. If not present or set to null, the document persists indefinitely. | | document | Ref | | true | The identity document associated with the token. | | secret | String | | | Randomly generated cryptographic hash. Equivalent to a password. | | data | Object | | | Arbitrary user-defined metadata for the document. | ## [](#static-methods)Static methods You can use the following static methods to manage the `Token` collection in FQL. | Method | Description | | --- | --- | --- | --- | | Token.all() | Get a Set of all tokens. | | Token.byDocument() | Get a token by its identity document. | | Token.byId() | Get a token by its document id. | | Token.create() | Create a token without a credential or related password. | | Token.firstWhere() | Get the first token that matches a provided predicate. | | Token.toString() | Get "Token" as a String. | | Token.where() | Get a Set of tokens that match a provided predicate. | ## [](#instance-methods)Instance methods You can use the following instance methods to manage specific `Token` documents in FQL. | Method | Description | | --- | --- | --- | --- | | token.delete() | Delete a token. | | token.exists() | Test if a token exists. | | token.replace() | Replace a token. | | token.update() | Update a token. | # `Token.all()` | Learn: Tokens | | --- | --- | --- | Get a Set of all [tokens](../../../../learn/security/tokens/). ## [](#signature)Signature ```fql-sig Token.all() => Set Token.all(range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set ``` ## [](#description)Description Gets a Set containing all [tokens](../../../../learn/security/tokens/), represented as [`Token` documents](../), for the database. To limit the returned Set, you can provide an optional range. If this method is the last expression in a query, the first page of the Set is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | range | { from: Any } | { to: Any } | { from: Any, to: Any } | | Specifies a range of Token documents in the form { from: start, to: end }. from and to arguments should be in the order returned by an unbounded Token.all() call. See Range examples.The Set only includes documents in this range (inclusive). Omit from or to to run unbounded range searches.If a range is omitted, all tokens are returned. | ### [](#range-parameters)Range parameters | Name | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | from | Any | | Beginning of the range (inclusive). Must be an Token document. | | to | Any | | End of the range (inclusive). Must be an Token document. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Token documents in the provided range. If a range is omitted, all tokens are returned.The Set is empty if:The database has no tokens.There are no tokens in the provided range.The provided range’s from value is greater than to. | ## [](#examples)Examples ### [](#range)Range examples 1. Get all tokens for the database: ```fql Token.all() ``` ``` { data: [ { id: "123", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("111") }, { id: "456", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("222") }, { id: "789", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("333") } ] } ``` 2. Given the previous Set, get all tokens starting with ID `456` (inclusive): ```fql Token.all({ from: Token.byId("456") }) ``` ``` { data: [ { id: "456", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("222") }, { id: "789", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("333") } ] } ``` 3. Get a Set of tokens from ID `456` (inclusive) to `789` (inclusive): ```fql Token.all({ from: Token.byId("456"), to: Token.byId("789") }) ``` ``` { data: [ { id: "456", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("222") }, { id: "789", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("333") } ] } ``` 4. Get a Set of tokens up to ID `789` (inclusive): ```fql Token.all({ to: Token.byId("456") }) ``` ``` { data: [ { id: "123", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("111") }, { id: "456", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("222") } ] } ``` # `Token.byDocument()` | Learn: Tokens | | --- | --- | --- | Get a [token](../../../../learn/security/tokens/) by its [identity document](../../../../learn/security/tokens/#identity-document). ## [](#signature)Signature ```fql-sig Token.byDocument(document: { *: Any }) => Set ``` ## [](#description)Description Gets a [token](../../../../learn/security/tokens/), represented as a [`Token` document](../), by its [identity document](../../../../learn/security/tokens/#identity-document). An identity document can have multiple tokens. A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | document | Object | true | Identity document for the token to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Resolved reference to a Token document. | ## [](#examples)Examples ```fql Token.byDocument(Customer.byId("111")) ``` ``` { data: [ { id: "371233004820889634", coll: Token, ts: Time("2099-07-25T14:10:32.165Z"), document: Customer("111") }, ... ] } ``` # `Token.byId()` | Learn: Tokens | | --- | --- | --- | Get a [token](../../../../learn/security/tokens/) by its [document `id`](../../../../learn/data-model/documents/#meta). ## [](#signature)Signature ```fql-sig Token.byId(id: ID) => Ref ``` ## [](#description)Description Gets a [token](../../../../learn/security/tokens/), represented as an [`Token` document](../), by its [document `id`](../../../../learn/data-model/documents/#meta). A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | id | String | true | ID of the Token document to retrieve. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Ref | Resolved reference to the Token document. Can resolve to an existing document or a NullDoc. | ## [](#examples)Examples ```fql Token.byId("371233004820889634") ``` ``` { id: "371233004820889634", coll: Token, ts: Time("2099-07-25T14:10:32.165Z"), document: Customer("111") } ``` # `Token.create()` | Learn: Tokens | | --- | --- | --- | Create a [token](../../../../learn/security/tokens/) without a credential or related password. ## [](#signature)Signature ```fql-sig Token.create(data: { id: ID | Null, document: { *: Any } | Null, ttl: Time | Null, data: { *: Any } | Null }) => Token ``` ## [](#description)Description Creates a [token](../../../../learn/security/tokens/) that’s tied to an [identity document](../../../../learn/security/tokens/#identity-document) without a credential or related password. This method is useful for creating tokens for servers, services, and other non-user identities. A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ### [](#create-token-with-a-credential)Create token with a credential To create a token with a credential and related password, use [`credential.login()`](../../credential/login/) instead. You typically use [`credential.login()`](../../credential/login/) to create and use tokens as part of a Fauna-based [end-user authentication system](../../../../build/tutorials/auth/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Document fields for the new Token document.For supported document fields, see Token collection. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Token | The new Token document. | ## [](#examples)Examples ```fql Token.create({ document: Customer.byId("111") }) ``` ``` { id: "401671202234433613", coll: Token, ts: Time("2099-06-25T13:32:39.240Z"), document: Customer("111"), secret: "fn..." } ``` # `Token.firstWhere()` | Learn: Tokens | | --- | --- | --- | Get the first [token](../../../../learn/security/tokens/) that matches a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Token.firstWhere(pred: (Token => Boolean)) => Token | Null ``` ## [](#description)Description Gets the first [token](../../../../learn/security/tokens/), represented as a [`Token` document](../), that matches a provided [predicate function](../../../fql/functions/#predicates). A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts a Token document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns the first Token document for which the predicate returns true. | ## [](#return-value)Return value One of: | Type | Description | | --- | --- | --- | --- | | Token | First Token document that matches the predicate. | | Null | No Token document matches the predicate. | ## [](#examples)Examples ```fql Token.firstWhere(.document.id == "111") ``` ``` { id: "401670938431586381", coll: Token, ts: Time("2099-06-25T13:28:27.660Z"), document: Customer("111") } ``` # `Token.toString()` | Learn: Tokens | | --- | --- | --- | Get `"Token"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig Token.toString() => String ``` ## [](#description)Description Returns the name of the [`Token` collection](../) as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "Token" | ## [](#examples)Examples ```fql Token.toString() ``` ``` "Token" ``` # `Token.where()` | Learn: Tokens | | --- | --- | --- | Get a Set of [tokens](../../../../learn/security/tokens/) that match a provided [predicate](../../../fql/functions/#predicates). ## [](#signature)Signature ```fql-sig Token.where(pred: (Token => Boolean)) => Set ``` ## [](#description)Description Gets a Set of [tokens](../../../../learn/security/tokens/), represented as [`Token` documents](../), that match a provided [predicate function](../../../fql/functions/#predicates). A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). If `Token.where()` is the last expression in a query, the first page of the `Set` is returned. See [Pagination](../../../../learn/query/pagination/). ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | pred | Predicate function | Yes | Anonymous predicate function that:Accepts an Token document as its only argument. Supports shorthand-syntax.Returns a Boolean value.The method returns a Set of Token documents for which the predicate returns true. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Set | Set of Token documents that match the predicate. If there are no matching documents, the Set is empty. | ## [](#examples)Examples ```fql Token.where(.document.id == "111") ``` ``` { data: [ { id: "401670938431586381", coll: Token, ts: Time("2099-08-14T23:54:00.750Z"), document: Customer("111") }, ... ] } ``` # `token.delete()` | Learn: Tokens | | --- | --- | --- | Delete a [token](../../../../learn/security/tokens/). ## [](#signature)Signature ```fql-sig delete() => NullToken ``` ## [](#description)Description Deletes a [token](../../../../learn/security/tokens/), represented as a [`Token` document](../). A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | NullToken | Document doesn’t exist. See NullDoc. | ## [](#examples)Examples ```fql Token.byId("401671202234433613")!.delete() ``` ``` Token("401671202234433613") /* deleted */ ``` # `token.exists()` | Learn: Tokens | | --- | --- | --- | Test if a [token](../../../../learn/security/tokens/) exists. ## [](#signature)Signature ```fql-sig exists() => true ``` ## [](#description)Description Tests if a [token](../../../../learn/security/tokens/), represented as an [`Token` document](../), exists. A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Boolean | If true, the Token document exists. If false, the Token document doesn’t exist. | ## [](#examples)Examples ```fql Token.byId("401671202234433613")!.exists() ``` ``` true ``` # `token.replace()` | Learn: Tokens | | --- | --- | --- | Replace a [token](../../../../learn/security/tokens/). ## [](#signature)Signature ```fql-sig replace(data: { *: Any }) => Token ``` ## [](#description)Description Replaces all fields in a [token](../../../../learn/security/tokens/), represented as a [`Token` document](../), with fields from a provided data object. Fields not present in the data object, excluding the `id`, `coll`, and `ts` metadata fields, are removed. A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. Fauna stores tokens as documents in the [`Token` system collection](../). ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | | Fields for the Token document. Fields not present, excluding the id, coll, and ts metadata fields, in the object are removed.For supported document fields, see Token collection.The object can’t include the following metadata fields:idcollts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Token | Token document with replaced fields. | ## [](#examples)Examples ```fql Token.byId("401670938431586381")!.replace({ document: Customer.byId("222") }) ``` ``` { id: "401670938431586381", coll: Token, ts: Time("2099-07-28T03:24:23.810Z"), document: Customer("222") } ``` # `token.update()` | Learn: Tokens | | --- | --- | --- | Update a [token](../../../../learn/security/tokens/). ## [](#signature)Signature ```fql-sig update(data: { *: Any }) => Token ``` ## [](#description)Description Updates a [token](../../../../learn/security/tokens/)'s metadata or [identity document](../../../../learn/security/tokens/#identity-document) represented as an [`Token` document](../), with fields from a provided data object. During the update, fields from the data object are copied to the document, creating new fields or updating existing fields. The operation is similar to a merge. A token is a type of [authentication secret](../../../../learn/security/authentication/#secrets) used to provide identity-based access to a Fauna database. ### [](#nested-fields)Nested fields Fields with nested objects in the data object are merged with the identically named nested object in the document. ### [](#remove-a-field)Remove a field To remove a document field, set its value in the data object to `null`. ### [](#metadata-fields)Metadata fields You can’t use this method to insert or edit the following [metadata fields](../../../../learn/data-model/documents/#meta): * `id` * `coll` * `ts` ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | data | Object | true | Document fields for the Token document.For supported document fields, see Token collection.The object can’t include the following metadata fields:* id * coll * ts | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Token | The updated Token document. | ## [](#examples)Examples ```fql Token.byId("401670938431586381")!.update({ data: { clientIpAddr: "123.123.12.1" } }) ``` ``` { id: "401670938431586381", coll: Token, ts: Time("2099-07-28T03:21:08.580Z"), document: Customer("111"), data: { clientIpAddr: "123.123.12.1" } } ``` # TransactionTime [TransactionTime](../../fql/types/#transactiontime) methods and properties. ## [](#description)Description [TransactionTime](../../fql/types/#transactiontime) methods are provided to represent an instantaneous query transaction time. ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | TransactionTime() | Get the query transaction time. | | TransactionTime.toString() | Get "[transaction time]" as a String. | # `TransactionTime()` Get the query transaction time. ## [](#signature)Signature ```fql-sig TransactionTime() => TransactionTime ``` ## [](#description)Description The [TransactionTime](../../../fql/types/#transactiontime) is a placeholder that is set when the query is committed. If the query doesn’t write, it is equivalent to the query snapshot time, [`Time.now()`](../../time/now/). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | TransactionTime | ISO 8601 time value. | ## [](#examples)Examples This example shows the transaction time, `ts`, is the `TransactionTime()`. ```fql let doc = Customer.create({ name: "John Doe", email: "jdoe@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }) [doc, doc.ts == TransactionTime()] ``` ``` [ { id: "412735829984673869", coll: Customer, ts: Time("2024-10-25T16:40:10.525Z"), cart: null, orders: "hdWCxmVPcmRlcoHKhGpieUN1c3RvbWVygcZidjD09oHNSgW6VQz0UABNBAD2wYIaZxvJ6hofSt1AEA==", name: "John Doe", email: "jdoe@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }, true ] ``` # `TransactionTime.toString()` Get `"[transaction time]"` as a [String](../../../fql/types/#string). ## [](#signature)Signature ```fql-sig TransactionTime.toString() => String ``` ## [](#description)Description Returns the name of the [TransactionTime](../../../fql/types/#transactiontime) module as a [String](../../../fql/types/#string). ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | String | "[transaction time]" | ## [](#examples)Examples ```fql TransactionTime().toString() ``` ``` "[transaction time]" ``` # Global functions FQL utility functions. ## [](#description)Description The global functions aid application development and debugging and provide added database query functionality. ## [](#static-methods)Static methods | Method | Description | | --- | --- | --- | --- | | abort() | End the current query and return an abort error with a user-defined abort value. | | dbg() | Output a debug message in the query summary and return the message in the query results. | | ID() | Create a valid ID | | log() | Output a log message in the query summary and return null. | | newId() | Get a unique string-encoded 64-bit integer. | # `abort()` End the current query and return an [abort error](#error) with a user-defined `abort` value. ## [](#signature)Signature ```fql-sig abort(return: Any) => Never ``` ## [](#description)Description `abort()` lets you intentionally return an abort error in an FQL query or UDF. You can pass a user-defined return value to `abort()`. For example, in a UDF: ```fsl function checkout(orderId, status, payment) { ... // Abort the query if its calls `checkout()` with a // `status` other than `processing`. if (status != "processing") { // `Abort()` accepts a user-defined return value. // The value can be of any FQL type. abort("Cannot call checkout with status other than processing.") } } ``` Calling `abort()` ends the current query, including all expressions in query, and returns an [abort error](#error). Changes made before the `abort()` call are discarded. ### [](#error)Abort errors Abort errors use the `abort` error code and include the user-defined return value in the [Query HTTP API endpoint](../../../http/reference/core-api/#operation/query)'s `error.abort` response body property: ```json { "error": { "code": "abort", "message": "Query aborted.", "abort": "\"Cannot call checkout with status other than processing.\"" }, ... } ``` The return value is encoded to JSON using the [data format](../../../http/reference/wire-protocol/#formats) specified in the `X-Format` header. Fauna’s client drivers include classes for abort errors: * JavaScript driver: [`AbortError`](https://fauna.github.io/fauna-js/latest/classes/AbortError.html) * Python driver: [`AbortError`](https://fauna.github.io/fauna-python/latest/api/fauna/errors/errors.html#AbortErrores) * Go driver: [`ErrAbort`](https://pkg.go.dev/github.com/fauna/fauna-go/v2#ErrAbort) * .NET/C# driver: [`AbortException`](https://fauna.github.io/fauna-dotnet/latest/class_fauna_1_1_exceptions_1_1_abort_exception.html) * JVM driver: [`AbortException`](https://fauna.github.io/fauna-jvm/latest/com/fauna/exception/AbortException.html) ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | return | Any | true | User-defined value returned in the error.abort property of abort error responses.The return value is encoded to JSON using the data format specified in the Query HTTP API request's X-Format header. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Never | abort() never returns a value. Queries that call abort() always return an abort error, not query results. | ## [](#examples)Examples This simple example shows how to abort a query. Create a document in the collection and abort the query: ```fql Customer.create({ name: "John Doe", email: "jdoe@example.com", address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }) abort("Discard") ``` ``` abort: Query aborted. error: Query aborted. at *query*:12:6 | 12 | abort("Discard") | ^^^^^^^^^^^ | ``` Run `Customer.all()` to verify that a customer with the last name of Jones wasn’t added. The following example creates an anonymous function, which aborts when called without a valid email argument: ```fql let createCustomer = (email) => { if (email.length <= 0) { abort({ code: "invalid_email", message: "user email must be non-empty" }) } Customer.create({ name: "Jane Doe", email: email, address: { street: "87856 Mendota Court", city: "Washington", state: "DC", postalCode: "20220", country: "US" } }) } createCustomer("fake@example.com") createCustomer("") ``` ``` abort: Query aborted. error: Query aborted. at *query*:3:10 | 3 | abort({ | __________^ 4 | | code: "invalid_email", 5 | | message: "user email must be non-empty" 6 | | }) | |______^ | at *query*:22:15 | 22 | createCustomer("") | ^^^^ | ``` The first call to `createCustomer()` succeeds. The second call fails because a valid email argument isn’t included, which triggers the `abort()` action. The response message is the notification response. Notice that the query runs all the statements included in the query. # `dbg()` Output a [debug message](../../../http/reference/query-summary/#debug) in the [query summary](../../../http/reference/query-summary/) and return the message in the query results. ## [](#signature)Signature ```fql-sig dbg(value: A) => A ``` ## [](#description)Description The `dbg()` (debug) method outputs a provided message in the [summary](../../../http/reference/query-summary/) of query responses and returns the message in the query result. In the summary, debug messages are annotated as `info`. ### [](#dbg-and-log)`dbg()` and `log()` [`dbg()`](./) is similar to [`log()`](../log/) except that `dbg()` returns its message in the actual query result. You can use [`dbg()`](./) inline within method calls for debugging. ### [](#debug-message-template)Debug message template The debug message template is: ``` info: at **:: | | dbg() | ^^^^^^^^^^^ | ``` where: | Field | Description | | --- | --- | --- | --- | | | Message source.One of: SourceDescriptionqueryThe dbg() call occurred in the main query body.udf:The dbg() call occurred in the user-defined function named | Source | Description | query | The dbg() call occurred in the main query body. | udf: | The dbg() call occurred in the user-defined function named | | Source | Description | | query | The dbg() call occurred in the main query body. | | udf: | The dbg() call occurred in the user-defined function named | | | Line number where dbg() is used. | | | Character offset in where dbg() is used. | | | String-serialized message. | ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | value | Any | true | Value to output to the query summary and query results. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Any | Returns value. | ## [](#examples)Examples ### [](#basic-example)Basic example The following FQL query uses [`dbg()`](./) within a [`collection.create()`](../../collection/instance-create/) call: ```fql let x = "key limes" Product.create( // `dbg()` outputs its message. In this case, // it outputs a struct containing the `name` // and `stock` properties. dbg({ name: "#{x}", stock: 1 + 2 + 3, }) ) ``` The query as a [Query endpoint](../../../http/reference/core-api/#operation/query) request: ```bash curl -X POST \ 'https://db.fauna.com/query/1' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -H 'X-Format: tagged' \ -d '{ "query": "let x = \"key limes\"\n\nProduct.create(\n dbg({\n name: \"#{x}\",\n stock: 1 + 2 + 3,\n })\n)" }' ``` The message is included in the query results in `data`. The `summary` includes the query lines that called `dbg()`: ``` { "data": { "@doc": { "id": "413921254218661965", "coll": { "@mod": "Product" }, "ts": { "@time": "2099-11-07T18:41:59.173Z" }, "name": "key limes", "stock": { "@int": "6" } } }, "static_type": "Product", "summary": "info: { name: \"key limes\", stock: 6 }\nat *query*:4:6\n |\n4 | dbg({\n | ______^\n5 | | name: \"#{x}\",\n6 | | stock: 1 + 2 + 3,\n7 | | })\n | |____^\n |", ... } ``` When unescaped, the response’s `summary` renders as: ``` info: { name: "key limes", stock: 6 } at *query*:4:6 | 4 | dbg({ | ______^ 5 | | name: "#{x}", 6 | | stock: 1 + 2 + 3, 7 | | }) | |____^ | ``` ### [](#output-a-field-value)Output a field value ```fql Product.create({ name: "debug1", stock: dbg(1 + 2 + 3), }) ``` ``` info: 6 at *query*:3:13 | 3 | stock: dbg(1 + 2 + 3), | ^^^^^^^^^^^ | { id: "394873023799230528", coll: Product, ts: Time("2099-04-11T12:38:31.050Z"), name: "debug1", stock: 6 } ``` ### [](#output-an-object)Output an object ```fql Product.create( dbg({ name: "debug2", stock: 1 + 2 + 3, }) ) ``` ``` info: { name: "debug2", stock: 6 } at *query*:2:6 | 2 | dbg({ | ______^ 3 | | name: "debug2", 4 | | stock: 1 + 2 + 3, 5 | | }) | |____^ | { id: "394873104675897408", coll: Product, ts: Time("2099-04-11T12:39:48.180Z"), name: "debug2", stock: 6 } ``` ### [](#output-a-document)Output a document ```fql dbg( Product.create({ name: "debug3", stock: 1 + 2 + 3, }) ) ``` ``` info: { id: ID("394873211262599234"), coll: Product, ts: TransactionTime(), name: "debug3", stock: 6 } at *query*:1:4 | 1 | dbg( | ____^ 2 | | Product.create({ 3 | | name: "debug3", 4 | | stock: 1 + 2 + 3, 5 | | }) 6 | | ) | |_^ | { id: "394873211262599234", coll: Product, ts: Time("2099-04-11T12:41:29.835Z"), name: "debug3", stock: 6 } ``` ## [](#see-also)See also [`log()`](../log/) [Query summary](../../../http/reference/query-summary/) # `ID()` Create a valid [ID](../../../fql/types/#id) ## [](#signature)Signature ```fql-sig ID(id: String) => ID ID(id: Number) => ID ``` ## [](#description)Description The `ID()` method returns a valid [ID](../../../fql/types/#id) given a [String](../../../fql/types/#string) or [Int](../../../fql/types/#int) representation of the ID. ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | id | String or Int | true | Document identifier. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | ID | Resource identifier. | ## [](#examples)Examples ```fql ID(123) ``` ``` "123" ``` ```fql ID("123") ``` ``` "123" ``` ## [](#see-also)See also [`collection.create()`](../../collection/instance-create/) # `log()` Output a [log message](../../../http/reference/query-summary/#log) in the [query summary](../../../http/reference/query-summary/) and return `null`. ## [](#signature)Signature ```fql-sig log(args: ...Any) => Null ``` ## [](#description)Description The `log()` method outputs `args` containing a message to the [summary](../../../http/reference/query-summary/) of query responses. In the summary, log messages are annotated as `info`. [`log()`](./) is similar to `console.log()` or `print()` in other programming languages. ### [](#log-and-dbg)`log()` and `dbg()` [`log()`](./) is similar to [`dbg()`](../dbg/) except that `log()` does not return its message in the query results. ### [](#log-message-template)Log message template The log message template is: ``` info at **:: ``` where: | Field | Description | | --- | --- | --- | --- | | | Message source.One of: SourceDescriptionqueryThe log() call occurred in the main query body.udf:The log() call occurred in the user-defined function named | Source | Description | query | The log() call occurred in the main query body. | udf: | The log() call occurred in the user-defined function named | | Source | Description | | query | The log() call occurred in the main query body. | | udf: | The log() call occurred in the user-defined function named | | | Line number where log() is used. | | | String-serialized message. | ## [](#parameters)Parameters | Parameter | Type | Required | Description | | --- | --- | --- | --- | --- | --- | | args | Any | | Values to output to the query summary. Supports interpolated strings containing FQL variables. | ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | Null | After output, the args are discarded. | ## [](#examples)Examples The following FQL query logs several `summary` messages: ```fql log("Before assignment") let x = 5 let y = { lat: 37.5542782, long: -122.3007394 } log("After assignment x=#{x}") log(y) x ``` The query as a [Query endpoint](../../../http/reference/core-api/#operation/query) request: ```bash curl -X POST \ 'https://db.fauna.com/query/1' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -H 'X-Format: tagged' \ -d '{ "query": "log(\"Before assignment\")\nlet x = 5\nlet y = { lat: 37.5542782, long: -122.3007394 }\nlog(\"After assignment x=#{x}\")\nlog(y)\nx\n" }' ``` Unlike [`dbg()`](../dbg/), [`log()`](./) does not return a value. The message is excluded from the query results in `data`. The `summary` includes the query lines that called `log()`: ``` { "data": { "@int": "5" }, "static_type": "5", "summary": "info at *query*:1: Before assignment\n\ninfo at *query*:4: After assignment x=5\n\ninfo at *query*:5: { lat: 37.5542782, long: -122.3007394 }", ... } ``` When unescaped, the response’s `summary` renders as: ``` "info at *query*:1: Before assignment info at *query*:4: After assignment x=5 info at *query*:5: { lat: 37.5542782, long: -122.3007394 } ``` ## [](#see-also)See also [`dbg()`](../dbg/) [Query summary](../../../http/reference/query-summary/) # `newId()` Get a unique string-encoded 64-bit integer. ## [](#signature)Signature ```fql-sig newId() => ID ``` ## [](#description)Description The `newId()` method returns a number that is guaranteed to be unique across all databases and is suitable for constructing the document ID part of a document reference. Document IDs are generated using the [Twitter Snowflake algorithm](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake). The IDs are based on time instead of sequential numbers and are generally increasing. The `newId()` method shouldn’t be used to generate random numbers. ## [](#parameters)Parameters None ## [](#return-value)Return value | Type | Description | | --- | --- | --- | --- | | ID | Numeric value that is unique across databases. | ## [](#examples)Examples ```fql newId() ``` ``` "374494810266927169" ``` ## [](#see-also)See also [`collection.create()`](../../collection/instance-create/)