Create an index

Problem

You need to create an index for a collection within the current database.

Solution

  1. Use the CreateIndex function and give the index a name, a source (the collection of documents to index); the values field is used to specify the values to include in the result for matching entries:

    try
    {
        Value result = await client.Query(
            CreateIndex(
                Obj(
                    "name", "all_people",
                    "source", Collection("People"),
                    "values", Arr(
                        Obj("field", Arr("data", "first")),
                        Obj("field", Arr("data", "last")),
                        Obj("field", Arr("ref"))
                    )
                )
            )
        );
        Console.WriteLine(result);
    }
    catch (Exception e)
    {
        Console.WriteLine($"ERROR: {e.Message}");
    }
    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))
    result, err := client.Query(
    	f.CreateIndex(
    		f.Obj{
    			"name": "all_people",
    			"source": f.Collection("People"),
    			"values": f.Arr{
    				f.Obj{"field": f.Arr{"data", "first"}},
    				f.Obj{"field": f.Arr{"data", "last"}},
    				f.Obj{"field": f.Arr{"ref"}},
    			},
    		},
    	),
    )
    
    if err != nil {
    	fmt.Fprintln(os.Stderr, err)
    } else {
    	fmt.Println(result)
    }
    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]]]]
    client.query(
      q.CreateIndex(
        {
          name: 'all_people',
          source: q.Collection('People'),
          values: [
            { field: ['data', 'first'] },
            { field: ['data', 'last'] },
            { field: ['ref'] },
          ],
        },
      )
    )
    .then((ret) => console.log(ret))
    .catch((err) => console.error(
      'Error: [%s] %s: %s',
      err.name,
      err.message,
      err.errors()[0].description,
    ))
    {
      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
    }
    result = client.query(
      q.create_index(
        {
          "name": "all_people",
          "source": q.collection("People"),
          "values": [
            {"field": ["data", "first"]},
            {"field": ["data", "last"]},
            {"field": ["ref"]}
          ]
        }
      )
    )
    print(result)
    {'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}
    CreateIndex({
      name: "all_people",
      source: Collection("People"),
      values: [
        { field: ["data", "first"] },
        { field: ["data", "last"] },
        { field: ["ref"] }
      ]
    })
    {
      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
    }
    Query metrics:
    •    bytesIn:   197

    •   bytesOut:   336

    • computeOps:     1

    •    readOps:     0

    •   writeOps:     8

    •  readBytes: 2,348

    • writeBytes: 1,613

    •  queryTime:  73ms

    •    retries:     0

  2. The following example adds the age field to the values definition, and sets reverse: true, to sort the results in descending order:

    try
    {
        Value result = await client.Query(
            CreateIndex(
                Obj(
                    "name", "people_by_age_desc",
                    "source", Collection("People"),
                    "values", Arr(
                        Obj("field", Arr("data", "age"), "reverse", true),
                        Obj("field", Arr("data", "fist")),
                        Obj("field", Arr("data", "last")),
                        Obj("field", Arr("ref"))
                    )
                )
            )
        );
        Console.WriteLine(result);
    }
    catch (Exception e)
    {
        Console.WriteLine($"ERROR: {e.Message}");
    }
    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))
    result, err := client.Query(
    	f.CreateIndex(
    		f.Obj{
    			"name": "people_by_age_desc",
    			"source": f.Collection("People"),
    			"values": f.Arr{
    				f.Obj{"field": f.Arr{"data", "age"}, "reverse": true},
    				f.Obj{"field": f.Arr{"data", "first"}},
    				f.Obj{"field": f.Arr{"data", "last"}},
    				f.Obj{"field": f.Arr{"ref"}},
    			},
    		},
    	),
    )
    
    if err != nil {
    	fmt.Fprintln(os.Stderr, err)
    } else {
    	fmt.Println(result)
    }
    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]]]]
    client.query(
      q.CreateIndex(
        {
          name: 'people_by_age_desc',
          source: q.Collection('People'),
          values: [
            { field: ['data', 'age'], reverse: true },
            { field: ['data', 'first'] },
            { field: ['data', 'last'] },
            { field: ['ref'] },
          ],
        },
      )
    )
    .then((ret) => console.log(ret))
    .catch((err) => console.error(
      'Error: [%s] %s: %s',
      err.name,
      err.message,
      err.errors()[0].description,
    ))
    {
      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
    }
    result = client.query(
      q.create_index(
        {
          "name": "people_by_age_desc",
          "source": q.collection("People"),
          "values": [
            {"field": ["data", "age"], "reverse": True},
            {"field": ["data", "first"]},
            {"field": ["data", "last"]},
            {"field": ["ref"]}
          ]
        }
      )
    )
    print(result)
    {'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}
    CreateIndex({
      name: "people_by_age_desc",
      source: Collection("People"),
      values: [
        { field: ["data", "age"], reverse: true },
        { field: ["data", "first"] },
        { field: ["data", "last"] },
        { field: ["ref"] }
      ]
    })
    {
      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
    }
    Query metrics:
    •    bytesIn:   256

    •   bytesOut:   392

    • computeOps:     1

    •    readOps:     0

    •   writeOps:     8

    •  readBytes: 2,406

    • writeBytes: 1,705

    •  queryTime:  91ms

    •    retries:     0

  3. The following example creates an index with defined terms to be able to search for document values:

    try
    {
        Value result = await client.Query(
            CreateIndex(
                Obj(
                    "name", "people_by_first",
                    "source", Collection("People"),
                    "terms", Arr(
                        Obj("field", Arr("data", "first"))
                    ),
                    "values", Arr(
                        Obj("field", Arr("data", "first")),
                        Obj("field", Arr("data", "last")),
                        Obj("field", Arr("ref"))
                    )
                )
            )
        );
        Console.WriteLine(result);
    }
    catch (Exception e)
    {
        Console.WriteLine($"ERROR: {e.Message}");
    }
    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))
    result, err := client.Query(
    	f.CreateIndex(
    		f.Obj{
    			"name": "people_by_first",
    			"source": f.Collection("People"),
    			"terms": f.Arr{
    				f.Obj{"field": f.Arr{"data", "first"}},
    			},
    			"values": f.Arr{
    				f.Obj{"field": f.Arr{"data", "first"}},
    				f.Obj{"field": f.Arr{"data", "last"}},
    				f.Obj{"field": f.Arr{"ref"}},
    			},
    		},
    	),
    )
    
    if err != nil {
    	fmt.Fprintln(os.Stderr, err)
    } else {
    	fmt.Println(result)
    }
    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]]]]
    client.query(
      q.CreateIndex(
        {
          name: 'people_by_first',
          source: q.Collection('People'),
          terms: [
            { field: ['data', 'first'] },
          ],
          values: [
            { field: ['data', 'first'] },
            { field: ['data', 'last'] },
            { field: ['ref'] },
          ],
        },
      )
    )
    .then((ret) => console.log(ret))
    .catch((err) => console.error(
      'Error: [%s] %s: %s',
      err.name,
      err.message,
      err.errors()[0].description,
    ))
    {
      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
    }
    result = client.query(
      q.create_index(
        {
          "name": "people_by_first",
          "source": q.collection("People"),
          "terms": [
            {"field": ["data", "first"]}
          ],
          "values": [
            {"field": ["data", "first"]},
            {"field": ["data", "last"]},
            {"field": ["ref"]}
          ]
    
        }
      )
    )
    print(result)
    {'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}
    CreateIndex({
      name: "people_by_first",
      source: Collection("People"),
      terms: [
        { field: ["data", "first" ] }
      ],
      values: [
        { field: ["data", "first"] },
        { field: ["data", "last"] },
        { field: ["ref"] }
      ]
    })
    {
      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
    }
    Query metrics:
    •    bytesIn:   250

    •   bytesOut:   383

    • computeOps:     1

    •    readOps:     0

    •   writeOps:     8

    •  readBytes: 2,442

    • writeBytes: 1,724

    •  queryTime: 403ms

    •    retries:     0

  4. The following examples creates an index with two terms fields:

    try
    {
        Value result = await client.Query(
            CreateIndex(
                Obj(
                    "name", "people_by_first_last",
                    "source", Collection("People"),
                    "terms", Arr(
                        Obj("field", Arr("data", "first")),
                        Obj("field", Arr("data", "last"))
                    ),
                    "values", Arr(
                        Obj("field", Arr("data", "first")),
                        Obj("field", Arr("data", "last")),
                        Obj("field", Arr("ref"))
                    )
                )
            )
        );
        Console.WriteLine(result);
    }
    catch (Exception e)
    {
        Console.WriteLine($"ERROR: {e.Message}");
    }
    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))
    result, err := client.Query(
    	f.CreateIndex(
    		f.Obj{
    			"name": "people_by_first_last",
    			"source": f.Collection("People"),
    			"terms": f.Arr{
    				f.Obj{"field": f.Arr{"data", "first"}},
    				f.Obj{"field": f.Arr{"data", "last"}},
    			},
    			"values": f.Arr{
    				f.Obj{"field": f.Arr{"data", "first"}},
    				f.Obj{"field": f.Arr{"data", "last"}},
    				f.Obj{"field": f.Arr{"ref"}},
    			},
    		},
    	),
    )
    
    if err != nil {
    	fmt.Fprintln(os.Stderr, err)
    } else {
    	fmt.Println(result)
    }
    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]]]]
    client.query(
      q.CreateIndex(
        {
          name: 'people_by_first_last',
          source: q.Collection('People'),
          terms: [
            { field: ['data', 'first'] },
            { field: ['data', 'last'] },
          ],
          values: [
            { field: ['data', 'first'] },
            { field: ['data', 'last'] },
            { field: ['ref'] },
          ],
        },
      )
    )
    .then((ret) => console.log(ret))
    .catch((err) => console.error(
      'Error: [%s] %s: %s',
      err.name,
      err.message,
      err.errors()[0].description,
    ))
    {
      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
    }
    result = client.query(
      q.create_index(
        {
          "name": "people_by_first_last",
          "source": q.collection("People"),
          "terms": [
            {"field": ["data", "first"]},
            {"field": ["data", "last"]}
          ],
          "values": [
            {"field": ["data", "first"]},
            {"field": ["data", "last"]},
            {"field": ["ref"]}
          ]
        }
      )
    )
    print(result)
    {'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}
    CreateIndex({
      name: "people_by_first_last",
      source: Collection("People"),
      terms: [
        { field: ["data", "first" ] },
        { field: ["data", "last" ] }
      ],
      values: [
        { field: ["data", "first"] },
        { field: ["data", "last"] },
        { field: ["ref"] }
      ]
    })
    {
      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
    }
    Query metrics:
    •    bytesIn:   292

    •   bytesOut:   419

    • computeOps:     1

    •    readOps:     0

    •   writeOps:     8

    •  readBytes: 2,494

    • writeBytes: 1,849

    •  queryTime: 124ms

    •    retries:     0

  5. The following example creates an index with a binding to compute a value that can be searched. The binding combines a People document’s first and last names into a fullname field:

    try
    {
        Value result = await client.Query(
            CreateIndex(
                Obj(
                    "name", "people_by_fullname",
                    "source", Obj(
                        "collection", Collection("People"),
                        "fields", Obj(
                            "fullname", Query(
                                Lambda(
                                    "doc",
                                    Concat(
                                        Arr(
                                            Select(
                                                Arr("data", "first"),
                                                Var("doc")
                                            ),
                                            Select(
                                                Arr("data", "last"),
                                                Var("doc")
                                            )
                                        ),
                                        " "
                                    )
                                )
                            )
                        )
                    ),
                    "terms", Arr(
                        Obj("binding", "fullname")
                    ),
                    "values", Arr(
                        Obj("binding", "fullname"),
                        Obj("field", Arr("ref"))
                    )
                )
            )
        );
        Console.WriteLine(result);
    }
    catch (Exception e)
    {
        Console.WriteLine($"ERROR: {e.Message}");
    }
    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))
    result, err := client.Query(
    
    	f.CreateIndex(
    		f.Obj{
    			"name": "people_by_fullname",
    			"source": f.Obj{
    				"collection": f.Collection("People"),
    				"fields": f.Obj{
    					"fullname": f.Query(
    						f.Lambda(
    							"doc",
    							f.Concat(
    								f.Arr{
    									f.Select(
    										f.Arr{"data", "first"},
    										f.Var("doc"),
    									),
    									f.Select(
    										f.Arr{"data", "last"},
    										f.Var("doc"),
    									),
    								},
    								f.Separator(" "),
    							),
    						),
    					),
    				},
    			},
    			"terms": f.Arr{
    				f.Obj{"binding": "fullname"},
    			},
    			"values": f.Arr{
    				f.Obj{"binding": "fullname"},
    				f.Obj{"field": f.Arr{"ref"}},
    			},
    		},
    	),
    )
    
    if err != nil {
    	fmt.Fprintln(os.Stderr, err)
    } else {
    	fmt.Println(result)
    }
    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]]]]
    client.query(
      q.CreateIndex(
        {
          name: 'people_by_fullname',
          source: {
            collection: q.Collection('People'),
            fields: {
              fullname: q.Query(
                q.Lambda(
                  'doc',
                  q.Concat(
                    [
                      q.Select(['data', 'first'], q.Var('doc')),
                      q.Select(['data', 'last'], q.Var('doc')),
                    ],
                    ' ',
                  ),
                ),
              ),
            },
          },
          terms: [
            { binding: 'fullname' },
          ],
          values: [
            { binding: 'fullname' },
            { field: ['ref'] },
          ],
        },
      )
    )
    .then((ret) => console.log(ret))
    .catch((err) => console.error(
      'Error: [%s] %s: %s',
      err.name,
      err.message,
      err.errors()[0].description,
    ))
    {
      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
    }
    result = client.query(
      q.create_index(
        {
          "name": "people_by_fullname",
          "source": {
            "collection": q.collection("People"),
            "fields": {
              "fullname": q.query(
                q.lambda_(
                  "doc",
                  q.concat(
                    [
                      q.select(["data", "first"], q.var("doc")),
                      q.select(["data", "last"], q.var("doc"))
                    ],
                    " "
                  )
                )
              )
            }
          },
          "terms": [
            {"binding": "fullname"}
          ],
          "values": [
            {"binding": "fullname"},
            {"field": ["ref"]}
          ]
        }
      )
    )
    print(result)
    {'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}
    CreateIndex({
      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"] }
      ]
    })
    {
      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
    }
    Query metrics:
    •    bytesIn:   427

    •   bytesOut:   571

    • computeOps:     1

    •    readOps:     0

    •   writeOps:     8

    •  readBytes: 2,322

    • writeBytes: 1,942

    •  queryTime: 103ms

    •    retries:     0

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 terms.

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!