С MongoDB 3.6 и новее, вы можете использовать оператор в $expr
в запросе find()
. Это позволяет создавать выражения запросов, которые сравнивают поля из того же документа на этапе $match
.
db.customer.find({ "$expr": { "$eq": [{ "$month": "$bday" }, 9] } })
Для других версий MongoDB, рассмотреть возможность запуска в трубопровод агрегации, который использует $redact
оператора, поскольку это позволяет включить с одного конвейера, функциональность с $project
создать поле, которое представляет месяц поля даты и $match
для фильтрации документов , которые соответствуют заданному состоянию месяца, являющемуся сентябрем.
В приведенном выше описании, $redact
использует $cond
tenary оператора в качестве средства, чтобы обеспечить условное выражение, которое будет создавать системную переменную, которая делает редакции. Логическое выражение в $cond
проверит для равенства поля даты оператора с заданным значением, если это соответствует тогда $redact
будет возвращать документы, используя системный переменную $$KEEP
и выброса в противном случае с помощью $$PRUNE
.
Запуск следующего трубопровода должен дать вам желаемый результат:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$eq": [{ "$month": "$bday" }, 9] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
Это похоже на комбо $project
+ $match
но вы должны затем выбрать все остальное поля, которые поступают в трубопровод:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$project": {
"month": { "$month": "$bday" },
"bday": 1,
"field1": 1,
"field2": 1,
.....
}
},
{ "$match": { "month": 9 } }
])
С другой альтернативы, хотя и медленный запрос, используя метод find()
с $where
как:
db.customer.find({ "$where": "this.bday.getMonth() === 8" })
Вот что мне нужно. Но теперь у меня есть небольшая проблема: «Исключение: невозможно преобразовать из BSON типа EOO в Date» errorCode: 16006 Я считаю, что это потому, что в некоторых документах нет поля bday. Итак, как я могу использовать $ project с оператором $ exists, делающим запрос только с документами, у которых есть поле $ bday? –
Добавьте '$ match' в начало вашего конвейера, который использует' $ exists', чтобы отфильтровать документы перед тем, как перейти к '$ project'. – JohnnyHK
Теперь работает отлично, вот окончательный запрос: https://gist.github.com/lslucas/d95767f8da0013bb92a4 –