Offset pagination with total count

Hello,

I am using neo4j-graphql.js' augmented schema. So I have pagination out of the box with first and offset. (Thanks!) However, I am struggling to get the total count so the UI can show the pages.

I've seen a lot of connection or relay pagination examples. However, I haven't found an offset tutorial that includes the total count. Does anyone know of one? Or have a working example they are willing to share?

1 Like

Hi Chad,
Can you paste a snippet of what you currently have?

You could probably just remove that "first and offset". I removed those for my projects so I would query everything. However, it would be helpful to see a snippet of what you have at the moment.

Most GraphQL Schemas, have queries to get the results, and other to get the total Count of records, this is for pagination, and knowing the total amount of data, without retrieving the data, here there's an example:

{
  Employees(
    filter: { OR: [{ name_contains: "Mar" }, { email_contains: "Mar" }] }
    first: 10
    orderBy: [name_asc]
  ) {
    _id
    email
    name
  }
  EmployeesCount(
    filter: { OR: [{ name_contains: "Mar" }, { email_contains: "Mar" }] }
  )
}

No sorting or paging should be implemented in the Count queries, but yes the rest of the filters.

I also hope they implement this feature.

Thanks.

Are these Count queries somehow able to be generated by neo4j-graphql.js augmented schema? It would be a great feature otherwise. It is very common to want to get a fast count on a query before actually retrieving all the data.

We currently have to write custom cypher queries for this which takes more time.

1 Like

To get the total count, you can define a custom query that contains a cypher directive. The resolver will be automatically generated by grandstack:

type Employee {
...
}

// Let's say I want the total number of employees:

type Query {
   EmployeeCount: Int
        @cypher(
            statement: "MATCH(n: Employee) RETURN count(n)"
        )
}
2 Likes

Yes, but what if you are using built in filtering ?

then count of total entities and count of filtered will be different.

how to get count of the current query results ?

I've found one solution to have totalCount query while using auto-generated queries.
Its a bit hacky, but works.

Lets say you have such type definition:

type Question  {
  nodeId: ID! @id
  title: String!
  text: String!
  totalCount: Int # will be used to implement total count on query resolver
}

And you can make such query type definition:

type Query {
	QuestionCount: Question  # only `totalCount` field will be actually resolved
}

Then create such custom query resolver:

import { cypherQuery } from 'neo4j-graphql-js'

const questionResolvers = {
		QuestionCount: async (_parent, params, context, resolveInfo) => {

             // generating querystring with all necessary filters and params
			const [queryString, queryParams] = cypherQuery(params, context, resolveInfo)

            // using neo4j-graphql driver injected in context to perform custom call
			const resultsCount = await context.driver
				.session()
				.run(queryString, queryParams)
				.then((res) => res.records.length) // getting count of the results

			const requiredFieldsMessage =
				'### Only `totalCount` field can be resolved with this query'

			return {
				nodeId: requiredFieldsMessage, // fields required in type definitions have to be resolved somehow
				title: requiredFieldsMessage, // fields required in type definitions have to be resolved somehow
				text: requiredFieldsMessage,// fields required in type definitions have to be resolved somehow
				totalCount: resultsCount, // <--- Here you get your results total count
			}
		},
}

After implementing above code you can query api with following graphql query:

query{
  Question(filter:{
    title_contains:"a" # your filters
  }){
    nodeId
    title
    text
  }
  QuestionCount(filter:{
    title_contains:"a" # <-- repeat your filters for count query
  }) {
      totalCount
    }
}

And you will get following result:

{
  "data": {
    "Question": [
      {
        "nodeId": "aeede919-4e01-4946-a13d-172702e4997a",
        "title": "Question containing 'a' letter 1",
        "text": "Question containing a letter 1"
      },
      {
        "nodeId": "5a17bd7c-74f9-4c64-ad7d-9f2675d31fe3",
        "title": "Question containing 'a' letter 2",
        "text": "Question containing 'a' letter 2"
      },
    ],
    "QuestionCount": {
      "totalCount": 2
    }
  }
}

I'm sure original neo4jgraphql() call to database also can return count() under the hood, but it is not so easy to get it out from there.

Any way, above solution works for me, hope it will help to you also.

How would this translate to the new @neo4j/graphql library where we do not have this cypherQuery ?