FQL v4 will be decommissioned on June 30, 2025. Ensure that you complete your migration from FQL v4 to FQL v10 by that date. For more details, review the migration guide. Contact support@fauna.com with any questions. |
Migrate to FQL v10
See also: | v10 migration FAQ |
---|
FQL v10 is the latest version of FQL that simplifies the data model and provides a more powerful and flexible query language. FQL v10 is backward-compatible with FQL v4. You don’t have to change or migrate your data to use v10. You can incrementally transition v4 applications to v10.
This guide covers:
-
Notable changes between FQL v4 and v10
-
How to transition v4 applications to v10
Document improvements
FQL v10 includes the following improvements to documents:
Data field
FQL v10 improves developer experience by automatically projecting
user-defined fields as top-level fields of the documents. In v4, user-defined
fields are always nested in a document’s data
field.
This top-level projection of user-defined fields doesn’t change how the underlying document is structured or stored. The new document format is only presented when using the v10 interface. Your existing v4-based applications can continue to work with no changes.
FQL v10 and v4-based applications work on the same documents
concurrently without breaking each other. Your FQL v4 queries continue to
reference and write to fields nested in the data
field.
Metadata fields
In v10, all documents contain the following top-level metadata fields:
-
coll
: The name of the document’s collection -
id
: A string-encoded 64-bit integer identifier that’s unique to the document in the collection -
ts
: A timestamp of the latest write to the document
v10 documents can also include an optional ttl
timestamp. A document is
permanently deleted on its ttl
.
Avoid conflicts with reserved fields
In v10, data
and metadata field names are
reserved.
To avoid conflicts, you can use the following methods to create and modify documents that may contain reserved field names:
These methods safely nest values for fields with reserved names in the data
field. For example:
Test.createData({
data: {
foo: "bar"
}
})
Result:
{
id: "398154525228138529"
coll: Test,
ts: Time("2024-05-17T17:56:34.670Z"),
data: {
data: {
foo: "bar"
}
}
}
User-defined functions
You may want to migrate your v4 code incrementally by mixing v4 queries with v10 queries. You can use user-defined functions (UDFs) for this purpose.
You can call v4 UDFs from v10 FQL queries and vice versa. This lets you mix FQL v10 queries into a v4 application by encapsulating the v10 query in a UDF and calling that UDF in your v4 queries.
Calling v4 from v10 (or the other way around) is convenient for incremental migration. It is not recommended for long-term use. We recommend you migrate your UDFs to v10. The ability to call v4 UDFs in v10 is a temporary convenience provided to users as a means to incrementally migrate. When v4 reaches its end of life (EOL), you must migrate your UDFs to v10. |
Call a v4 UDF in a v10 query
To create a v4 UDF:
CreateFunction({
name: "Increment",
body: Query(Lambda("number", Add(1, Var("number"))))
})
To call the v4 UDF in a v10 query:
// Calls the v4 `Increment` UDF with the argument `1`
let num = Increment(1)
num
Call a v10 UDF in a v4 query
In v10, you can define UDFs using Fauna Schema Language (FSL):
function getOrdersByCustomer(name, status) {
Order.where(.customer.name == name && .status == status)
}
To call the v10 UDF in a v4 query:
// Calls the v10 `getOrdersByCustomer` UDF
Call('getOrdersByCustomer', 'Gregor Samsa')
Indexes
In v4, indexes were a top-level schema object, separate from collections. In v10, indexes are part of a collection’s schema.
To use a v4 index in FQL v10, wrap the indexed query in a v4 UDF, and call the UDF in FQL v10.
For example, if you have a v4 index named product_by_name
,
you can not call it directly in FQL v10.
You must first wrap the v4 product_by_name
index in a v4 UDF:
CreateFunction({
name: "productByName",
body: Query(
Lambda(
["name"],
Select(
"data",
Paginate(Match(Index("product_by_name"), Var("name")))
)
)
)
})
Then call the v4 productByName
UDF in a v10 query:
productByName("Apple Macbook Pro")
Similarly, FQL v10 indexes can’t be called directly from FQL v4 queries unless they are in a UDF.
Indexes in FQL v10 are full indexes whereas v4 indexes are sparse indexes.
For example, if you declared a v4 index with a value field foo
, in FQL v4
there is an entry in the index for every document that has a non-null foo
value. In FQL v10, all documents are indexed, including those that have a
null foo
value.
In FQL v4, terms and values treat arrays as a multi-valued attribute (MVA) such that when a term targets a document field or index binding result that is an array, one index entry per array item is created. In FQL v10, you must explicitly state that a term or a value is an MVA. See index definitions.
FQL v10 computed fields are generally equivalent to FQL v4 index binding, and are declared inside the collection instead of in the index. See computed field definitions.
Reserved words and field names
As described previously, the document metadata id
, coll
, and
ts
keywords are reserved. See
Reserved words. If your
existing documents use these field names, they’re nested in the data field of
your documents to avoid colliding with the FQL v10 reserved key names. For
example, notice how the id
field in the following FQL v4 document is nested
in data, avoiding collision on the reserved key name:
Reserved collection names
To avoid naming conflicts with system collections and system entities,
FQL v10 doesn’t allow you to name top-level entities, such as collections
and UDFs, with a reserved name. Where a user-defined collection or function
has a conflicting name, you can assign collections and UDFs an
alias
that makes that resource available in the FQL v10 environment. For example,
when migrating from FQL v4 with a Collection named Collection
, you must
add an alias to the collection to use it in their FQL v10 environment.
// adding an alias to a Collection named Collection
Collection.byName("Collection")!.update(
{
alias: "Products"
}
)
// using that collection in a subsequent query
Products.firstWhere(.name == "Hard Anodised 12 Kadhai")
Products.create(...)
If the original name is non-conflicting, the Collection/UDF is available as its name and as the aliased name. If it is conflicting, the Collection/UDF is available only under the aliased name.
Referenced collections
You can no longer delete a collection that is referenced by a Role
or Key
document. This is true of roles or keys created in v4 or v10. You must
reconfigure or remove the Role
or Key
and then delete the collection.
Security-related definitions
You must convert definitions for access providers and user-defined roles to v10 before the v4 EOL.
In v10, you typically define access providers and roles using Fauna Schema Language (FSL) schema.
Access providers
To convert a v4 access provider definition to v10, open the definition as FSL in the Fauna Dashboard and save the result.
User-defined roles
You can authorize v10 transactions using v4 roles. This lets you incrementally migrate v4 role definitions to v10.
You can’t use FQL v4 methods to create v10 role definitions. The structure of role definitions has changed significantly from v4 to v10.
Major differences are outlined below. For more information, see You should review the Role FSL schema documentation.
Role name
In v10, the role name must be a valid identifier.
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!