Вывести несколько элементов из массива с объектами
У меня есть collection:
{
"_id": {
"$oid": "5f84ffad51d91fa6247b17e6"
},
"chat_id": 1,
"status": true,
"members": [{
"user_id": 2436324243,
"rank": 1
}, {
"user_id": 2346246243,
"rank": 2
}, {
"user_id": 2634243643,
"rank": 1
}, {
"user_id": 2634634234,
"rank": 0
}],
"groups": [...]
},
{
"_id": {
"$oid": "5f84ffad51d91fa6247b17e7"
},
"chat_id": 2,
"status": true,
"members": [{
"user_id": 1526236,
"rank": 1
}, {
"user_id": 13242664,
"rank": 2
}, {
"user_id": 12315161,
"rank": 1
}, {
"user_id": 21362463,
"rank": 0
}],
"groups": [...]
}
Я хочу получить из chat_id = 2 массив объектов members, там где members.rank >= 1
Ответ должен выглядеть для выше указанных данных так:
{ "members" : [{
"user_id": 1526236,
"rank": 1
}, {
"user_id": 13242664,
"rank": 2
}, {
"user_id": 12315161,
"rank": 1
}]
}
Пробовал
db.chats.find({"chat_id": 2, "members": {"$elemMatch": {"rank" : {"$gte": 1}}}}, {"_id": 0, "members.$":1})
Но оно возвращает только один объект
Ответы (1 шт):
Автор решения: Exploding Kitten
→ Ссылка
У вас несколько ошибок в запросе.
"members.$": 1 вернет первый элемент в найденном массиве, если вы его уберете, то вам будет возвращаться полноценный массив:
"members": [{
"user_id": 1526236,
"rank": 1
}, {
"user_id": 13242664,
"rank": 2
}, {
"user_id": 12315161,
"rank": 1
}, {
"user_id": 21362463,
"rank": 0
}],
но тут будет содержаться лишний элемент. Это происходит из-за того, что $elemMatch выбирает те объекты, у который в массиве хотя бы один элемент удовлетворяет условию > 1.
Это можно решить при помощи aggregate, например, так:
db.collection.aggregate(
{
$match: {
"chat_id": 2
// выбираем нужные нам документы
}
},
{
$unwind: "$members"
// выводим каждый элемент массива как отдельный документ
},
{
$match: {
"members.rank": {
"$gte": 1
}
// выбирает нужные элементы по rank
}
},
{
"$group": {
"_id": "$_id",
"members": {
"$push": "$members"
}
// группируем элементы обратно в виде одного массива
}
})
или так:
db.collection.aggregate(
{
$match: {
"chat_id": 2
}
},
{
$unwind: "$members"
},
{
$match: {
"members.rank": {
"$gte": 1
}
}
},
{
$project: {
_id: 0,
user_id: "$members.user_id",
rank: "$members.rank"
}
}
)