Motivation
Although, there exists a count functionality to count number of matched nodes or predicates in DQL, Dgraph GraphQL currently does not support count
.
This feature of supporting count
in Dgraph GraphQL has been requested by Users many times. Here are some of the related discuss posts:
- Add @count to GraphQL schemas and queries
- Fetch all counters with GraphQL API
- Count lists
- Will Dgraph GraphQL be supporting GraphQL+- capability such as count() and sum()?
- Group nodes by a literal and count the number of categories
This RFC is about supporting count
natively with Dgraph GraphQL .
User Impact
Users will now be able to use count functionality of DQL in Dgraph GraphQL.
Implementation
There are two ways in which count
is used in DQL.
-
count(uid)
counts the number of UIDs matched in the enclosing block. -
count(predicate)
counts how manypredicate
edges lead out of a node.
Count
in GraphQL will also support this two ways.
Count matched UIDs
Example GraphQL Schema:
type Data {
id: ID!
name: String!
intList: [Int]
stringList: [String]
metaData: [Data]
}
The above input GraphQL schema will generate an additional countData
query in the output schema as follows:
query {
countData(filter: DataFilter): Int
}
The input type to the countFilter
query, DataFilter
will be the same as input type of queryFilter
. The countFilter
query will return the number of matched UIDs satisfying the filter
condtition.
The above count
GraphQL query would be rewritten to the following DQL query.
query {
queryData(func: type(Data)) @filter(/* rewritten filter condtition */)) {
count: count(uid)
}
}
Count predicate edges
For every field in input schema which is of type list, an extra field will be generated in output schema to store its count. These extra fields will be utilized to return the count of predicate edges.
The example input schema:
type Data {
id: ID!
intList: [Int]
stringList: [String]
metaData: [Data]
}
will generated the following extra fields in output schema.
countintList: Int
countstringList: Int
countmetaData: Int
These fields could be used with queryData
and getData
queries to return count of predicate edges as follows.
query {
queryData {
name
countintList
countmetaData
}
}
The above query would be rewritten to DQL as follows.
query {
queryData(func: type(Data)) {
Data.name
count(Data.intList) /* returns number of items in intList*/
count(Data.metaData) /* returns number of items in metaData list*/
}
}
Open Questions
- Should count be enabled by default for all Graphql Schemas or should there be an option to enable
count
queries andcount
fields for the types and predicates which are specified by the User. - Should we be supporting filtering on count predicate edges. For example, should there be an option to filter out only some of the
Data
frommetaData
and return a count of it.
Count Queries on other GraphQL platforms
- Hasura has support for counting predicate edges using their aggregation queries on aggregate fields like
sum
,count
,avg
. - GraphQL does not natively support
count
. There are some other platforms which recommend storing of a count attribute manually and updating it every time data is updated to supportcount
functionality.