Allow @index directive to work with Indexes defining values other than All

Fauna relies on your feedback to educate our product development process. To help us prioritize this feature in our product roadmap, please vote for this topic and complete our 2020 GraphQL Roadmap Survey.

Issue description

At the moment, it is not possible to directly associate a query with an Index that defines values other than “All”.

Proposal

We could make the resolver backing the @index directive a bit smarter, allowing you to call such Indexes properly. The limitation of the current implementation is that the resolver always expects a single Ref value (which is the proper response when calling an Index with All values), but when defining custom values, the response format is an Array.

For example, if you have the following existing Index (which defines values with an special ordering):

{
  "ref": Index("topSongStats"),
  "ts": 1573843043830000,
  "active": true,
  "serialized": true,
  "name": "topSongStats",
  "source": Collection("SongStats"),
  "values": [
    {
      "field": [
        "data",
        "claps"
      ],
      "reverse": true
    },
    {
      "field": [
        "ref"
      ]
    }
  ],
  "partitions": 8
}

After importing the following schema:

type SongStats {
  spotifyId: String!
  claps: Int
}

type Query {
  topSongStats: [songStats!] @index(name: "topSongStats")
}

When calling the topSongStats query, it should call the topSongStats Index without any further work (right now, it needs a UDF in the middle to work).

Workaround

With the current implementation, you need to create a UDF along with the Index, as explained here. If you have implemented your own UDFs that you think could help other users with this, please share them as replies to this topic and/or make a gist and link to it from the awesome-faunadb list.

Is this more about an index that returns a sorted list of documents? I’m not quite following the title… So the only way to sort documents is to include the sorted field in the index values, which then breaks the built-in GQL pagination.

I think a feature that would be a little more general would be to have a special behavior for resolvers that return a Set (e.g. from a Match statement). 1000% bonus points if you can use this resolver anywhere in the schema (on the field of a custom type). The idea is that if I return a Set, the GQL API can handle the pagination and even a Count aggregation out-of-the-box, and this allows the flexibility of anything I can accomplish using a UDF, rather than needing to support every Index use case, eventually support Join use cases, etc etc. If I get into a resolver, I can write arbitrarily complex queries that return a Set based on the args. Then you just need to deal with other limitations of Fauna, such as how can I map a Set to the second value column without first paginating it. Which I guess brings us back around to… Maybe GQL does need to handle automatically finding the ref in the paginated results, OR… we need both a @resolver directive to return a custom Set, in combination with a @map directive that specifies either a UDF to map the paginated results through, or the path to a field in the paginated results. For the Index example you provided: [1]