Need a total count returned with GraphQL queries
Do you want to request a feature or report a bug?
Feature
What is the current behavior?
When querying collections, ie:
query testNodesQuery {
testNodes(first: 10, skip: 0) {
id
name
}
}
There is no way to determine the total number of query results. It's possible to page through until we reach a page where the result count is less than the first param, but it's extremely cumbersome.
What is the expected behavior?
I'd suggest a result object:
type TestNode @entity {
id: ID!
name: Bytes
}
type TestNodesResult {
totalCount: Int!
skip: Int
first: Int
result: [TestNode!]!
}
type Query {
testNodes(...): TestNodesResult!
}
Hi @asselstine, the way we do pagination is likely to be improved in the future, potentially to something based on cursors. Supplying counts only for the sake of pagination might not be the most efficient. You can see more context in issue #613, in particular this comment has a good example of how to implement pagination in your application.
The technique in the comment simply describes scraping the query until no more results are returned. It's not ideal.
For a future implementation the cursor technique does sound more efficient. However, since we're already using skip and first it would make sense to also provide a count.
In the meantime I will likely create a separate "PaginationInfo" entity and just increment and decrement the counts manually when I create new entities.
The technique in the comment simply describes scraping the query until no more results are returned. It's not ideal.
To clarify, why is it not ideal for your use case? Do you want to have the total count to display in your UI?
Basic pagination my friend!
We are using the Graph to display all the users who hold tickets for a prize. Right now we have about 1000 users.
You can see our new UI here: https://app.pooltogether.us/prizes/6
We'd like to add standard pagination controls. Something like:
First Prev 2 3 4 5 10 20 30 Next Last
The list is sorted by the chance to win, so it would be fun to skip to the end and see what the smallest chances were, or vice versa. Especially once we let people sort the list as they wish.
For now I can calculate the totals myself and store them in another object, but it's not ideal and seems like something that should be provided by the infrastructure (like a database).
I see that you're using queries of size 10, which is the size of your UI page. Considering that currently you have about 1000 users, and the maximum value for first is 1000, it seems viable for you to get all the data in just two queries, once you have that on the client you can know the count and split it into pages without additional queries. Don't know if it's the best for your use case, but it's an alternative.
I understand the scraping solution; it was mentioned previously.
My point is that it's an inefficient hack. We shouldn't have to load N * 1000 queries over the wire just to get a count. If we select just the identifiers in that query then that's 32 kb per call (256 bits * 1000 / 8). Plus, there might be more than one call.
Anyway, I hacked around it myself by incrementing a counter field on an entity in our schema.
I wouldn't call it an inefficient hack, there's a tradeoff between number of requests, size of each requests, requesting data that potentially won't be needed vs having the data ready in case you need it. Paging is hard. Anyways, if you choose to use a count, having it in the schema is actually a good solution, count queries are slower than you might think. None of this excuses us from having a count query feature, of course.
I also have same problem in our project. If we don't use any where clause, we can simply save total count in a schema and use that, but we are using complex where clause and it's impossible to save all count of items filtered by each queries.
I want to request a feature that you can provide in the following way.
// assume I have entity like this type Token @entity { ID String! price BigInt! }
// then we can query like this query { tokens(where: {price_gt:"30"}) { ID } }
// in this case can we use like this? query { countOf: tokens(where: {price_gt:"30"}) { count } tokens(where: {price_gt:"30"}, first:1000) { ID } } // if we use special alias like "countOf", can you return one entity that has field count?
I think it's not too difficult to add this feature in your dev team. If you guys don't have time, I can work with you to add this feature. Thanks
Many websites show the total count with a facet panel or search panel. There should be a way to get a count for queries.
@leoyvens Have you noticed @lclement927's offer of help?
None of this excuses us from having a count query feature, of course.
@leoyvens I too would like this feature. I see that this issue is closed so is that feature tracked somewhere else? If not, could this issue be reopened to track it?
Thanks.
Yeah, it is a important feature, but graph-node doesn't have it yet
Hi, any updates on this? the counter is an important feature, after all we get the data to eventually display it in a frontend app
hey @asselstine @Chriton we have been discussing adding support here cc @lutter, and @dotansimha & @saihaj looking in the context of pagination
hey @asselstine @Chriton we have been discussing adding support here cc @lutter, and @dotansimha & @saihaj looking in the context of pagination
Hey @azf20 I don't see any link added
We shouldn't have to load N * 1000 queries over the wire just to get a count.
It really is weird. Hopefully some update in the works...? 👀
Any updates on this? 😢
Any updates? or any efficient quick workaround?
If this was as completed, how can the feature be used?
Perhaps this should have been closed as "outdated".
@PaulRBerg yeah that was the intention ("outdated"), I haven't been using the specific types of "closing" yet sorry if that was confusing.
I did a big pass yesterday to categorize and cleanup all our issues, so the existing issues will be easier to parse and give attention to discussion. There were a lot of them, so bear with me if I was too eager to close some.