Given the following schema:
type Parent {
id: ID!
children: [Child] @hasInverse(field: parent)
}
type Child {
id: ID!
parent: Parent!
}
…and assuming that Parent
objects often have thousands of Child
objects, I’d like a way of verifying that a given Parent
has a non-zero number of Child
objects without needing to fetch a giant array of Parent.children
and comparing the length of the array to 0
.
Ideally there should be an automatically available property on relationships for this, e.g.
query getParent(id: uid(0x123)) {
id
children {
count
}
}
In the meantime I’m creating a custom query to solve this, but it’d be great to be able to avoid this complexity.
EDIT: Nevermind, just discovered that there’s an aggregate property, so in my above example, the available aggregate would be:
query getParent(id: uid(0x123)) {
id
children {
childrenAggregate {
count
}
}
}
Relevant documentation: Aggregate Queries - GraphQL
EDIT: Ran into an issue trying to get this to work with a custom query. In error I assumed that I’d be able to use a built-in aggregate inside a custom query, e.g.:
type Query {
queryBlogPostsIndex(first: Int!, offset: Int!, keyword: String!): [BlogPost] @custom(dql: """
query q($first: int, $offset: int, $keyword: string) {
queryBlogPostsIndex(func: type(BlogPost), first: $first, offset: $offset) @filter(regexp(BlogPost.name, $keyword)){
id: uid
isPublished: BlogPost.isPublished
name: BlogPost.name
comments: BlogPost.comments {
id: uid
commentsAggregate {
count
}
}
}
}
""")
}
However, what this results in is just a null
value for commentsAggregate
.
Other attempts to solve this problem led to the following error, which led me to believe that it was possible to use a built-in aggregate query inside a custom query, (which is incorrect).
Error: GraphQL Request Error: Cannot query field "commentsCount" on type "BlogPost". Did you mean "comments" or "commentsAggregate"?
The solution to get this working inside a custom query:
type Query {
queryBlogPostsIndex(first: Int!, offset: Int!, keyword: String!): [BlogPost] @custom(dql: """
query q($first: int, $offset: int, $keyword: string) {
queryBlogPostsIndex(func: type(BlogPost), first: $first, offset: $offset) @filter(regexp(BlogPost.name, $keyword)){
id: uid
isPublished: BlogPost.isPublished
name: BlogPost.name
comments: BlogPost.comments {
id: uid
commentsCount: count(BlogPost.comments) // gotcha: count(comments) will always return 0
}
}
}
""")
}
Also, this ↑ won’t work unless you add commentsCount
property to BlogPost
:
type BlogPost {
id: ID!
isPublished: Boolean!
name: String!
comments: [Comment] @hasInverse(field: blogPost)
commentsCount: Int
}