Search code examples
next.jsfaunadb

How to query by data within a collection document in Fauna?


I'm looking for a way to query all users using the index users_filtered if isApproved: true. I'm using Fauna as a database within my Next.js project. I've added isApproved as a term for the index users_filtered in the Fauna database.

Here is an example of a document within the users collection:

{
  "ref": Ref(Collection("users"), "328571711165938374"),
  "ts": 1649676683111000,
  "data": {
    "givenName": "Leo",
    "familyName": "Deo",
    "isApproved": true
  }

Here is my current function which queries all documents using the index users_filtered

const getFilteredUsers = async () => {
  const { data } = await faunaClient.query(
    q.Map(
      q.Paginate(q.Match(q.Index("users_filtered"))),
      q.Lambda("userRef", q.Get(q.Var("userRef")))
    )
  )

  const filtered = data.map((x) => {
    x.data.id = x.ref.value.id
    x.data.ts = x.ts
    return x.data
  })
  return filtered
}

Index definition:

Source Collection: users

Index Name: users_filtered

Terms: isApproved

Values: None defined

How can I query for all documents containing the isApproved: true?


Solution

  • Your index definition seems a bit curious. It looks like you're reporting the values displayed in the Dashboard, but if so, the terms definition is incorrect: it should be data.isApproved. Via FQL, you should see something like:

    > Get(Index("users_filtered"))
    {
      ref: Index("users_filtered"),
      ts: 1649779238270000,
      active: true,
      serialized: true,
      name: "users_filtered",
      unique: false,
      source: Collection("users"),
      terms: [
        {
          field: ["data", "isApproved"]
        }
      ],
      partitions: 1
    }
    

    If you left out data. by accident, then your index definition could be correct and you should be able to proceed.

    When an index has a terms definition, that definition specifies how the index can be searched. With the isApproved field as a term, then you have to specify which value of isApproved that you're looking for in your Match expression. For example:

      const { data } = await faunaClient.query(
        q.Map(
          q.Paginate(q.Match(q.Index("users_filtered"), true)),
          q.Lambda("userRef", q.Get(q.Var("userRef")))
        )
      )
    

    When I create the user document that you described, the query's result is:

    {
      data: [
        {
          ref: Ref(Collection("users"), "328750455338304000"),
          ts: 1649779715770000,
          data: { givenName: 'Leo', familyName: 'Deo', isApproved: true }
        }
      ]
    }