FQL v4 will be decommissioned on June 30, 2025. Ensure that you complete your migration from FQL v4 to FQL v10 by that date. For more details, review the migration guide. Contact support@fauna.com with any questions. |
Create an index
Solution
-
Use the
CreateIndex
function and give the index aname
, asource
(the collection of documents to index); thevalues
field is used to specify the values to include in the result for matching entries:{ ref: Index("all_people"), ts: 1631909303210000, active: true, serialized: true, name: 'all_people', source: Collection("People"), values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 8 }
{'ref': Ref(id=all_people, collection=Ref(id=indexes)), 'ts': 1631911013630000, 'active': True, 'serialized': True, 'name': 'all_people', 'source': Ref(id=People, collection=Ref(id=collections)), 'values': [{'field': ['data', 'first']}, {'field': ['data', 'last']}, {'field': ['ref']}], 'partitions': 8}
map[active:true name:all_people partitions:8 ref:{all_people 0xc000109c20 0xc000109c20 <nil>} serialized:true source:{People 0xc000109d10 0xc000109d10 <nil>} ts:1631911923630000 values:[map[field:[data first]] map[field:[data last]] map[field:[ref]]]]
ObjectV(ref: RefV(id = "all_people", collection = RefV(id = "indexes")),ts: LongV(1632032492710000),active: BooleanV(True),serialized: BooleanV(True),name: StringV(all_people),source: RefV(id = "People", collection = RefV(id = "collections")),values: Arr(ObjectV(field: Arr(StringV(data), StringV(first))), ObjectV(field: Arr(StringV(data), StringV(last))), ObjectV(field: Arr(StringV(ref)))),partitions: LongV(8))
{ ref: Index("all_people"), ts: 1631830966460000, active: true, serialized: true, name: 'all_people', source: Collection("People"), values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 8 }
-
The following example adds the
age
field to thevalues
definition, and setsreverse: true
, to sort the results in descending order:{ ref: Index("people_by_age_desc"), ts: 1635294301820000, active: true, serialized: true, name: 'people_by_age_desc', source: Collection("People"), values: [ { field: [ 'data', 'age' ], reverse: true }, { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 8 }
{'ref': Ref(id=people_by_age_desc, collection=Ref(id=indexes)), 'ts': 1631910357460000, 'active': True, 'serialized': True, 'name': 'people_by_age_desc', 'source': Ref(id=People, collection=Ref(id=collections)), 'values': [{'field': ['data', 'age'], 'reverse': True}, {'field': ['data', 'first']}, {'field': ['data', 'last']}, {'field': ['ref']}], 'partitions': 8}
map[active:true name:people_by_age_desc partitions:8 ref:{people_by_age_desc 0xc00009bd70 0xc00009bd70 <nil>} serialized:true source:{People 0xc00009be60 0xc00009be60 <nil>} ts:1631911924280000 values:[map[field:[data age] reverse:true] map[field:[data first]] map[field:[data last]] map[field:[ref]]]]
ObjectV(ref: RefV(id = "people_by_age_desc", collection = RefV(id = "indexes")),ts: LongV(1632032888530000),active: BooleanV(True),serialized: BooleanV(True),name: StringV(people_by_age_desc),source: RefV(id = "People", collection = RefV(id = "collections")),values: Arr(ObjectV(field: Arr(StringV(data), StringV(age)),reverse: BooleanV(True)), ObjectV(field: Arr(StringV(data), StringV(fist))), ObjectV(field: Arr(StringV(data), StringV(last))), ObjectV(field: Arr(StringV(ref)))),partitions: LongV(8))
{ ref: Index("people_by_age_desc"), ts: 1631892996810000, active: true, serialized: true, name: 'people_by_age_desc', source: Collection("People"), values: [ { field: [ 'data', 'age' ], reverse: true }, { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 8 }
-
The following example creates an index with defined
terms
to be able to search for document values:{ ref: Index("people_by_first"), ts: 1631910146230000, active: true, serialized: true, name: 'people_by_first', source: Collection("People"), terms: [ { field: [ 'data', 'first' ] } ], values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 1 }
{'ref': Ref(id=people_by_first, collection=Ref(id=indexes)), 'ts': 1631910427650000, 'active': True, 'serialized': True, 'name': 'people_by_first', 'source': Ref(id=spells, collection=Ref(id=collections)), 'terms': [{'field': ['data', 'first']}], 'values': [{'field': ['data', 'first']}, {'field': ['data', 'last']}, {'field': ['ref']}], 'partitions': 1}
map[active:true name:people_by_first partitions:1 ref:{people_by_first 0xc00009bd10 0xc00009bd10 <nil>} serialized:true source:{People 0xc00009be00 0xc00009be00 <nil>} terms:[map[field:[data first]]] ts:1631911924970000 values:[map[field:[data first]] map[field:[data last]] map[field:[ref]]]]
ObjectV(ref: RefV(id = "people_by_first", collection = RefV(id = "indexes")),ts: LongV(1632032500770000),active: BooleanV(True),serialized: BooleanV(True),name: StringV(people_by_first),source: RefV(id = "People", collection = RefV(id = "collections")),terms: Arr(ObjectV(field: Arr(StringV(data), StringV(first)))),values: Arr(ObjectV(field: Arr(StringV(data), StringV(first))), ObjectV(field: Arr(StringV(data), StringV(last))), ObjectV(field: Arr(StringV(ref)))),partitions: LongV(1))
{ ref: Index("people_by_first"), ts: 1631831198910000, active: true, serialized: true, name: 'people_by_first', source: Collection("People"), terms: [ { field: [ 'data', 'first' ] } ], values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 1 }
-
The following examples creates an index with two
terms
fields:{ ref: Index("people_by_first_last"), ts: 1631902422410000, active: true, serialized: true, name: 'people_by_first_last', source: Collection("People"), terms: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] } ], values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 1 }
{'ref': Ref(id=people_by_first_last, collection=Ref(id=indexes)), 'ts': 1631910539040000, 'active': True, 'serialized': True, 'name': 'people_by_first_last', 'source': Ref(id=People, collection=Ref(id=collections)), 'terms': [{'field': ['data', 'first']}, {'field': ['data', 'last']}], 'values': [{'field': ['data', 'first']}, {'field': ['data', 'last']}, {'field': ['ref']}], 'partitions': 1}
map[active:true name:people_by_first_last partitions:1 ref:{people_by_first_last 0xc000109e00 0xc000109e00 <nil>} serialized:true source:{People 0xc000109ef0 0xc000109ef0 <nil>} terms:[map[field:[data first]] map[field:[data last]]] ts:1631911925650000 values:[map[field:[data first]] map[field:[data last]] map[field:[ref]]]]
ObjectV(ref: RefV(id = "people_by_first_last", collection = RefV(id = "indexes")),ts: LongV(1632032504810000),active: BooleanV(True),serialized: BooleanV(True),name: StringV(people_by_first_last),source: RefV(id = "People", collection = RefV(id = "collections")),terms: Arr(ObjectV(field: Arr(StringV(data), StringV(first))), ObjectV(field: Arr(StringV(data), StringV(last)))),values: Arr(ObjectV(field: Arr(StringV(data), StringV(first))), ObjectV(field: Arr(StringV(data), StringV(last))), ObjectV(field: Arr(StringV(ref)))),partitions: LongV(1))
{ ref: Index("people_by_first_last"), ts: 1631893151560000, active: true, serialized: true, name: 'people_by_first_last', source: Collection("People"), terms: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] } ], values: [ { field: [ 'data', 'first' ] }, { field: [ 'data', 'last' ] }, { field: [ 'ref' ] } ], partitions: 1 }
-
The following example creates an index with a binding to compute a value that can be searched. The binding combines a
People
document’sfirst
andlast
names into afullname
field:{ ref: Index("people_by_fullname"), ts: 1631908766580000, active: true, serialized: true, name: 'people_by_fullname', source: { collection: Collection("People"), fields: { fullname: Query(Lambda("doc", Concat([Select(["data", "first"], Var("doc")), Select(["data", "last"], Var("doc"))], " "))) } }, terms: [ { binding: 'fullname' } ], values: [ { binding: 'fullname' }, { field: [ 'ref' ] } ], partitions: 1 }
{'ref': Ref(id=people_by_fullname, collection=Ref(id=indexes)), 'ts': 1631910356810000, 'active': True, 'serialized': True, 'name': 'people_by_fullname', 'source': {'collection': Ref(id=People, collection=Ref(id=collections)), 'fields': {'fullname': Query({'api_version': '4', 'lambda': 'doc', 'expr': {'concat': [{'select': ['data', 'first'], 'from': {'var': 'doc'}}, {'select': ['data', 'last'], 'from': {'var': 'doc'}}], 'separator': ' '}})}}, 'terms': [{'binding': 'fullname'}], 'values': [{'binding': 'fullname'}, {'field': ['ref']}], 'partitions': 1}
map[active:true name:people_by_fullname partitions:1 ref:{people_by_fullname 0xc000124270 0xc000124270 <nil>} serialized:true source:map[collection:{People 0xc000124390 0xc000124390 <nil>} fields:map[fullname:{[123 34 97 112 105 95 118 101 114 115 105 111 110 34 58 34 52 34 44 34 108 97 109 98 100 97 34 58 34 100 111 99 34 44 34 101 120 112 114 34 58 123 34 99 111 110 99 97 116 34 58 91 123 34 115 101 108 101 99 116 34 58 91 34 100 97 116 97 34 44 34 102 105 114 115 116 34 93 44 34 102 114 111 109 34 58 123 34 118 97 114 34 58 34 100 111 99 34 125 125 44 123 34 115 101 108 101 99 116 34 58 91 34 100 97 116 97 34 44 34 108 97 115 116 34 93 44 34 102 114 111 109 34 58 123 34 118 97 114 34 58 34 100 111 99 34 125 125 93 44 34 115 101 112 97 114 97 116 111 114 34 58 34 32 34 125 125]}]] terms:[map[binding:fullname]] ts:1631911922930000 values:[map[binding:fullname] map[field:[ref]]]]
ObjectV(ref: RefV(id = "people_by_fullname", collection = RefV(id = "indexes")),ts: LongV(1632033440090000),active: BooleanV(True),serialized: BooleanV(True),name: StringV(people_by_fullname),source: ObjectV(collection: RefV(id = "People", collection = RefV(id = "collections")),fields: ObjectV(fullname: QueryV(System.Collections.Generic.Dictionary`2[System.String,FaunaDB.Query.Expr]))),terms: Arr(ObjectV(binding: StringV(fullname))),values: Arr(ObjectV(binding: StringV(fullname)), ObjectV(field: Arr(StringV(ref)))),partitions: LongV(1))
{ ref: Index("people_by_fullname"), ts: 1635354169660000, active: true, serialized: true, name: 'people_by_fullname', source: { collection: Collection("People"), fields: { fullname: Query(Lambda("doc", Concat([Select(["data", "first"], Var("doc")), Select(["data", "last"], Var("doc"))], " "))) } }, terms: [ { binding: 'fullname' } ], values: [ { binding: 'fullname' }, { field: [ 'ref' ] } ], partitions: 1 }
Discussion
An index with no terms
and values
defined is called a "collection"
index. You cannot search for any specific document with a collection
index; it is used simply to make it easy to access all of the documents
within a collection. With the introduction of the Documents
function, you no longer need to create collection indexes.
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 64 KB. If an index
entry is too large, the query that created/updated the index
entry fails.
|
When you define a terms
field, you specify one or more fields to
search for. That makes the index selective in what it returns. Note that
once terms
fields are defined, they are not optional for searching:
every field must be specified when the index is queried.
Avoid creating a unique index that does not define If you do create a "term-less" index, the index could cause performance issues. Every time a covered document is created or updated, the index (and its history) needs to be evaluated to decide whether the document is unique or not. As the index grows larger, the evaluation for uniqueness can cause your queries involving writes to exceed the query timeout. |
When you define a values
field, you are specifying which field value
are returned for matching index entries. If you don’t specify values
,
each matching index entry returns the associated document’s Reference.
If you do specify values
and want to include the indexed document’s
Reference in results, be sure to include the ref
field.
Results from an index are sorted by the defined values
. If multiple
fields are specified, results are ordered initially by the first field,
and then the next field, and so on.
Bindings allow you to compute values to be included in the index that don’t exist within the original document. However, binding functions must be "pure" and cannot perform reads, writes, or create any other kind of side effect from their execution.
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!