Search with indexes

Searching documents in FaunaDB is accomplishing using indexes, specifically by matching inputs against an index’s terms field.

Note that FaunaDB does not currently have a full-text or wildcard search capabilities. Also, indexes without defined terms cannot be used for searching.

This tutorial shows you how to create indexes that help you search your documents:

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’s first field which exists in the document’s data 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
}

FaunaDB indexes are initially populated by a background task, that may take anywhere from a few seconds to several minutes to complete, largely due to the number of documents in the source collection. If you execute queries using a freshly-created index and you receive no results, likely the index is still being built. Try again in a few seconds.

Note that when you create an index, any documents created afterwards that involve that index would always show up.

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 the people_by_first_name index that have the first name Alan.

  • We’re using the Paginate function to iterate on all of the results returned by Match.

  • We’re using the Map function to iterate on all of the results from Paginate, in order to pass them to a Lambda function. The Lambda uses the Get function to read the specified document by using the Ref returned by the index.

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"), "240166254282805769"),
      "ts": 1565299238420000,
      "data": {
        "first": "Alan",
        "last": "Perlis",
        "letter": "A"
      }
    }
  ]
}

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 FaunaDB’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 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, FaunaDB’s searching can provide similar results provided that you create all of the indexes required for your searching situations.

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve! documentation@fauna.com

Thank you for your feedback!