Feature request: 'count' property on relationships

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
}

Yeah, what you were really looking for is remote types:

https://dgraph.io/docs/graphql/custom/directive/#how-dgraph-processes-custom-results

Instead of creating a new schema in the database, a remote type is a pseudo type just for the custom dql to return the GraphQl properly. This is not clear at all in the docs, and a rather advanced technique.

There should be @remote fields on real types, but that does not exists for the moment.

J