Indexes
In working with Fauna, indexes are the primary way to query your documents. Aside from querying directly for documents by Reference (or just "Ref"), most Fauna database queries use an index in some way. This section of the documentation provides an introduction to indexes and how to use them to achieve specific development goals.
The source field
Every index has one or more source Collections. Once an index is active, any query that performs a write operation in the source collection(s) and meets the index criteria (if any) causes the index to be updated. To learn more about index criteria, see Terms and Values.
The following example creates an index on a collection named People:
{
ref: Index("all_people"),
ts: 1641932479200000,
active: true,
serialized: true,
name: 'all_people',
source: Collection("People"),
partitions: 8
}
An index can have more than one source collection. The following example demonstrates how to create an index with multiple source collections:
{
ref: Index("orders_and_products_by_name"),
ts: 1645051208160000,
active: false,
serialized: true,
name: 'orders_and_products_by_name',
source: [ Collection("orders"), Collection("products") ],
terms: [ { field: [ 'data', 'name' ] } ],
partitions: 1
}
| Indexes which cover multiple collections may be less performant than those which cover a single index. If possible, it’s a better practice to organize your collections and queries so that multi-collection indexes are not necessary. |
The Documents function
The simplest way to retrieve documents from a collection using no search
criteria is the Documents function. The following example uses
the Documents function to return documents in the People
collection. It passes a size parameter to the Paginate function
to limit results to the first three entries in the collection.
{
after: [ Ref(Collection("People"), "323794055850886656") ],
data: [
{
ref: Ref(Collection("People"), "323794055847739904"),
ts: 1645052924890000,
data: {
first: 'Alan',
last: 'Perlis',
age: 97,
degrees: [ 'BA', 'MA', 'PhD' ],
letter: 'A'
}
},
{
ref: Ref(Collection("People"), "323794055848788480"),
ts: 1645052924890000,
data: {
first: 'Alan',
last: 'Turing',
age: 107,
degrees: [ 'BA', 'MA', 'MS', 'PhD' ],
letter: 'B'
}
},
{
ref: Ref(Collection("People"), "323794055850885632"),
ts: 1645052924890000,
data: {
first: 'Grace',
last: 'Hopper',
age: 119,
degrees: [ 'BA', 'MA', 'PhD' ],
letter: 'C'
}
}
]
}
Terms
Including the terms field within an index allows you to specify one or
more document fields to be searchable within the index. For example,
consider a collection called People in which documents have fields
called first_name and last_name. If you include those fields in the
terms of an index on the People collection, you can run queries
which search for matches within those fields.
When a document is indexed, and all of the index’s defined terms
evaluate to null, no index entry is stored for the document.
See Index terms for more details.
Values
Including the values field within an index allows you to sort
documents according to the contents of specific document fields, and to
return specified field values to avoid the need to Get the
indexed document. If you need to sort query results from a collection
called People by the last_name field, you can include the
last_name field within the values definition of an index. Index
values can be ordered in either ascending or descending direction.
When a document is indexed, and all of the index’s defined values
evaluate to null, no index entry is stored for the document.
See Values for more details.
Uniqueness
Index definition documents have an optional unique field. If unique is
set to true, then for the index’s defined terms and values, each
document in the index must have unique values in the fields covered by
the terms and values. For example, if a field called name is included
in an index’s terms, each document must have a unique name field, and if
you try to add a new document with a duplicate name field, an error occurs.
It is possible to set unique to true in an index with no
terms, but it is strongly discouraged due to performance
considerations. All unique indexes should have defined terms.
|
The following example creates a unique example on the People collection,
so that each document in the collection must have a unique name field.
{
ref: Index("people_by_name"),
ts: 1649187002375000,
active: true,
serialized: true,
name: 'people_by_name',
source: Collection("People"),
terms: [ { field: [ 'data', 'name' ] } ],
unique: true,
partitions: 1
}
Bindings
An index binding is a way to create a computed value for an index’s
terms or values definition. Many data access patterns require
searching for or reporting a computed result rather than a literal
value, and bindings make that operation much faster than getting results
and then computing values after the fact.
Pagination
If a query finds a large number of results, you probably don’t want to
deal with them all in one response. The Fauna Paginate
function lets you break a result set down into smaller chunks, or
"pages". Pagination allows you to specify how many results per page to
return, and to move through the pages of results.
Paginate defaults to 64 results, and can return up to 100,000
results.
Multi-collection indexes
Some data access patterns may involve searching across multiple collections, and that’s possible with a multi-collection index.
Temporality and indexes
Every Fauna document includes a timestamp field (ts) which identifies
when the most recent document event occurred, including when the
document was created, updated, or deleted.
Index entries also store document history, including previous versions
of covered documents and documents events, such as updates and
deletions. Storing document history permits searching at a specific
point in the past (using the At function) and receiving results
consistent with that time. However, usage patterns which involve frequent
document history changes can lead to rapid index growth and slower performance.
Be careful when indexing collections in which documents are updated frequently,
and be sure to set an appropriate value for the history_days attribute on
indexed collections. See Collections for
more information about setting collection attributes.
Combining and comparing sets
FQL provides several functions for comparing and combining sets from
indexes, including Union, Intersection, Join, and
Filter. Read more.
Collection indexes
The simplest kind of Fauna index is a collection index. A collection
index has no terms or values defined and includes all documents in
its source collection. Collection indexes are useful for data access
patterns in which you need to retrieve all the documents in a collection
with no search criteria.
Consider using the Documents function rather than a
collection index. It provides the same functionality, and avoids
the storage and write operations required for a collection index.
|
The following example uses the all_people index to return documents in
the People collection. It passes a size parameter to the
Paginate function to limit results to the first three entries in
the index.
{
after: [ Ref(Collection("People"), "323071623929266688") ],
data: [
{
ref: Ref(Collection("People"), "323071623916683776"),
ts: 1644363960140000,
data: {
first: 'Alan',
last: 'Perlis',
age: 97,
degrees: [ 'BA', 'MA', 'PhD' ],
letter: 'A'
}
},
{
ref: Ref(Collection("People"), "323071623920878080"),
ts: 1644363960140000,
data: {
first: 'Alan',
last: 'Turing',
age: 107,
degrees: [ 'BA', 'MA', 'MS', 'PhD' ],
letter: 'B'
}
},
{
ref: Ref(Collection("People"), "323071623925072384"),
ts: 1644363960140000,
data: {
first: 'Grace',
last: 'Hopper',
age: 119,
degrees: [ 'BA', 'MA', 'PhD' ],
letter: 'C'
}
}
]
}