Get unique field values

This guide covers how to best get unique values for a field from a set of documents.

As an example, the guide shows you how to get unique name field values from Product collection documents. An example of a Product document:

{
  id: "<DOCUMENT_ID>",
  coll: Product,
  ts: Time("2099-07-05T13:00:11.200Z"),
  name: "cups",
  description: "Translucent 9 Oz, 100 ct",
  price: 6.98,
  quantity: 90,
  store: Store("402575128544673858"),
  backorderLimit: 5,
  backordered: false
}

Define an index that covers the field

Add the field as an index value in an index definition:

collection Product {
  ...
  // Defines the `sortedByPriceLowToHigh()` index.
  // The index includes the `name` field as an index value.
  // The index can include `terms` and other `values`.
  index sortedByPriceLowToHigh {
    values [.price, .name, .description]
  }
}

Using an index improves performance and reduces costs by avoiding the need to read each document individually.

Extract unique values in a small set

If your set contains fewer than 16,000 documents, you can use an FQL query to get unique values for the field. In the query:

  • Use map() to iterate through each Product collection document.

  • Use toArray() to convert field values to an array.

  • Call distinct() to return a deduplicated array containing only unique elements.

  • Optionally, call order() to sort the deduplicated array.

// Uses `map()` to return a set of `name` field values
// from `Product` collection documents.
Product.sortedByPriceLowToHigh().map(doc => doc.name)
  // `toArray()` converts the set to an array.
  .toArray()
  // `distinct()` returns a deduplicated array.
  .distinct()
  // (Optional) `order()` sorts the deduplicated array.
  .order()
[
  "avocados",
  "cilantro",
  "cups",
  "limes",
  "pinata",
  "pizza"
]

Extract unique values in a large set

If your set contains 16,000 or more documents, the previous query would require pagination. distinct() would only be able to extract unique elements from each page of results.

Instead, it’s more efficient to retrieve all field values and process them on the client side. For example, using Fauna’s JavaScript client:

// Uses `map()` and `pageSize() to get the `name` field values
// of all `Product` collection documents in batches of 500.
const query = fql`Product.sortedByPriceLowToHigh()
  .map(doc => doc.name)
  .pageSize(500)`

const iter = client.paginate(query)

// In JavaScript, a `Set` object only stores unique values.
const names = new Set()
for await (const name of iter.flatten()) {
  names.add(name)
}

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!