Mongodb 在mongo中对组进行子排序?

Mongodb 在mongo中对组进行子排序?,mongodb,Mongodb,我在mongo有这个收藏: [ { "key": "guitar", "name": "john" }, { "key": "guitar", "name": "paul" }, { "key": "guitar", "n

我在mongo有这个收藏:

[
  {
    "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总是唯一的,我正在纠正这一点。