Check out v4 of the Fauna CLI

v4 of the Fauna CLI is now in beta.

The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start.

Sets

Reference: Set

A Set is an FQL data type that contains an iterable, unbounded group of values. You typically fetch documents from a collection as a Set.

Get a Set of collection documents

You can fetch a Set of documents from a collection by calling a collection instance method that returns a Set. For example, you can call an index to get a filtered list of documents:

// Uses the `Product` collection's `sortedByPriceLowToHigh()`
// index to get `Product` documents with a
// `price` greater than or equal to `199` ($1.99):
Product.sortedByPriceLowToHigh({ from: 1_99 })
{
  // Returns matching `Product` documents as a Set:
  data: [
    {
      id: "777",
      coll: Product,
      ts: Time("2099-08-20T18:18:47.100Z"),
      name: "limes",
      description: "Conventional, 16 oz bag",
      // $2.99 in cents
      price: 299,
      stock: 30,
      category: Category("789")
    },
    ...
  ]
}

Transform Sets with Set instance methods

You can use set instance methods to transform a fetched Set. For example, you can:

// Uses the`Product` collection's `sortedByPriceLowToHigh()`
// index and `where()` to get `Product` collection documents with:
// - A `price` greater than or equal to `1_99` ($1.99)
// - A `stock` greater than `50`
Product.sortedByPriceLowToHigh({ from: 1_99 }).where(.stock > 50)
Reference: Set instance methods

Set operations

You can use set instance methods to perform SQL-like set operations, such as unions, joins, and intersections, in FQL. For examples, see Work with multiple Sets.

See Work with multiple Sets

Pagination

Fauna automatically paginates result Sets with 16 or more elements. When a query returns paginated results, Fauna materializes a subset of the Set with an after pagination cursor:

// Uses the `Product` collection's `sortedByPriceLowToHigh()` index to
// return all `Product` documents.
// The collection contains more than 16 documents.
Product.sortedByPriceLowToHigh()
{
  // The result Set contains 16 elements.
  data: [
    {
      id: "555",
      coll: Product,
      ts: Time("2099-07-30T15:57:03.730Z"),
      name: "single lime",
      description: "Conventional, 1 ct",
      price: 35,
      stock: 1000,
      category: Category("789")
    },
    {
      id: "888",
      coll: Product,
      ts: Time("2099-07-30T15:57:03.730Z"),
      name: "cilantro",
      description: "Organic, 1 bunch",
      price: 149,
      stock: 100,
      category: Category("789")
    },
    ...
  ],
 // Use the `after` cursor to get the next page of results.
  after: "hdW..."
}

To get the next page of results, pass the after cursor to Set.paginate(). To change the default page size, use set.pageSize().

See Pagination

Set references

Sets are not persistable. You can’t store a Set as a field value or create a field definition that accepts a Set.

Instead, you can use a computed field to define a read-only function that dynamically fetches a Set:

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<Order> = ( customer => Order.byCustomer(customer))
  ...
}

If the field isn’t projected, it contains an after pagination cursor that references the Set:

// 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:

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():

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: {}
    },
    ...
  ]
}

Sets vs. Arrays

While both are iterable, Sets differ from FQL arrays as follows:

Difference Set Array

Purpose

Typically represents a dynamic and potentially large Set of documents from a collection.

Represents a fixed sequence of known values. Limited to 16,000 elements.

Order

Unordered. You order Sets using indexes and set instance methods. Elements don’t have index numbers.

Ordered. Each element has a specific index number.

Pagination

Result Sets are paginated. See Pagination.

Arrays are not paginated.

Persistable

Not persistable. A Set is dynamic and can’t reliably stored, retrieved, and updated in a Fauna database.

An Array of other persistable values is persistable.

Supported methods

Loading strategy

Some Set instance methods lazily load the Set. Other Set instance methods eagerly load the Set. Lazy-loading methods only return a result Set when the query forces the Set to be materialized.

All Array instance methods eagerly load and materialize the entire Array.

Interoperability between Sets and Arrays

For interoperability, most set instance methods have an equivalent array instance method (and the reverse).

You can use the set.toArray() and array.toSet() methods to cast between the Set and Array data types.

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!