Вернуть все документы, только если все соответствует условиям - PullRequest
0 голосов
/ 12 февраля 2020

В поисках справки по запросу, который возвращает true или false (или пустой массив, если false или аналогичный), мне нужно запросить пару документов by id в коллекции и вернуть true, только если все документы соответствуют запросу, если один или несколько документов не совпадают, мне нужно вернуть ложное значение.

Если документы выглядят так, как показано ниже, с проверенным значением как истина, так и ложь, я бы хотел вернуть значение ложного / пустого массива из запроса, но если проверенное значение истинно во всех, я хочу получить значение true или весь массив обратно .

Если обычный find более подходит, я мог бы использовать это.

Я пробовал с обычным $ match, но он возвращает только совпадающие документы.

Сейчас мне это нравится, но кажется, что это можно сделать лучше?

 const coupons = await CouponModel.find({ id }, { checked: 1, _id: 0 });

 const everyCouponIsChecked = coupons.every(data => data.checked === true);

Спасибо.

Sample data:

[ { _id: 5e43e7831bc81503efa54c61,
    id: 'foo',
    checked: true,
},
{ _id: 5e43e7831bc81503efa54c61,
    id: 'foo',
    checked: true,
},{ _id: 5e43e7831bc81503efa54c61,
    id: 'foo',
    checked: false,
}]


const result = await MyModel.aggregate([
    {
      $match: {
        id: 'foo',
        checked: true,

      },
    },

  ]);

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020

Вы можете использовать стадию $ group с нулевым _id, а затем проверить, все ли проверенные поля верны с оператором $ allElementsTrue .

Вот запрос:

db.collection.aggregate([
  {
    $group: {
      _id: null,
      docs: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $addFields: {
      allTrue: {
        $allElementsTrue: "$docs.checked"
      }
    }
  },
  {
    $project: {
      result: {
        $cond: {
          if: {
            $eq: [
              true,
              "$allTrue"
            ]
          },
          then: "$docs",
          else: "$allTrue"
        }
      }
    }
  }
])

Если какое-либо проверенное поле имеет значение false, результат будет равен false, иначе результат будет равен массиву документов.

Вы можете проверить его здесь

0 голосов
/ 12 февраля 2020

Вы могли бы сделать с запросом, подобным этому

const coupons = await CouponModel.find({ _id:id, checked:true });
const everyCouponIsChecked = coupons.length > 0;
...