繁体   English   中英

使用动态键重塑 mongodb 聚合结果

[英]Reshape the mongodb aggregation result with dynamic keys

样本收集文件:

{
  "_id" : ObjectId("5fec3b978b34e8b047b7ae14"),
  "duration" : 20.0,
  "createdOn" : ISODate("2020-12-16T22:28:44.000Z"),
  "ClockInTime" : ISODate("2020-12-31T14:57:13.041Z"),
  "states" : "PROCESSED"
}

目前我正在使用以下查询。

db.collection.aggregate([{
            $match: {
                states: 'PROCESSED'
            }
        },
        {
            $group: {
                _id: {
                    month: {
                        $month: "$createdOn"
                    },
                    year: {
                        $year: "$createdOn"
                    }
                },
                count: {
                    $sum: 1
                },
                date: {
                    $first: "$createdOn"
                }
            }
        },
        {
            $project: {
                _id: 0,
                year: {
                    $year: "$date"
                },
                month: {
                    $month: "$date"
                },
                count: 1
            }
        }
    ]);

这给了我以下格式的结果。

[{
    "count" : 2.0,
    "year" : 2020,
    "month" : 11
}, {
    "count" : 5.0,
    "year" : 2020,
    "month" : 12
}, ...]

但我想要以下格式。

{
    "2020": {
        "11": 2,
        "12": 5
    }
}

现在我可以通过应用程序级编码获得上述 output 但我试图从 mongodb 查询本身获得相同的 output。

根据您已有的结果,添加以下结果:

db.collection.aggregate([
   { $set: { result: [{ k: { $toString: "$month" }, v: "$count" }] } },
   { $set: { result: { $arrayToObject: "$result" } } },
   { $set: { result: [{ k: { $toString: "$year" }, v: "$result" }] } },
   { $replaceRoot: { newRoot: { $arrayToObject: "$result" } } }
])

请注意, date: { $first: "$createdOn" }未确定。 在运行$group之前使用date: { $min: "$createdOn" }或插入{$sort: {...}}阶段。 好吧,如果你总是只得到一份文件,那当然没关系。 (但你也不需要count: { $sum: 1 }

根据附加输入进行更新

db.collection.aggregate([
  { $match: { states: "PROCESSED" } },
  {
    $group: {
      _id: {
        month: { $month: "$createdOn" },
        year: { $year: "$createdOn" }
      },
      count: { $sum: 1 },
      date: { $first: "$createdOn" }
    }
  },
  { $group: { _id: "$_id.year", data: { $push: "$$ROOT" } } },
  {
    $set: {
      data: {
        $map: {
          input: "$data",
          in: {
            k: { $toString: "$$this._id.month" },
            v: "$$this.count"
          }
        }
      }
    }
  },
  { $set: { data: { $arrayToObject: "$data" } } },
  { $set: { data: [ { k: { $toString: "$_id" }, v: "$data" } ] } },
  { $replaceRoot: { newRoot: { $arrayToObject: "$data" } } }
])

蒙戈游乐场

在较旧的 MonogDB 版本中,使用$addFields$set的别名

以下代码适用于较旧的 mongodb 版本:

db.collection.aggregate([{
    $match: {
        states: "PROCESSED"
    }
}, {
    $group: {
        _id: {
            month: {
                $dateToString: { format: "%m", date: "$createdOn" }
            },
            year: {
                $dateToString: { format: "%Y", date: "$createdOn" }
            }
        },
        count: {
            $sum: 1
        },
        date: {
            $first: "$createdOn"
        }
    }
}, {
    $group: {
        _id: "$_id.year",
        data: {
            $push: "$$ROOT"
        }
    }
}, {
    $addFields: {
        data: {
            $map: {
                input: "$data",
                in: {
                    k: "$$this._id.month",
                    v: "$$this.count"
                }
            }
        }
    }
}, {
    $addFields: {
        data: {
            $arrayToObject: "$data"
        }
    }
}, {
    $addFields: {
        data: [{
            k: "$_id",
            v: "$data"
        }]
    }
}, {
    $replaceRoot: {
        newRoot: {
            $arrayToObject: "$data"
        }
    }
}])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM