Documents

Reference: Document

You add data to Fauna as JSON-like objects called documents. A document is a single, changeable record in a Fauna database. Each document belongs to a collection.

All user data is stored in documents, and every entity in the Fauna data model, including Database, Collection, and Function, is defined in a document.

Storing data in documents instead of rows and columns gives you greater flexibility. It allows you to shape your data in the way that best fits your applications instead of writing your applications to fit the data. Every record in a Fauna database is grouped and stored as a Document object, consisting of key:value pairs. A key can be a document.

Data stored in a document looks similar to a JSON document and can include Strings, Integers, Arrays, and other FQL data types. Documents include:

  • a timestamp

  • the name of their collection

  • a string-encoded integer used as a document ID.

Documents changes create a new version of the document, which supports temporal querying.

See the Global limits for more information on document size and query limits.

Document type

A document’s data type is taken from its collection’s name. For example, Product for a document in the Product collection. This type is an instance of the Document type, which is a subtype of the Object type.

You define the structure of a collection’s document type using the collection schema’s:

See Document type definitions

Document metadata

All documents have these common metadata fields:

  • Documents have a string-encoded 64-bit integer identifier. A document ID is a compound value of a collection identifier and a unique document ID. The ID is a unique identifier for the document in the scope of the database where it is stored.

  • When a document is updated, a new version is stored. User documents have a timestamp that identifies the most recent document update. Documents are versioned, and the versions are distinguished using a timestamp. When a query doesn’t specify a timestamp, the latest version of the document is used. The timestamp is returned in the document ts field.

  • The ts field shouldn’t be directly manipulated. To track timestamps independent of Fauna operations, include fields that are under your control in your documents to record timestamps.

  • data is 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.

  • Documents have an optional ttl (time-to-live) field that indicates when the document should be removed. See Document time-to-live (TTL).

CRUD operations on documents

Every document object has the following methods:

Method Description

Deletes the document, returning the id and coll in an object.

Tests if a given document exists.

Fully replaces the document data with the provided data. Fields are removed if they aren’t present in the provided data.

Updates the document with the provided data and returns the updated document. This does a patch update. Omitted fields are left as-is. To remove fields from a document, set the field value to null.

Document references

You can use document references to model relationships between documents, including documents in other collections.

// Get a `Category` collection document.
let produce = Category.byName("produce").first()

// Create a `Product` document that references
// the `Category` document.
Product.create({
  name: "key lime",
  description: "Organic, 1 ct",
  price: 79,
  // The `category` field includes a reference to
  // the `Category` document as a field value.
  category: produce,
  stock: 2000
})
See Model relationships using document references

NullDocs

A NullDoc is a marker used to indicate that a document doesn’t exist or is inaccessible.

A NullDoc’s data type is taken from its collection’s name. For example, a NullDoc for a Product collection document is NullProduct.

NullDocs coalesce as a null value. Testing a NullDoc against a value of null returns true.

Several FQL methods, such as collection.byId(), return a NullDoc for missing or inaccessible documents:

// Attempts to access a `Product` collection document
// with an `id` of `12345`. In this
// example, the document doesn't exist.
Product.byId("12345")
// Returns a `NullProduct` value.
Product("12345") /* not found */

Dangling references

Documents may contain references to Nulldocs — documents that don’t exist. These are called dangling references. For example:

// Gets a `Product` collection document.
// Use projection to return `name`, `description`, and `category` fields.
Product.byId("111") {
  name,
  description,
  // The `category` field contains a reference to a `Category` collection document.
  category
}
{
  name: "cups",
  description: "Translucent 9 Oz, 100 ct",
  // If the referenced `Category` collection document doesn't exist,
  // the projection returns a NullDoc.
  category: Category("123") /* not found */
}

Check for a document’s existence

User-defined collection documents and system collection documents have an exists() method to test whether a referenced document exists. For example:

// Checks if a `Product` collection
// document with an ID of `111` exists.
Product.byId("111").exists()  // true

// If the document doesn't exist,
// `exists()` returns `false`.
Product.byId("999").exists()  // false

exists() vs. null comparisons

You can use either exists() or a null comparison (== null or != null) to check the existence or validity of a value. For example:

Product.byId("111").exists()  // true

Product.byId("111") != null   // true

Key differences:

  • exists() returns an error if called on an unsupported value.

  • Null comparisons do not throw errors and work safely on any value.

For example:

// Declare an object. Objects don't support
// an `exists()` method.
let object = { a: "Foo", b: "Bar" }

object.exists()  // Returns `invalid_query` error

object != null   // Returns true
\