Поэтому, когда вы хотите получить только документы, которые имеют ВСЕ ПОЛЯ , без указания всех их в фильтре, например: { a: {$exists : true}, b : {$exists : true}, c : {$exists : true}}
, тогда это может быть не очень хорошей идеей, технически иначе если у вас есть 10 полей в документе, то было бы неплохо упомянуть все из них в запросе. В любом случае, поскольку вы не хотите перечислять их все - мы можем попробовать этот хак, если он работает хорошо, скажем, если у вас фиксированная схема и скажите, что все ваши документы могут содержать только поля a
, b
& c
(_id
является значением по умолчанию и исключительным), но ничего кроме этих попробуйте:
Если вы можете получить общее количество полей, мы можем проверить количество полей, которое говорит все поля существуют, что-то вроде ниже:
db.collection.aggregate([
/** add a new field which counts no.of fields in the document */
{
$addFields: { count: { $size: { $objectToArray: "$$ROOT" } } }
},
{
$match: { count: { $eq: 4 } } // we've 4 as 3 fields + _id
},
{
$project: { count: 0 }
}
])
Тест: mongoplayground
Примечание: Мы только проверка на наличие полей, но не проверка на ложные значения, такие как null
или []
или ''
для полей. Также это может не сработать для вложенных полей.
На всякий случай, если вы хотите проверить, что все поля существуют в документе с их именами, поэтому, если вы можете передать все имена полей в качестве входных данных, попробуйте запрос ниже:
db.collection.aggregate([
/** create a field with all keys/field names in the document */
{
$addFields: {
data: {
$let: {
vars: { data: { $objectToArray: "$$ROOT" } },
in: "$$data.k"
}
}
}
},
{
$match: { data: { $all: [ "b", "c", "a" ] } } /** List down all the field names from schema */
},
{
$project: { data: 0 }
}
])
Тест: mongoplayground
Ссылка: Агрегационный конвейер
Вы можете попытаться использовать объяснение для проверки эффективности ваших запросов.