Gergő Horváth
Gergő Horváth

Reputation: 3705

Check if all matching elements match the criteria

For example we have the next dataset:

balls = [
  {
    _id: 0,
    color: 'red',
    size: 10,
    available: true,
  },
  {
    _id: 1,
    color: 'red',
    size: 15,
    available: false,
  },
  {
    _id: 2,
    color: 'blue',
    size: 10,
    available: true,
  }
]

I want to run a query like:

balls.every({ color: 'red' }, { available: true }); // should return false
balls.update({ color: 'red', available: false }, { available: true }); // set unavailable red ball to true
balls.every({ color: 'red' }, { available: true }); // should return true

in a sort of .every(query, condition) type. If the documents returned from query are all matching the condition, return true, otherwise false.

Otherwise, I would have to get all matching documents, and then manually checking if all of them are available. I could save those steps with a solution like the above, and it would be less expensive.

Upvotes: 1

Views: 116

Answers (1)

turivishal
turivishal

Reputation: 36144

  • Every function to execute find query and check all available is true by every function,
  • Or use aggregation query to return one document with all available status
async function _every(query, condition) {
  let result = await balls.find(query, { _id: 0, available: 1 }).lean();
  return (
    result.length > 0 &&
    result.every(e => e.available === condition.available)
  );
}

// OR

async function _every(query, condition) {
  let result = await balls.aggregate([
    { $match: query },
    {
      $group: {
        _id: null,
        available: { $push: "$available" }
      }
    }
  ]);
  return (
    result.length > 0 &&
    result[0].available.every(e => e === condition.available)
  );
}
  • Update function to execute updateMany query:
async function _update(query, condition) {
  await balls.updateMany(query, { $set: condition });
}

You can execute your query like:

await _every({ color: 'red' }, { available: true }); 
await _update({ color: 'red', available: false }, { available: true }); 
await _every({ color: 'red' }, { available: true }); 

Upvotes: 1

Related Questions