Quick start
In this quick start guide, you’ll:
-
Create a Fauna database with demo data.
-
Run Fauna Query Language (FQL) queries to read and write data.
-
Build an application that integrates with Fauna using a client driver.
Prefer to learn using a sample application? Check out the Fauna JavaScript sample app on GitHub. |
Before you start
Before starting this guide, you should be familiar with the concepts in the Overview.
Create a database
Set up a database with demo data.
-
Log in to the Fauna Dashboard. You can sign up for a free account at https://dashboard.fauna.com/register.
-
Create a database. When creating the database, enable demo data.
-
Navigate to the database in the Dashboard.
Read data
You use FQL queries to read data in a Fauna database. You can run FQL queries in the Dashboard Shell.
Get all collection documents
Fauna stores data as JSON-like documents in collections.
You can filter and fetch documents from a collection as a set, and iterate through each document.
Run the following FQL query to get all documents in the demo data’s Customer
collection. The query calls the
all()
method
on the Customer
collection:
// Calls `all()` on the `Customer` collection.
Customer.all()
The query returns a set of Customer
collection documents. Each document has a
64-bit id
that’s unique to the document within the collection.
{
data: [
{
// Document ID, generated on write.
id: "402336425554477133",
coll: Customer,
ts: Time("2099-07-02T21:46:05.720Z"),
firstName: "Alice",
lastName: "Appleseed",
email: "alice.appleseed@example.com",
address: {
street: "87856 Mendota Court",
city: "Washington",
state: "DC",
zipCode: "20220"
},
telephone: "208-346-0715",
creditCard: {
network: "Visa",
number: "4556781272473393"
}
},
...
]
}
Exact match search
For one-off queries, use
Collection.where()
to
filter documents using a
predicate:
// Runs an unindexed query.
Customer.where(.email == "alice.appleseed@example.com")
For better performance on large datasets, use an index with a term to run an exact match search. An index stores, or covers, specific document field values for quick retrieval.
You define indexes in an FSL collection schema. The
demo data includes a schema for the Customer
collection:
collection Customer {
// Unique constraint.
// Ensures a field value or combination of field values
// is unique for each document in the collection.
unique [.email]
// Definition for the `byEmail()` index.
// Use indexes to filter and sort documents
// in a performant way.
index byEmail {
// `terms` are document fields for exact match searches.
// In this example, you get `Customer` collection documents
// by their unique `email` field value.
terms [.email]
}
}
You call an index as a method on its collection:
// Uses the `Customer` collection's `byEmail()` index
// to run an exact match search on an `email` field value.
Customer.byEmail("alice.appleseed@example.com")
{
data: [
{
id: "402336425554477133",
coll: Customer,
ts: Time("2099-07-02T21:46:05.720Z"),
firstName: "Alice",
lastName: "Appleseed",
email: "alice.appleseed@example.com",
address: {
street: "87856 Mendota Court",
city: "Washington",
state: "DC",
zipCode: "20220"
},
telephone: "208-346-0715",
creditCard: {
network: "Visa",
number: "4556781272473393"
}
}
]
}
Sort data
You can use method chaining to call a method on the output of another method. Expressions are evaluated sequentially from left to right.
// Runs an unindexed query.
// Sorts `Product` collection documents by:
// - `price` (ascending), then ...
// - `name` (ascending), then ...
// - `description` (ascending).
Product.all().order(.price, .name, .description)
For better performance on large datasets, use an index with values to sort collection documents.
The demo data includes a schema for the Product
collection:
collection Product {
...
// Defines the `sortedByPriceLowToHigh()` index.
index sortedByPriceLowToHigh {
// `values` are document fields for sorting and range searches.
values [.price, .name, .description]
}
}
Call the index in a query:
// Uses the `Product` collection's `sortedByPriceLowToHigh()` index
// to sort `Product` collection documents by:
// - `price` (ascending), then ...
// - `name` (ascending), then ...
// - `description` (ascending).
Product.sortedByPriceLowToHigh()
Range search
For one-off queries, use
Collection.where()
to
filter documents:
// Runs an unindexed query.
// Get `Product` collection documents with a `price` between
// 10 and 100 (inclusive).
Product.where(.price >= 10 && .price <= 100)
.order(.price, .name, .description)
For better performance on large datasets, use an index with values to run range searches on collection documents:
// Get `Product` collection documents with a `price` between
// 10 and 100 (inclusive).
Product.sortedByPriceLowToHigh({ from: 10, to: 100 })
Project results
Projection lets you return only the specific fields you want from queries. Use projection to create smaller response payloads and decrease egress costs.
// Get only product names, descriptions, and prices
Product.sortedByPriceLowToHigh() {
name,
description,
price
}
{
data: [
{
name: "limes",
description: "Conventional, 1 ct",
price: 0.35
},
{
name: "cilantro",
description: "Organic, 1 bunch",
price: 1.49
},
...
]
}
Paginate results
Fauna automatically paginates sets with 16 or more
elements. Use pageSize()
to
change the maximum number of elements per page:
// Calls `pageSize()` with a size of `2`.
Product.sortedByPriceLowToHigh().pageSize(2) {
name,
description,
price
}
If a set is paginated and a subsequent page is available, the result includes an
after
cursor:
{
// The results contain two elements or fewer.
data: [
{
name: "limes",
description: "Conventional, 1 ct",
price: 0.35
},
{
name: "cilantro",
description: "Organic, 1 bunch",
price: 1.49
}
],
// Use the `after` cursor to get the next page of results.
after: "hdWCxmd..."
}
To get the next page of results, pass the after
cursor to
Set.paginate()
:
Set.paginate("hdWCxmd...")
The Fauna client drivers also include methods for automatically iterating through pages. See:
Write data
You also use FQL queries to write data to a Fauna database.
Create a document
Use create()
to create, or insert, a document in a collection:
// Calls `create()` on the `Customer` collection.
// Creates a `Customer` collection document.
Customer.create({
firstName: "John",
lastName: "Doe",
email: "jdoe@example.com"
})
If wanted, you can also provide a document id
. If you don’t provide an ID,
Fauna auto-generates one. Once assigned, the document ID is immutable and
can’t be changed.
Customer.create({
id: "12345",
firstName: "Jacob",
lastName: "Doe",
email: "jacob.doe@example.com"
})
Update a document
Use update()
to update a document:
// Declares a `customer` variable.
// 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("jdoe@example.com").first()
// Calls `update()` on the `Customer` collection document.
// `?.` safely calls `update()` only if `customer` contains
// a non-null value.
customer?.update({
// Updates the existing `firstName` field value.
firstName: "Jonathan",
// Adds new `age` field.
age: 42
})
To remove a field, set its value to null
:
let customer = Customer.byEmail("jdoe@example.com").first()
customer?.update({
// Removes the `age` field.
age: null
})
Replace a document
Use replace()
to replace a document:
let customer = Customer.byEmail("jdoe@example.com").first()
// Calls `replace()` on the `Customer` collection document.
customer?.replace({
firstName: "Jane",
lastName: "Doe",
email: "jane.doe@example.com"
})
Delete a document
Use delete()
to delete a document:
let customer = Customer.byEmail("jdoe@example.com").first()
// Calls `delete()` on the `Customer` collection document.
customer?.delete()
The query returns a NullDoc, which indicates the document no longer exists:
Customer("<DOCUMENT_ID>") /* deleted */
Bulk writes
Use forEach()
to iteratively update each document in a set:
// 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: {
state: "District of Columbia"
}
})) // `forEach()` returns `null`.
For more examples, see Bulk writes.
Document relationships
A document relationship establishes associations between documents. Fauna supports one-to-one, one-to-many, and many-to-many relationships between documents in different collections.
Create a relationship between documents
To create a document relationship, include the document as a field value:
// Uses the `Store` collection's `byName()`
// index to get the first store named `DC Fruits`.
let store = Store.byName("DC Fruits").first()
// Creates a `Product` collection document.
Product.create({
name: "limes",
description: "Organic, 2 ct",
price: 1.98,
quantity: 70,
// Adds the previous `Store` collection document as
// a `store` field value.
store: store,
backorderLimit: 5,
backordered: false
})
Traverse document relationships
You can project a field that contains a document to dynamically traverse the document relationship:
// Get product names, descriptions, and prices
Product.sortedByPriceLowToHigh() {
name,
description,
price,
store
}
{
data: [
{
name: "limes",
description: "Conventional, 1 ct",
price: 0.35,
// Traverses the `Store` collection document in
// the `store` field.
store: {
id: "402336425534554189",
coll: Store,
ts: Time("2099-07-02T21:46:05.720Z"),
name: "DC Fruits",
address: {
street: "13 Pierstorff Drive",
city: "Washington",
state: "DC",
zipCode: "20220"
}
}
},
{
name: "cilantro",
description: "Organic, 1 bunch",
price: 1.49,
store: {
id: "402336425534554189",
coll: Store,
ts: Time("2099-07-02T21:46:05.720Z"),
name: "DC Fruits",
address: {
street: "13 Pierstorff Drive",
city: "Washington",
state: "DC",
zipCode: "20220"
}
}
},
...
]
}
Create a key
Next, you’ll connect to Fauna using a client. To do this, you need a secret to authenticate with Fauna.
Fauna supports several secret types. For this quick start, create a key:
-
In the upper left pane of Dashboard’s Explorer page, click the demo database, and click the Keys tab.
-
Click Create Key.
-
Choose a Role of Server.
-
Click Save.
-
Copy the Secret Key, which is the key’s secret. The secret is scoped to the database.
Build an application
Next, create a basic application that integrates with Fauna using a Fauna client driver.
A client driver sends FQL queries and receives responses using your preferred programming language. The client deserializes query responses into the language’s corresponding data types.
-
Set the
FAUNA_SECRET
environment variable to your key’s secret. Fauna’s client drivers can access the secret from this variable.export FAUNA_SECRET=<KEY_SECRET>
-
Create a directory for the app and install the driver.
mkdir app cd app go mod init app go get github.com/fauna/fauna-go
mkdir app cd app npm install fauna
mkdir app cd app pip install fauna
The C# client library is currently in beta.
Navigate to your .NET or C# project directory and add the Fauna package to your project.
mkdir app cd app dotnet new console dotnet add package Fauna --prerelease
-
Create an
app.go
file and add the following code:Create an
app.mjs
file and add the following code:Create an
app.py
file and add the following code:Edit the
Program.cs
file and replace the code with the following:The application prints product data from the demo database.
-
Run the application:
go run app.go
node app.mjs
python app.py
dotnet run
The application prints the following:
[ { name: 'limes', description: 'Conventional, 1 ct', price: 0.35 }, ... { name: 'pinata', description: 'Original Classic Donkey Pinata', price: 24.99 } ]
[ {"name": "clear cups", "description": "Translucent 9 Oz, 100 ct", "price": 6.98}, ... {"name": "pinata", "description": "Giant Taco Pinata", "price": 23.99}, ]
[ { name: 'limes', description: 'Conventional, 1 ct', price: 0.35 }, ... { name: 'pinata', description: 'Original Classic Donkey Pinata', price: 24.99 } ]
[ { "name": "limes", "description": "Conventional, 1 ct", "price": 0.35 }, ... { "name": "pinata", "description": "Original Classic Donkey Pinata", "price": 24.99 } ]
Next steps
Congratulations! You’ve created a database, run some queries, and integrated Fauna with an application.
As a next step, try one of the following:
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!