My schema (truncated):
type User {
...
}
type Passage {
...
User:User
}
User
does not know anything about Passages
. When a new Passage
is created, it is connected it to a user using { connect: [user id] }
.
I want to retrieve all passages owned by a User
given their ID
.
I created the following index:
The index works as intended when used through the dashboard.
Finally I added the following to my schema:
passageByUser(User:ID):[Passage] @index(name: "passage_by_user")
I am getting a type mismatch error:
Type mismatch: field āUserā defined at object āPassageā has type āUserā.
This would make sense if FaunaDb needed to create the index, but because it exists already I would expect this to be working. What is the proper way to do this?
What I did above was based off the solution to this topic, although not the final proposed solution it allowed me to avoid embedding Passages
directly in the User
documents, which would be ideal.
The error happens because of how the @index works. It expectats that argument names and types match exactly with the fields of the output type. You set your User
argument to an ID
type, but the Passage
user type has field User: User
.
If you want to provide this custom functionality, you will need to use the @resolver
directive, instead of @index
.
That said, I strongly recommend you consider using built in relations before going the custom route.
A more idiomatic approach
You can do this out of the box with GraphQL. You will need to provide a field on the User
for connected Passages
. I know you said that a User
does not know anything about Passages
, but you are in fact querying in that way.
Here is a similar question for querying all Todos
for a given user.
Rather than provide the related ID, the more idiomatic GraphQL approach is to to query the User, then expand the related fields.
The reason that this way is preferred is that the query results represent your actual āgraphā of data. If you create a custom resolver to take an User ID and skip over the user in the results, then you lose your ability to reason about the graph fully. One practical consequence is that you might break your local cache, like what Apollo Client uses, but if you return the whole graph then your cache stays up to date without additional work to link everything together.
type User {
...
passages: [Passage]! @relation
}
type Passage {
...
user:User @relation
}
Then you can immediately query for all Passages
for a given User
{
findUserById(id: "1234") { # <- auto-generated query
_id
# other User fields
passages: {
after # pagination is build in!
data {
_id
# other Passage fields
}
}
}
}
what happens if say, 1 user has 10 million passages? and I want only a subset of them without having to do a for loop on 10M entities? how would that query look like?
Thanks!
Iām not sure I understand what you mean by āa subsetā. Do you mean that you would like to apply an additional filter on the passages, or simply acquire chunks of them at a time?
Pagination is built in to the default generated schema. The default size for Pagination is 64 ā thatās how Fauna works in general. So we can update my example query like the following without changing the schema
{
findUserById(id: "1234") { # <- auto-generated query
_id
# other User fields...
# apply size limit for paginating Passages
passages(_size: 100) {
after # pagination is build in!
data {
_id
# other Passage fields
}
}
}
}
If you want to apply additional filters for your sub-selections, we donāt yet support filters or resolvers on user-type fields yet. That means you would need to create a top level custom resolver to handle the specific logic you desire. If thatās what you need, then I suggest taking another look around the forums and starting a new topic to focus on putting all of those elements together.
EDIT: Actually, it looks like thatās what this one is for Help with nested graphql query
haha yeah, my question was solved thank you @ptpaterson !
1 Like
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.