Incorrect total in meta pagination when filtering

System Information
  • Strapi Version: 4.1.2
  • Operating System: Mac
  • Database: MySQL
  • Node Version: v14.18.3
  • NPM Version: 6.14.15
  • Yarn Version: 1.22.17

I have a model called ‘Articles’ and a model called ‘Tags’ - The relationship between the two is “Articles
has and belongs to many Tags”.

I currently have 2 articles in the database - one has 2 tags, the other has just one.

When querying with with the rest API or GraphQL to filter by tags in the result in the pagination is incorrect.

query {
 articles(pagination:{pageSize:100} filters: {tags:{id: {in:[1,2]}}}) {
  meta {
    pagination {
      total
      pageSize
    }
  }
    data {
      id
      attributes {
        title
      }
    }
  }
}

The total in meta > pagination is 3 not the expected 2.

{
  "data": {
    "articles": {
      "meta": {
        "pagination": {
          "total": 3,
          "pageSize": 100
        }
      },
      "data": [
        {
          "id": "739",
          "attributes": {
            "title": "I am a project"
          }
        },
        {
          "id": "740",
          "attributes": {
            "title": "I am a project"
          }
        }
      ]
    }
  }

This is also occurring when using the following code

 const [entries, count] = await strapi.db
    .query("api::article.article")
    .findWithCount({
      select: ["title"],
      where: {
        topics: { id: { $in: [1, 2] } },
      },
    });

Is this a bug or am I doing something wrong?

Hi, any news?

@tod97 Yes check out this thread Count Metadata doesn't take filtering into account · Issue #7631 · strapi/strapi · GitHub

It is frozen alike, with no news.

You can see here that a fix has been found Count Metadata doesn't take filtering into account · Issue #7631 · strapi/strapi · GitHub and a pull request has been created here fix(count): fix count in query with join by mithenks · Pull Request #13480 · strapi/strapi · GitHub so hopefully this will be fixed soon

Two years for getting fixed. I got it.

And it is still not fixed.

I think my post is related am i wrong ?

did we found any solution for this.
It looks like when we try to filter nested properties, metapagination is totally incorrect

@Jim_Wiberley @LuisAlaguna

@DMehaffy Three years and we still have this issue.

I’m not sure if this is related to your issue or the cause of it but I’d like to put it here in case someone experiences something similar in the future.

I had an issue with this when using Strapi graphql plugin and I realized while the linked GitHub issue by Jim has been fixed, pagination total count was still broken. So it had to be from the Strapi graphql plugin. Turns out it was from the toEntityResponseCollection method provided by the plugin, which works this way:

return toEntityResponseCollection(data, {
            args,
            resourceUID: entityType,
          });

The method works well when you pass your query variables (args.filters) as the only filters to your find operation. It doesn’t return the right count when you add an extra check or condition. This can be found in the graphql plugin code base here.

I got this to work by using the findWithCount method which returns the right count for me, passing it into the args object used by the toEntityResponseCollection method, and extending the RESPONSE_COLLECTION_META_TYPE_NAME type to use a total value if available into the args object (otherwise default to the usual method).

In the register method of the index.js file

    const extension = ({ nexus }) => ({
      types: [
        nexus.extendType({
          type: RESPONSE_COLLECTION_META_TYPE_NAME,
          definition(t) {
            t.nonNull.field("pagination", {
              type: PAGINATION_TYPE_NAME,

              async resolve(parent) {
                const { args, resourceUID } = parent;
                const { start, limit, total } = args;
                const safeLimit = Math.max(limit, 1);

               // https://docs.strapi.io/dev-docs/backend-customization/controllers#sanitization-when-utilizing-controller-factories (You probably don't need this line in earlier versions of strapi and you can use args directly in place of sanitizedQuery)
                const sanitizedQuery = await sanitize.contentAPI.query(args, parent.contentType, {
              auth: ctx?.state?.auth,
            });

                const count =
                  total ||
                  (await strapi.entityService.count(resourceUID, sanitizedQuery));
                const pageSize = limit === -1 ? count - start : safeLimit;
                const pageCount =
                  limit === -1 ? safeLimit : Math.ceil(count / safeLimit);
                const page =
                  limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;

                return { total: count, page, pageSize, pageCount };
              },
            });
          },
        }),
      ],
    });

    extensionService.use(extension);

Then in your resolver for your query - You can learn to extend queries and create resolvers in this article - return your data this way:

const transformedArgs = transformArgs(args, {
    contentType: strapi.contentTypes[entityType],  
    usePagination: true,
});

const data = await strapi.db.query(entityType).findWithCount(filters);

return toEntityResponseCollection(data[0], {
  args: {
  // you can just spread the transformedArgs but I'm adding start and limit here for better visualization
  start: transformedArgs.start,
  limit: transformedArgs.limit,
  total: data[1], // this will be returned if provided and you can pass the right count returned from findWithCount here
   ...transformedArgs,
},
resourceUID: entityType,
});

1 Like

And this code solves the meta count issue, right?