Почему это не работает?
{"firstName": "John", "cars.carName": "BMW"}
означает «где имя Джон и где по крайней мере одна запись в массиве автомобилей, где carName -« BMW »».Но он возвращает полный документ без массива фильтрации.
{"_id": 0, "cars.carColor": 1}
не проецирует _id, нопроекты carColor всех записей массива автомобилей.
РЕШЕНИЕ
Фактически, вы не можете достичь именно того, что вы хотите, с помощью методов поиска и проекции.Лучше всего добавить оператор проекции $ , например:
db.collection.find({
firstName: "john",
"cars.carName": "BMW"
},
{
_id: 0,
"cars.$": 1
})
**RESULT**
[
{
"cars": [
{
"_id": "...",
"carColor": "silver",
"carModel": "330",
"carName": "BMW"
}
]
}
]
Но у этого метода есть недостатки:
- вы получаете запись всего массива, ине только тот цвет, который вы хотите / нужно
- Возвращается только первая соответствующая запись: если у Джона 2 BMW, будет возвращен только один.
ЛУЧШЕЕ РЕШЕНИЕ
К счастью, MongoDB предоставляет другой способ достижения этой цели, с помощью механизма агрегирования и оператора $ filter :
db.collection.aggregate([
{
$match: {
firstName: "john"
}
},
{
$project: {
cars: {
$filter: {
input: "$cars",
as: "cars",
cond: {
$eq: [
"$$cars.carName",
"BMW"
]
}
}
}
}
},
{
$project: {
_id: 0,
"colors": "$cars.carColor"
}
}
])
Вы можете попробовать этоздесь.
РЕДАКТИРОВАТЬ: Другое решение
вы можете попробовать это тоже, с размоткой / групповые этапы:
db.collection.aggregate([
{
$match: {
firstName: "john"
}
},
{
$unwind: "$cars"
},
{
$match: {
"cars.carName": "BMW"
}
},
{
$group: {
"_id": null,
colors: {
$push: "$cars.carColor"
}
}
}
])