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. |
collection.indexName()
Signature
<indexName>() => Set<A>
<indexName>(term: B, ... ) => Set<A>
<indexName>(term: B, ..., range: { from: Any } | { to: Any } | { from: Any, to: Any }) => Set<A>
Description
Calls an index by its name as a method to get a Set of matching collection documents.
An index stores, or covers, specific document field values for quick retrieval. You can use indexes to filter and sort a collection’s documents in a performant way.
The call returns:
-
Documents with terms that exactly match the provided
term
arguments (if any) -
Documents within the specified range of
values
(if provided) -
All indexed documents sorted by the index
values
if no arguments are provided
Index definitions
You define an index as part of a collection schema. See FSL collection schema: Index definitions.
You can only call an index that is part of the database’s active schema.
Missing or null values
-
Terms: If an index definition contains terms, Fauna doesn’t index a document if all its index terms are missing or otherwise evaluate to null. This applies even if the document contains index values.
-
Values: If an index definition contains only values, Fauna indexes all documents in the collection, regardless of whether the document’s index values are missing or otherwise null.
Covered queries
If you only project fields that are covered by the index terms or values, Fauna can retrieve the data directly from the index without reading the documents. These are called "covered queries" and are more performant.
A query is uncovered if:
-
It projects fields not included in the index definition.
-
It has no projection, which means it returns entire documents.
Uncovered queries require additional document reads and are typically more expensive.
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
term |
Yes |
Arguments that exactly match the index terms defined in the index definition. Must be provided in the same order as defined in the index definition. Required if the index definition includes terms. Use a comma to separate term arguments when passing multiple terms. |
|
|
Specifies a range of values to match in the form
Both When using Arrays, values are compared in order:
For range searches on indexes with descending order values, pass the higher
value in Omit |
Return value
Type | Description |
---|---|
Set of matching collection documents. Results are sorted according to the index values defined in the index definition. |
Examples
Basic example
You define an index in an FSL collection schema:
collection Product {
...
index byName {
terms [.name]
}
...
}
Once the index is built, you call it as a method on the collection:
// Call the `byName()` index to fet `Product` collection
// documents with a `name` value of `limes`. Values must
// match exactly.
Product.byName("limes")
The call returns a Set of matching collection documents.
Use index terms for exact match searches
You can use index terms to run exact match searches on document field values.
The following index definition includes name
as an index term:
collection Product {
...
index byName {
terms [.name]
}
...
}
When you call the index, you must pass an argument for each term in the index definition.
// Get products named "limes"
Product.byName("limes")
The call returns a Set of Product
collection documents with a name
of
limes
.
Pass multiple index terms
The following index definition includes two index terms:
collection Customer {
...
index byName {
terms [.firstName, .lastName]
}
}
In an index call, use a comma to separate term arguments. Provide arguments in the same field order used in the index definition.
// Get customers named "Alice Appleseed"
Customer.byName("Alice", "Appleseed")
The call returns a Set of matching collection documents.
Use index values for sorting and range searches
You can use index values to sort a collection’s documents. You can also use index values for range searches.
Sort documents
The following index definition includes several index values:
collection Product {
...
index sortedByPriceLowToHigh {
values [.price, .name, .description]
}
}
Call the sortedByPriceLowToHigh()
index with no arguments to return Product
documents sorted by:
-
Ascending
price
, then … -
Ascending
name
, then … -
Ascending
description
, then … -
Ascending
id
(default)
// Get products by ascending price, name, and description
Product.sortedByPriceLowToHigh()
Sort in descending order
By default, index values sort results in ascending order. To use descending
order, use desc()
in the index definition:
collection Product {
...
index sortedByPriceHighToLow {
values [desc(.price), .name, .description]
}
...
}
Call the index with no arguments to return Product
documents sorted by:
-
Descending
price
, then … -
Ascending
name
, then … -
Ascending
description
, then … -
Ascending
id
(default)
// Get products by descending price,
// ascending name, and ascending description
Product.sortedByPriceHighToLow()
Run a range search
You can also use index values for range searches.
The following index definition includes several index values:
collection Product {
...
index sortedByPriceLowToHigh {
values [.price, .name, .description]
}
}
The index specifies price
as its first value. The following query passes an
argument to run a range search on price
:
// Get products with a price between
// 20_00 (inclusive) and 30_00 (inclusive)
Product.sortedByPriceLowToHigh({ from: 20_00, to: 30_00 })
If an index value uses descending order, pass the higher value in from
:
// Get products with a price between
// 20_00 (inclusive) and 30_00 (inclusive) in desc order
Product.sortedByPriceHighToLow({ from: 30_00, to: 20_00 })
Omit from
or to
to run unbounded range searches:
// Get products with a price greater than or equal to 20_00
Product.sortedByPriceLowToHigh({ from: 20_00 })
// Get products with a price less than or equal to 30_00
Product.sortedByPriceLowToHigh({ to: 30_00 })
Pass multiple index values
Use an Array to pass multiple value arguments. Pass the arguments in the same field order used in the index definition.
Product.sortedByPriceLowToHigh({ from: [ 20_00, "l" ], to: [ 30_00, "z" ] })
The index returns any document that matches the first value in the from
and
to
Arrays. If matching documents have the same values, they are compared
against the next Array element value, and so on.
For example, the Product
collection’s sortedByPriceLowToHigh()
index covers
the price
and name
fields as index values. The Product
collection contains
two documents:
Document |
|
|
Doc1 |
|
|
Doc2 |
|
|
The following query returns both Doc1 and Doc2, in addition to other matching documents:
Product.sortedByPriceLowToHigh({ from: [4_99, "p"] })
The first value (4_99
and 6_98
) of each document matches the first value
(4_99
) of the from
Array.
Later, you update the document values to:
Document | price |
name |
---|---|---|
Doc1 |
|
|
Doc2 |
|
|
The following query no longer returns Doc2:
Product.sortedByPriceLowToHigh({ from: [4_99, "p"] })
Although the first value (4_99
) in both documents matches the first value in
the from
Array, the second value (cups
) in Doc2 doesn’t match the second
value (p
) of the from
Array.
Run a range search on id
All indexes implicitly include an ascending document id
as the index’s last
value.
If you intend to run range searches on id
, we recommend you explicitly include
an ascending id
as the last index value in the index definition, even if you
have an otherwise identical index.
For example, the following sortByStock()
and sortByStockandId()
indexes have the same values:
collection Product {
...
index sortByStock {
values [.stock]
}
index sortByStockandId {
values [.stock, .id]
}
...
}
Although it’s not explicitly listed, sortByStock()
implicitly includes an
ascending id
as its last value.
To reduce your costs, Fauna only builds the sortByStock()
index. When a
query calls the sortByStockandId()
index, Fauna uses the
sortByStock()
index behind the scenes. sortByStockandId()
only acts as
a virtual index and isn’t
materialized.
Pass terms and values
If an index has both terms and values, you can run an exact match search on documents in a provided range.
The following index definition includes name
as an index term and
stock
as an index value:
collection Product {
...
index byName {
terms [.name]
values [.stock]
}
...
}
When you call the index, you must provide a term and can specify an optional range:
// Get products named "donkeypinata"
// with a stock between 10 (inclusive) and 50 (inclusive)
Product.byName("donkey pinata", { from: 10, to: 50 })
Covered queries
If you project or map an index’s covered term or value fields, Fauna gets the field values from the index.
The following index definition includes several index values:
collection Product {
...
index sortedByPriceLowToHigh {
values [.price, .name, .description]
}
}
The following is a covered query:
// This is a covered query.
// `name`, `description`, and `price` are values
// in the `sortedByPriceLowToHigh()` index definition.
Product.sortedByPriceLowToHigh() {
name,
description,
price
}
If the projection contains an uncovered field, Fauna must retrieve the field values from the documents. This is an uncovered query:
// This is an uncovered query.
// `stock` is not one of the terms or values
// in the `sortedByPriceLowToHigh()` index definition.
Product.sortedByPriceLowToHigh() {
name,
stock
}
No projection or mapping
Index queries without a projection or mapping are uncovered. Fauna must read each document returned in the Set. For example:
// This is an uncovered query.
// Queries without a projection or mapping
// require a document read.
Product.byName("limes")
Filter covered values
You can use set.where()
to filter the results of an
index call. If the
set.where()
predicate only accesses fields defined
in the index definition’s terms
and values
, the query is
covered.
For example, given the following index definition:
collection Product {
...
index byName {
terms [.name]
values [.price, .description]
}
...
}
The following query is covered:
// Covered query.
// Calls the `byName()` index.
// Uses `where()` to filter the results of
// the index call. The predicates only
// access covered terms and values.
Product.byName("limes")
.where(.description.includes("Conventional"))
.where(.price < 500) {
name,
description,
price
}
The following query is uncovered:
Product.byName("limes")
.where(.description.includes("Conventional"))
// The `where()` predicate accesses the uncovered
// `stock` field.
.where(.stock < 100)
.where(.price < 500) {
name,
description,
price
}
To cover the query, add the uncovered field to the index definition’s values
:
collection Product {
...
index byName {
terms [.name]
// Adds `stock` to the index's values
values [.price, .description, .stock]
}
...
}
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!