Index tutorials
This section assumes that you have successfully completed the Dashboard quick start, and that you still have the Fauna Dashboard open in a browser tab/window. If your Fauna Dashboard session has expired, log in again. |
Indexes are the fundamental tool for querying your documents in Fauna. Fauna uses log-structured merge-tree indexes, unlike most SQL systems, which use B-tree indexes.
Since Fauna does not currently provide table scans, indexes are required for any queries where you do not already know all of the Refs involved.
Indexes are also key to searching, sorting, and combining results from multiple collections (typically called "joins").
This section provides a number of tutorials that demonstrate how to use indexes in various ways.
The maximum size of an index entry, which is comprised of the terms
and values content (and some overhead to distinguish multiple
fields), must not exceed 64k bytes. If an index
entry is too large, the query that created/updated the index
entry fails.
|
Preparation
Each of the tutorials uses a common set of collections and documents.
Create collections
A collection is like an SQL table: it groups similar kinds of documents together. Unlike SQL, the documents in a Fauna collection are not required to include the same fields.
For our tutorials, we’re going to create a Letters
collection, storing
the letters of the alphabet plus some counting fields, plus a People
collection, storing person
documents that include first and last
names, plus a letter
identifier.
Let’s create the collections:
-
In the Fauna Dashboard, make sure that you are using the
my_db
database.If you were already viewing the Dashboard click the Dashboard Home button at the top left.
Click
my_db
in the list of databases. -
Click the NEW COLLECTION button.
-
Specify
Letters
for the Collection Name field. -
Click the SAVE button.
-
Click the NEW COLLECTION button.
-
Specify
People
for the Collection Name field. -
Click the SAVE button.
The collections have been created. If you were using the Shell (either
in the Fauna Dashboard, or fauna-shell
in a terminal window), the
following queries would create the collections:
CreateCollection({ name: "Letters" })
CreateCollection({ name: "People" })
Create indexes
An index is a lookup table, which makes finding documents faster, and more efficient compared to inspecting every document.
We need to create a few indexes to lookup documents within the collections that we just created:
-
In the Fauna Dashboard, click Indexes in the left navigation panel.
-
Click the NEW INDEX button.
-
Select the
Letters
collection for the Source Collection field. -
Specify
all_letters
for the Index Name field. -
Click the SAVE button.
-
Click the NEW INDEX button.
-
Select the
People
collection for the Source Collection field. -
Specify
all_people
for the Index Name field. -
Click the SAVE button.
The indexes have been created. If you were using the Shell (either
in the Fauna Dashboard, or fauna-shell
in a terminal window), the
following queries would create the indexes:
CreateIndex({ name: "all_letters", source: Collection("Letters") })
CreateIndex({ name: "all_people", source: Collection("People") })
The indexes that we have created are called "collection indexes",
because that have no terms
defined to help us search for specific
fields, and no values
defined to report specific fields in the
results. These indexes just make it easy to fetch all of the documents
in a collection.
You can use the Documents function instead of collection
indexes.
|
Create documents
A document is equivalent to an SQL record; it stores values for named fields (in SQL, "columns"). The notable differences are:
-
Fauna documents do not have to have the same field structure as any other document in the same collection.
-
Fields in Fauna documents can contain documents/nested data.
Let’s create some documents for the Letters
collection. Copy the
following query, paste it into your Shell, and run it:
Map(
[
[ "101", { letter: "A", extra: "First" } ],
[ "102", { letter: "B", extra: "second" } ],
[ "103", { letter: "C", extra: "third" } ],
[ "104", { letter: "D", extra: "4th" } ],
[ "105", { letter: "E", extra: "fifth" } ],
[ "106", { letter: "F", extra: "sixth" } ],
[ "107", { letter: "G", extra: "seventh" } ],
[ "108", { letter: "H", extra: "eighth" } ],
[ "109", { letter: "I", extra: "9th" } ],
[ "110", { letter: "J", extra: "tenth" } ],
[ "111", { letter: "K", extra: 11 } ],
[ "112", { letter: "L", extra: "" } ],
[ "113", { letter: "M" } ],
[ "114", { letter: "N", extra: "14th" } ],
[ "115", { letter: "O", extra: "fifteenth" } ],
[ "116", { letter: "P", extra: "16th" } ],
[ "117", { letter: "Q", extra: "seventeenth" } ],
[ "118", { letter: "R", extra: "18th" } ],
[ "119", { letter: "S", extra: "19th" } ],
[ "120", { letter: "T", extra: "20th" } ],
[ "121", { letter: "U", extra: "21st" } ],
[ "122", { letter: "V", extra: "22nd" } ],
[ "123", { letter: "W", extra: "twenty-third" } ],
[ "124", { letter: "X", extra: 24 } ],
[ "125", { letter: "Y", extra: "24 + 1" } ],
[ "126", { letter: "Z" } ]
],
Lambda(
["dID", "data"],
Create(Ref(Collection("Letters"), Var("dID")), { data: Var("data") })
)
)
The points of interest for this query:
-
We’re using the
Map
function to process an array of arrays, with the inner array containing a document ID (a string-encoded 64-bit integer) and an object representing the document we wish to create in Fauna.We’re using the document ID to create documents with a known numeric identifier, rather than the number that Fauna would auto-generate for us. Specified document IDs can make working with particular documents notably easier.
-
We’re using a
Lambda
function to process each item in the document array, where each item contains a document ID and the data for the corresponding document. -
Each invocation of the Lambda function creates a new document in the
Letters
collection, using theVar
function to apply the value of thedID
variable as the document ID, and thedata
variable as the document’s data.
When you run this query, the result should be similar to:
[
{
"ref": Ref(Collection("Letters"), "101"),
"ts": 15652991764850000,
"data": {
"letter": "A",
"extra": "First"
}
},
{
"ref": Ref(Collection("Letters"), "102"),
"ts": 15652991764850000,
"data": {
"letter": "B",
"extra": "second"
}
},
{
"ref": Ref(Collection("Letters"), "103"),
"ts": 15652991764850000,
"data": {
"letter": "C",
"extra": "third"
}
},
{
"ref": Ref(Collection("Letters"), "104"),
"ts": 15652991764850000,
"data": {
"letter": "D",
"extra": "4th"
}
},
{
"ref": Ref(Collection("Letters"), "105"),
"ts": 15652991764850000,
"data": {
"letter": "E",
"extra": "fifth"
}
},
{
"ref": Ref(Collection("Letters"), "106"),
"ts": 15652991764850000,
"data": {
"letter": "F",
"extra": "sixth"
}
},
{
"ref": Ref(Collection("Letters"), "107"),
"ts": 15652991764850000,
"data": {
"letter": "G",
"extra": "seventh"
}
},
{
"ref": Ref(Collection("Letters"), "108"),
"ts": 15652991764850000,
"data": {
"letter": "H",
"extra": "eighth"
}
},
{
"ref": Ref(Collection("Letters"), "109"),
"ts": 15652991764850000,
"data": {
"letter": "I",
"extra": "9th"
}
},
{
"ref": Ref(Collection("Letters"), "110"),
"ts": 15652991764850000,
"data": {
"letter": "J",
"extra": "tenth"
}
},
{
"ref": Ref(Collection("Letters"), "111"),
"ts": 15652991764850000,
"data": {
"letter": "K",
"extra": 11
}
},
{
"ref": Ref(Collection("Letters"), "112"),
"ts": 15652991764850000,
"data": {
"letter": "L",
"extra": ""
}
},
{
"ref": Ref(Collection("Letters"), "113"),
"ts": 15652991764850000,
"data": {
"letter": "M"
}
},
{
"ref": Ref(Collection("Letters"), "114"),
"ts": 15652991764850000,
"data": {
"letter": "N",
"extra": "14th"
}
},
{
"ref": Ref(Collection("Letters"), "115"),
"ts": 15652991764850000,
"data": {
"letter": "O",
"extra": "fifteenth"
}
},
{
"ref": Ref(Collection("Letters"), "116"),
"ts": 15652991764850000,
"data": {
"letter": "P",
"extra": "16th"
}
},
{
"ref": Ref(Collection("Letters"), "117"),
"ts": 15652991764850000,
"data": {
"letter": "Q",
"extra": "seventeenth"
}
},
{
"ref": Ref(Collection("Letters"), "118"),
"ts": 15652991764850000,
"data": {
"letter": "R",
"extra": "18th"
}
},
{
"ref": Ref(Collection("Letters"), "119"),
"ts": 15652991764850000,
"data": {
"letter": "S",
"extra": "19th"
}
},
{
"ref": Ref(Collection("Letters"), "120"),
"ts": 15652991764850000,
"data": {
"letter": "T",
"extra": "20th"
}
},
{
"ref": Ref(Collection("Letters"), "121"),
"ts": 15652991764850000,
"data": {
"letter": "U",
"extra": "21st"
}
},
{
"ref": Ref(Collection("Letters"), "122"),
"ts": 15652991764850000,
"data": {
"letter": "V",
"extra": "22nd"
}
},
{
"ref": Ref(Collection("Letters"), "123"),
"ts": 15652991764850000,
"data": {
"letter": "W",
"extra": "twenty-third"
}
},
{
"ref": Ref(Collection("Letters"), "124"),
"ts": 15652991764850000,
"data": {
"letter": "X",
"extra": 24
}
},
{
"ref": Ref(Collection("Letters"), "125"),
"ts": 15652991764850000,
"data": {
"letter": "Y",
"extra": "24 + 1"
}
},
{
"ref": Ref(Collection("Letters"), "126"),
"ts": 1565299176485000,
"data": {
"letter": "Z"
}
}
]
Now, let’s create some documents for the People
collection. Copy
the following query, paste it into your Shell, and run it:
Map(
[
{
first: "Alan", last: "Perlis",
degrees: ['BA', 'MA', 'PhD'], letter: "A",
},
{
first: "Alan", last: "Turing",
degrees: ['BA', 'MA', 'MS', 'PhD'], letter: "B",
},
{
first: "Grace", last: "Hopper",
degrees: ['BA', 'MA', 'PhD'], letter: "C",
},
{
first: "Leslie", last: "Lamport",
degrees: ['BS', 'MA', 'PhD'],
},
{
first: "Marvin", last: "Minsky",
degrees: ['BA', 'PhD'], letter: 1,
},
{
first: "Stephen", last: "Cook",
degrees: ['BS', 'PhD'], letter: "F",
},
{
first: "Tim", last: "Cook",
degrees: ['BS', 'MBA'], letter: "G",
}
],
Lambda(
"person",
Create(Collection("People"), { data: Var("person") })
)
)
This query is very similar to the query we used to create documents in
the Letters
collection. The People
documents that we have created
just differ in structure.
You may have noticed that both queries vary the definition of the last field. These variations are used in the tutorials to highlight behavioral differences.
When you run this query, the result should be similar to:
[
{
"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"
}
},
{
"ref": Ref(Collection("People"), "240166254282806793"),
"ts": 1565299238420000,
"data": {
"first": "Grace",
"last": "Hopper",
"degrees": [ 'BA', 'MA', 'PhD' ],
"letter": "C"
}
},
{
"ref": Ref(Collection("People"), "240166254282803721"),
"ts": 1565299238420000,
"data": {
"first": "Leslie",
"last": "Lamport",
"degrees": [ 'BS', 'MA', 'PhD' ]
}
},
{
"ref": Ref(Collection("People"), "240166254282804745"),
"ts": 1565299238420000,
"data": {
"first": "Marvin",
"last": "Minsky",
"degrees": [ 'BA', 'PhD' ],
"letter": 1
}
},
{
"ref": Ref(Collection("People"), "240166254282807817"),
"ts": 1565299238420000,
"data": {
"first": "Stephen",
"last": "Cook",
"degrees": [ 'BS', 'PhD' ],
"letter": "F"
}
},
{
"ref": Ref(Collection("People"), "240166254282802697"),
"ts": 1565299238420000,
"data": {
"first": "Tim",
"last": "Cook",
"degrees": [ 'BS', 'MBA' ],
"letter": "G"
}
}
]
Now that we have our collections and documents created, we’re all set to start working through the index tutorials.