Mongodb 在mongo中对组进行子排序?
我在mongo有这个收藏:Mongodb 在mongo中对组进行子排序?,mongodb,Mongodb,我在mongo有这个收藏: [ { "key": "guitar", "name": "john" }, { "key": "guitar", "name": "paul" }, { "key": "guitar", "n
[
{
"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
}
},
])
但它不会对吉他
组中的名称
进行排序:
[
{
"_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"
}
]
}
]
问题:
如何对组项目的名称进行排序?现场演示:如果您想使用
$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
将添加所有值,即使其重复但顺序正确
如果您想使用
$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
将添加所有值,即使其重复但顺序正确
那么预期的输出应该是什么?@KunalMukherjee鼓、吉他。。。。。。在吉他组:我希望见到保罗,约翰,乔治。(名称按描述顺序排列)为什么要按
“project.key”
再次排序?因为键肯定是相同的,只需按“project.name”
排序即可。我想先看“鼓”,然后看“吉他”。这就是我按键排序的原因。它当前的排序顺序与您指定的相同。那么,预期的输出应该是什么?@KunalMukherjee-drums,guitar。。。。。。在吉他组:我希望见到保罗,约翰,乔治。(名称按描述顺序排列)为什么要按“project.key”
再次排序?因为键肯定是相同的,只需按“project.name”
排序即可。我想先看“鼓”,然后看“吉他”。这就是我按键排序的原因。它当前的顺序与您指定的相同。谢谢。放松到底在做什么?文档中不清楚。$unwind将解构数组并在根目录中添加所有数组文档。$$root是唯一的,因此$addToSet不会替换任何内容。在这种情况下,$push的唯一区别是它会打乱项目的顺序。@AlexBlex你是对的,$$ROOT总是唯一的,我正在纠正这一点。谢谢。放松到底在做什么?文档中不清楚。$unwind将解构数组并在根目录中添加所有数组文档。$$root是唯一的,因此$addToSet不会替换任何内容。在这种情况下,$push的唯一区别是它会扰乱项目的顺序。@AlexBlex你是对的,$$ROOT总是唯一的,我正在纠正这一点。