Mongodb: найти документы с массивом, где все элементы существуют в массиве запросов, но массив документов может быть меньше
У меня есть коллекция в моей базе данных, где большинство документов имеют поля массива. Эти массивы содержат ровно 2 элемента. Теперь я хочу найти все документы, в которых все эти элементы массива являются элементами моего массива запросов.
Примеры документов:
{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] },
{ a:["1","4"] }
Массив запросов:
["1","2","3"]
Запрос должен найти первые 3 документа, но не последний, так как в моем массиве запросов нет "4".
Ожидаемый результат:
{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] }
Ждем полезного ответа:).
3 ответа
Поскольку размер статический, вы можете просто проверить, что оба элемента находятся в [1,2,3];
db.test.find(
{ $and: [ { "a.0": {$in: ["1","2","3"] } },
{ "a.1": {$in: ["1","2","3"] } } ] },
{ _id: 0, a: 1 }
)
>>> { "a" : [ "1", "2" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "3" ] }
РЕДАКТИРОВАТЬ: Делать это динамически немного сложнее, я не могу придумать способ без структуры агрегации. Просто посчитайте совпадения как 0 и не совпадения как 1, и, наконец, удалите все группы, которые имеют сумму!= 0;
db.test.aggregate(
{ $unwind: "$a" },
{ $group: { _id: "$_id",
a: { $push: "$a" },
fail: { $sum: {$cond: { if: { $or: [ { $eq:["$a", "1"] },
{ $eq:["$a", "2"] },
{ $eq:["$a", "3"] }]
},
then: 0,
else: 1 } } } } },
{ $match: { fail: 0 } },
{ $project:{ _id: 0, a: 1 } }
)
>>> { "a" : [ "1", "3" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "2" ] }
Я также думаю, что это невозможно без структуры агрегации (если количество элементов является динамическим). Но я нашел более универсальный способ сделать это:
db.tests.aggregate({
$redact: {
$cond: {
if: {$eq: [ {$setIsSubset: [ '$a', [ "1", "2", "3" ] ]}]},
then: '$$KEEP',
else: '$$PRUNE'
}
}
})
Я считаю, что ответом на вашу проблему является использование
$ в
(из документов:)
Рассмотрим следующий пример:
db.inventory.find ({qty: {$in: [5, 15]}})
Этот запрос выбирает все документы в инвентаре, где значение поля qty равно 5 или 15. Хотя этот запрос можно выразить с помощью оператора $ или, выберите оператор $in вместо оператора $ или при выполнении проверок на равенство поле.
Вы также можете делать более сложные вещи, используя массивы. Оформить заказ: http://docs.mongodb.org/manual/reference/operator/query/in/