#mongodb
#mongodb
Вопрос:
У меня есть эта коллекция в монго :
[
{
"key": "guitar",
"name": "john"
},
{
"key": "guitar",
"name": "paul"
},
{
"key": "guitar",
"name": "george"
},
{
"key": "drums",
"name": "ringo"
}
]
Я хочу сначала сгруппировать по «ключу» в порядке возрастания и отсортировать каждую группу по названию (в порядке убывания).
Я уже пробовал это :
db.collection.aggregate([
{
$group: {
_id: "$key",
"projects": {
"$addToSet": "$$ROOT"
},
count: {
$sum: 1
}
}
},
{
$sort: {
"projects.key": 1,
"projects.name": -1
}
},
])
Но это не сортирует name
в guitar
группе :
[
{
"_id": "drums",
"count": 1,
"projects": [
{
"_id": ObjectId("5a934e000102030405000003"),
"key": "drums",
"name": "ringo"
}
]
},
{
"_id": "guitar",
"count": 3,
"projects": [
{
"_id": ObjectId("5a934e000102030405000000"),
"key": "guitar",
"name": "john" // ?????????????????????????
},
{
"_id": ObjectId("5a934e000102030405000001"),
"key": "guitar",
"name": "paul"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"key": "guitar",
"name": "george"
}
]
}
]
Вопрос:
Как я могу отсортировать название элемента группы?
Живая демонстрация: https://mongoplayground.net/p/nXaN76HzLV0
Комментарии:
1. Каким тогда должен быть ожидаемый результат?
2. @KunalMukherjee барабаны, гитара …… и в гитарной группе: я ожидаю увидеть Пола, Джона, Джорджа. (имена в порядке убывания)
3. Почему сортировка по
"project.key"
снова, поскольку ключ должен быть одинаковым, просто сортируйте по"project.name"
4. Я хочу сначала увидеть «барабаны», а затем «гитару». вот почему я сортирую по ключу
5. В настоящее время она находится в том же порядке, который вы указали, верно
Ответ №1:
Если вы хотите использовать $addToSet
, это изменит порядок значений массива, которые мы отсортировали первыми, и вы не сможете упорядочить значение массива, не размотав его (деконструировав массив), вы можете попробовать,
db.collection.aggregate([
{
$group: {
_id: "$key",
"projects": {
"$addToSet": {
name: "$name",
key: "$key"
}
},
count: { $sum: 1 }
}
},
{ $unwind: "$projects" },
{ $sort: { "projects.name": -1 } },
{
$group: {
_id: "$_id",
projects: { $push: "$projects" },
count: { $first: "$count" }
}
},
{ $sort: { "_id": 1 } }
])
Если вы используете $push
вместо $addToSet
, то это сработает,
db.collection.aggregate([
{ $sort: { name: -1 } },
{
$group: {
_id: "$key",
"projects": { "$push": "$$ROOT" },
count: { $sum: 1 }
}
},
{ $sort: { "_id": 1 } }
])
Разница между
$push
и$addToSet
,$addToSet
заменит значение, если оно уже установлено в массиве (в вашем случае $$ROOT всегда будет уникальным) и не будет поддерживать порядок документа,$push
добавит все значение, даже если оно дублируется, но по порядку.
Комментарии:
1. Спасибо. что на самом деле делает unwind? из документов неясно.
2. $ unwind деконструирует массив и добавит все документы массива в root
3. $$ROOT уникален, поэтому $ addToSet ничего не заменит. Единственное отличие от $ push в этом случае заключается в том, что он изменяет порядок элементов.
4. @AlexBlex вы правы, $$ROOT всегда уникален, я исправляю это.