首页 > 解决方案 > 按嵌套数组/对象值(在不同级别上)和 $push 按多个级别过滤 - MongoDB Aggregate

问题描述

我有一个包含多层嵌入子文档的文档,每个文档都有一些嵌套数组。使用 $unwind 和 sort,按天进行降序排序,并使用 push 将每行记录组合成单个数组。此推送仅在一个级别上工作,这意味着它只允许一次推送。如果想在嵌套级别做同样的事情并保留顶层数据,得到“errmsg”:“无法识别的表达式'$push'”。

{
        "_id" : ObjectId("5f5638d0ff25e01482432803"),
        "name" : "XXXX",
        "mobileNo" : 323232323,
        "payroll" : [
                {
                        "_id" : ObjectId("5f5638d0ff25e01482432801"),
                        "month" : "Jan",
                        "salary" : 18200,
                        "payrollDetails" : [
                                {
                                        "day" : "1",
                                        "salary" : 200,
                                },
                                {
                                        "day" : "2",
                                        "salary" : 201,
                                }
                        ]
                },
                {
                        "_id" : ObjectId("5f5638d0ff25e01482432802"),
                        "month" : "Feb",
                        "salary" : 8300,
                        "payrollDetails" : [
                                {
                                        "day" : "1",
                                        "salary" : 300,
                                },
                                {
                                        "day" : "2",
                                        "salary" : 400,
                                }
                        ]
                }
        ],
       
}

Expected Result:
{
        "_id" : ObjectId("5f5638d0ff25e01482432803"),
        "name" : "XXXX",
        "mobileNo" : 323232323,
        "payroll" : [
                {
                        "_id" : ObjectId("5f5638d0ff25e01482432801"),
                        "month" : "Jan",
                        "salary" : 18200,
                        "payrollDetails" : [
                                {
                                        "day" : "2",
                                        "salary" : 201
                                },
                                {
                                        "day" : "1",
                                        "salary" : 200
                                }
                        ]
                },
                {
                        "_id" : ObjectId("5f5638d0ff25e01482432802"),
                        "month" : "Feb",
                        "salary" : 8300,
                        "payrollDetails" : [
                                {
                                        "day" : "2",
                                        "salary" : 400
                                },
                                {
                                        "day" : "1",
                                        "salary" : 300
                                }
                        ]
                }
        ],
       
}

只是一天将被排序,其余的东西都是一样的

我试过了,但它得到了无法识别的表达式'$push'

db.employee.aggregate([
{$unwind: '$payroll'},
{$unwind: '$payroll.payrollDetails'},
{$sort: {'payroll.payrollDetails.day': -1}},
{$group: {_id: '$_id', payroll: {$push: {payrollDetails:{$push: 
'$payroll.payrollDetails'} }}}}])

标签: mongodbnestedpush

解决方案


它需要两次$group,你不能$push在一个字段中使用两次运算符,

  • $group by main id 和 payroll id,构造payrollDetails数组
  • $sort by payroll id (如果不需要,你可以跳过)
  • $group by main id 并构造payroll数组
db.employee.aggregate([
  { $unwind: "$payroll" },
  { $unwind: "$payroll.payrollDetails" },
  { $sort: { "payroll.payrollDetails.day": -1 } },
  {
    $group: {
      _id: {
        _id: "$_id",
        pid: "$payroll._id"
      },
      name: { $first: "$name" },
      mobileNo: { $first: "$mobileNo" },
      payrollDetails: { $push: "$payroll.payrollDetails" },
      month: { $first: "$payroll.month" },
      salary: { $first: "$payroll.salary" }
    }
  },
  { $sort: { "payroll._id": -1 } },
  {
    $group: {
      _id: "$_id._id",
      name: { $first: "$name" },
      mobileNo: { $first: "$mobileNo" },
      payroll: {
        $push: {
          _id: "$_id.pid",
          month: "$month",
          salary: "$salary",
          payrollDetails: "$payrollDetails"
        }
      }
    }
  }
])

操场


推荐阅读