Stephan Du Toit
Stephan Du Toit

Reputation: 849

Graphql Filter on Strapi using the "where" method to check if a record contain empty array

Does anyone know how to use the graphql “where” filter method to check if an array contains any items? Currently, I use the following query:

query devices {
  onts(where:{images_null: false}){
    id
    images{
      id
    }
  }
}

which returns:

{
  "data": {
    "onts": [
      {
        "id": "5ebfffa957c09c029fa7831c",
        "images": [
          {
            "id": "5ed3a5040889c464b4e5e07f"
          }
        ]
      },
      {
        "id": "5eccc3bb7c3b9d59351593de",
        "images": []
      },
      {
        "id": "5ece135e7c3b9d59351593df",
        "images": []
      }
    ]
  }
}

As you can see, 2x of the returned records contain empty arrays.
I would like the query to only return records that contain at least one item in the array.

Using Strapi v 3.0.1

Appreciate any assistance.

Upvotes: 1

Views: 3510

Answers (1)

ColaFanta
ColaFanta

Reputation: 1060

It seems like filtering on array field is not so well implemented currently:

https://github.com/strapi/strapi/discussions/6480#discussioncomment-61022

However, there is a workaround for you to try.

First you should know how to write your own GraphQL Resolver on Strapi:

https://strapi.io/documentation/v3.x/plugins/graphql.html#customize-the-graphql-schema

Then here is a simple workaround, you could try below code (assume your model is ont):

resolver: async (obj, options, ctx) => {
  // Get all onts first
  const onts = await strapi.api.onts.services.onts.find()

  // Filter your result
  return onts.filter(ont => ont.images.length > 0)
}

Note that if you need more complicated implementation such as paging and sorting, you will need something like strapi.model to use underlying ORM api:

And your code would look like this (take mongodb as an example)

resolver: async (obj, options, {context}) => {
  const {_start, _limit, _sort} = context  

  // Get your 'onts' from database
  const onts = await strapi.query('ont').model.aggregate([{
        $lookup: {
            from: "ont",
            localField: "_id",
            foreignField: "ont",
            as: "images"
        }
    }, {
        $match: {
            // Your filter here, same as image.length > 0
            'images.0': {$exists:true}
        }
    }, {
        $sort: {_sort}
    }, {
        $skip: parseInt(_start)
    }, {
        $limit: parseInt(_limit)
    }])

  return onts
}

Hope it helps you~!

Upvotes: 2

Related Questions