To address the specific case that you have: comments by authors with firstName = “Something”
The solution is similar whether you are using GraphQL or not, but it’s a bit easier to get nested results in a nice shape with GraphQL, so we can start there.
With GraphQL
You can add an @index
Query field to the schema to create a filter by the Author’s firstName field. Remember, the name doesn’t matter: the arguments and the return type dictate how the index get’s defined.
type Query {
authorsByFirstName(firstName: String!): [Author] @index
}
Technically, the @index
part is redundant, since Query fields without any directives default to using @index
underneath.
This will generate an Index as if you run this in the shell:
CreateIndex({
name: "authorsByFirstName", // same as field name
source: Collection("Author"), // same as result type
terms: [ // terms match the arguments provided
{ field: ["data", "firstName"] },
]
// note that there are no `values` specified.
})
Then you can query the Authors by first name and use a nested selection to fetch the related Comments
{
authorsByFirstName(firstName: "Paul", _size: 10) {
data {
_id
firstName
lastName
comments(_size: 10) {
data {
_id
message
}
}
}
}
}
Without GraphQL
You can write a very similar query directly with FQL. Returning nested results with FQL is verbose, but is straightforward once you get the hang of it.
Using the @relation
directives created an Index for us. We will need to use that directly with the FQL-only approach.
CreateIndex({
name: "comment_author_by_author",
source: Collection("Comment"),
terms: [
{ field: ["data", "author"] }
]
})
This index let’s us traverse the relationship from an Author to all of its related Comment Documents, since the author ref is stored in the Comment Collection.
Let(
{
firstName: 'Paul',
authorsPage: Paginate(
Match(Index('authorsByFirstName'), Var('firstName')),
{ size: 10 }
),
},
{
authorsByFirstName: Map(
Var('authorsPage'),
Lambda(
'ref', // Author Ref
{
author: Get(Var('ref')),
comments: Paginate(
Match(Index('comment_author_by_author'), Var('ref')),
{ size: 10 }
),
}
)
),
}
)
here, I’ve not really nested the comments within the author Documents, but just stuck them next to each other. I think this was just easier to demonstrate quickly. But you can use Merge
and Select
functions to nest Documents and even be selective about which fields you return, similar to GraphQL.