Any way to filter by dynamic zone?

System Information
  • Strapi Version: 4.4.5
  • Operating System: Alpine Linux
  • Database: Postgres
  • Node Version: 16.x
  • NPM Version: NA
  • Yarn Version: 1.22.19

I am trying to use strapi query to filter dynamic zone but unlucky seems it dosen’t support.

Example collection

My code

const result = await strapi.db.query('api::xxx.xxx').findMany({
      where: {
        period: {
__component: "routine"
}
      },
      populate: ['period'],
    })

Ran into the same thing today.

It seems that any filters on dynamic zones are completely ignored (based on my testing).

If anyone from the Strapi team has any suggestions here I’d love to hear it.

What I’ve started into doing now is writing my own db-level queries via the knex instance which is accessible via strapi.db.connection (connection is the knex instance itself).

Unfortunately the Typescript types for strapi.db don’t include connection (might be updated on a newer version, I’m on version 4.3.3.

So I’m accessing it and running knex queries like:

                        const db = strapi.db as any;
                        const knex = db.connection;
                        const rows = await knex('table_name')
                            .where({
                            some: "param"
                        })
                            .select({
                            id: "id",
                            other: "fields"
                        });

The knex variable assignment to db.connection is not necessary but just showing that’s the knex instance.

Will update when I figure out how to dynamically determine table names from a component’s model definition. That’ll be tomorrow.

So nobody find a solution for filter dynamic zone with entity service api?

Hello, any news? :slight_smile:

I don’t believe it’s possible to filter on dynamic zones using either the Entity Service API or the Query Engine API.

The easiest way to accomplish a filter on a dynamic zone would be to populate the fields you need from the dynamic zone on a .findMany() request and then filter manually (i.e. use .filter on the returned array). Obviously, this could be a major performance problem if you have a lot of entries in your dynamic zone but if this approach would work fine.

The other option is to use the underlying knex instance to run your own sql queries using the knex query builder functions. But each component type in your dynamic zone lives in a different table so you need to do multiple joins to be able to use a where clause on the component’s attributes.