Search with indexes
Searching documents in Fauna is accomplished using indexes,
specifically by matching inputs against an index’s terms
field.
Note that Fauna does not currently have a full-text or wildcard search
capabilities. Also, indexes without defined terms
cannot be used for
searching.
This tutorial assumes that you have successfully prepared your database by creating the necessary collections and documents. |
Exact match
Let’s say that we want to search our People
collection for documents
where the first
name is "Alan". To do that, we need to create an index
with the first
field defined as one of the terms
. Copy the following
query, paste it into the Shell, and run it:
CreateIndex({
name: "people_search_by_first",
source: Collection("People"),
terms: [
{
field: ["data", "first"]
}
]
})
The points of interest for this query:
-
It is a good practice to name an index after its collection, its purpose, which field(s) are involved in the purpose, and the sort direction.
-
We specify a single
terms
field, which includes the value in each document’sfirst
field which exists in the document’sdata
field.
When you run this query, the result should be similar to:
{
"ref": Index("people_search_by_first"),
"ts": 1565320196190000,
"active": true,
"serialized": true,
"name": "people_search_by_first",
"source": Collection("People"),
"terms": [
{
"field": [
"data",
"first"
]
}
],
"partitions": 1
}
Now that the index has been created, we can use it to search our documents. Copy the following query, paste it into the Shell, and run it:
Map(
Paginate(
Match(Index("people_search_by_first"), "Alan")
),
Lambda(
"person",
Get(Var("person"))
)
)
The points of interest for this query:
-
We’re using the
Match
function to locate all of the entries in thepeople_by_first_name
index that have the first nameAlan
. -
We’re using the
Paginate
function to iterate on all of the results returned byMatch
. -
We’re using the
Map
function to iterate on all of the results fromPaginate
, in order to pass them to aLambda
function. TheLambda
uses theGet
function to read the specified document by using the Reference returned by the index.
When you run this query, the result should be similar to:
{
data: [
{
ref: Ref(Collection("People"), "240166254282805769"),
ts: 1565299238420000,
data: {
first: "Alan",
last: "Perlis",
degrees: ["BA", "MA", "PhD"],
letter: "A"
}
},
{
ref: Ref(Collection("People"), "240166254282801673"),
ts: 1565299238420000,
data: {
first: "Alan",
last: "Turing",
degrees: ["BA", "MA", "MS", "PhD"],
letter: "B"
}
}
]
}
Array field matches
When a document has a field containing an array of items, and that field is indexed, Fauna creates distinct index entries for each item in the field’s array. That makes it easy to search for any item in the array.
Our People
documents contain the degrees
field, which is an array
with varying numbers of items. We can search on the degrees
field
items by creating an appropriate index. Copy the following query, paste
it into the Shell, and run it:
CreateIndex({
name: "people_search_by_degrees",
source: Collection("People"),
terms: [
{
field: ["data", "degrees"]
}
]
})
The only difference between this index and the Exact match index is that
we’re defining the degrees
field as one of the terms
.
After the index has been created, we can use it to search for our
documents. Let’s find out which People
documents have an MBA
degree.
Copy the following query, paste it into the Shell, and run it.
Map(
Paginate(
Match(Index("people_search_by_degrees"), "MBA")
),
Lambda(
"person",
Get(Var("person"))
)
)
This query differs from the Exact match query only in the index that we
are using, and the search term, MBA
.
When you run this query, the result should be similar to:
{
data: [
{
ref: Ref(Collection("People"), "240166254282802697"),
ts: 1565299238420000,
data: {
first: "Tim",
last: "Cook",
degrees: ["BS", "MBA"],
letter: "G"
}
}
]
}
term1
or term2
matches
Suppose we want to search for people where the first name is Alan
or
the first name is Tim
. To do that, we need to use one of Fauna’s
Set functions, Union
.
Copy the following query, paste it into the Shell, and run it:
Map(
Paginate(
Union(
Match(Index("people_search_by_first"), "Alan"),
Match(Index("people_search_by_first"), "Tim")
)
),
Lambda("person", Get(Var("person")))
)
In this query, Union
combines the results of the first Match
with
the results of the second Match
, giving us the Alan-or-Tim results
that we’re looking for.
When you run this query, the result should be similar to:
{
"data": [
{
"ref": Ref(Collection("People"), "240166254282801673"),
"ts": 1565299238420000,
"data": {
"first": "Alan",
"last": "Turing",
"letter": "B"
}
},
{
"ref": Ref(Collection("People"), "240166254282802697"),
"ts": 1565299238420000,
"data": {
"first": "Tim",
"last": "Cook",
"letter": "G"
}
},
{
"ref": Ref(Collection("People"), "240166254282805769"),
"ts": 1565299238420000,
"data": {
"first": "Alan",
"last": "Perlis",
"letter": "A"
}
}
]
}
Conclusion
This tutorial has demonstrated how to search documents by exact, array, or union matches, using indexes. While it may be a bit more work than you might expect, especially if you are familiar with SQL searching, Fauna’s searching can provide similar results provided that you create all of the indexes required for your searching situations.
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!