Search code examples
reactjsgraphqlapollo-servergqlfaunadb

Cannot return documents based off a sorted index using Fauna DB


I'm bumbling my way through adding a back-end to my site and have decided to get acquainted with graphQL. I may be structuring things totally the wrong way, however from following some tutorials I have a React front-end (hosted on Vercel), so I have created an api folder in my app to make use of Vercel's serverless functions. I'm using Apollo server and I decided to go with Fauna as my database.

I've successfully been able to return an entire collection via my API. Now I wish to be able to return the collection sorted by my id field.

To do this I created an index which looks like this:

{
  name: "sort_by_id",
  unique: false,
  serialized: true,
  source: "my_first_collection",
  values: [
    {
      field: ["data", "id"]
    },
    {
      field: ["ref"]
    }
  ]
}

I then was able to call this via my api and get back and array, which simply contained the ID + ref, rather than the associated documents. I also could only console log it, I assume because the resolver was expecting to be passed an array of objects with the same fields as my typedefs. I understand I need to use the ref in order to look up the documents, and here is where I'm stuck. An index record looks as follows:

[1, Ref(Collection("my_first_collection"), "352434683448919125")]

In my resolvers.js script, I am attempting to receive the documents of my sorted index list. I've tried this:

async users() {
    const response = await client.query(
            q.Map(
                q.Paginate(
                    q.Match(
                        q.Index('sort_by_id')
                    )
                ),
                q.Lambda((ref) => q.Get(ref))
            )
        )

        const res = response.data.map(item => item.data);
        return [... res]
}

I'm unsure if the problem is with how I've structured my index, or if it is with my code, I'd appreciate any advice.


Solution

  • It looks like you also asked this question on the Fauna discourse forums and got an answer there: https://forums.fauna.com/t/unable-to-return-a-list-of-documents-via-an-index/3511/2

    Your index returns a tuple (just an array in Javascript) of the data.id field and the ref. You confirmed that with your example result

    [
      /* data.id */ 1, 
      /* ref     */ Ref(Collection("my_first_collection"), "352434683448919125")
    ]
    

    When you map over those results, you need to Get the Ref. Your query uses q.Lambda((ref) => q.Get(ref)) which passes the whole tuple to Get

    Instead, use:

    q.Lambda(["id", "ref"], q.Get(q.Var("ref")))
    
    // or with JS arrow function 
    q.Lambda((id, ref) => q.Get(ref))
    

    or this will work, too

    q.Lambda("index_entry", q.Get(q.Select(1, q.Var("index_entry"))))
    
    // or with JS arrow function 
    q.Lambda((index_entry) => q.Get(q.Select(1, index_entry)))
    

    The point is, only pass the Ref to the Get function.