【发布时间】:2017-04-16 19:53:21
【问题描述】:
我有以下数据。我想运行一个查询来按类别和月份对我的结果进行分组并返回一个总数。
第一个期望的输出是月份名称的嵌套数组,其中按类别汇总了所有 12 个月的总数。数据中不存在的月份仍将返回,但总和为 0。
{"category":"Auto","month":{"Jan":9.12,"Feb":9.12,"Mar":0,...}},
{"category":"Fees","month":{..."Apr":0,"May":4.56,"Jun":0,...}},
{"category":"Travel","month":{..."Oct":0,"Nov":4.56,"Dec":0}}
第二个期望的输出是一个没有嵌套月份的数组...
{"category":"Auto","Jan":4.56,"Feb":4.56,"Mar":0,...},
{"category":"Fees",..."Apr":0,"May":4.56,"Jun":0,...},
{"category":"Travel",..."Oct":0,"Nov":0,"Dec":4.56,}
如何用MongoDB查询这些结果?这是示例输入数据:
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f1"),
"transid" : 1,
"category": "Auto",
"postdate" : ISODate("2016-01-28T05:00:00.000Z"),
"total" : 4.56 }
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f2"),
"transid" : 5,
"category": "Auto",
"postdate" : ISODate("2016-01-31T05:00:00.000Z"),
"total" : 4.56 }
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f3"),
"transid" : 3,
"category": "Auto",
"postdate" : ISODate("2016-02-28T05:00:00.000Z"),
"total" : 4.56 }
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f4"),
"transid" : 2,
"category": "Auto",
"postdate" : ISODate("2016-02-31T05:00:00.000Z"),
"total" : 4.56 }
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f5"),
"transid" : 6,
"category": "Fees",
"postdate" : ISODate("2016-05-16T05:00:00.000Z"),
"total" : 4.56 }
{
"_id" : ObjectId("583f6e6d14c8042dd7c153f6"),
"transid" : 7,
"category": "Travel",
"postdate" : ISODate("2016-11-13T05:00:00.000Z"),
"total" : 4.56 }
我是 mongodb 的新手,来自 sql 背景,所以我觉得我一直在用 sql 术语考虑这一切。
以下是我迄今为止根据阅读 mongodb 文档并尝试翻译“sql think”所做的尝试。我实际上是在尝试过滤到指定的年份(在本例中为 2016 年)。然后我按类别和日期分组。在最后一步中,我计划使用 project 和 $cond 关键字通过指定每个月的开始和结束日期来“细分”月份,然后将月份名称指定为 Jan、Feb 等......我有语法错误而且我不知道这是正确的还是最好的方法。
db.transactions.aggregate(
[
{ $match: { "postdate": {$gte: new Date("2016-01-01")}} },
{ $group: { _id: {"category":"$category","postdate":"$postdate"} , "total": { $sum: "$debit" } } },
{ $project: {"_id":0,"category":"$_id.category",
"month":{$cond: {
$and:
[
{ $gte: ["$_id.postdate", new Date("2016-01-01")] },
{ $lt: ["$_id.postdate", new Date("2016-02-01")] },
]
},"Jan":"$sum"}
//repeat for all other 11 months...
}}
]
)
【问题讨论】:
-
我找到了一个解决方案,可以让我在第一个场景中接近我想要的输出,但它需要一些调整,因为我无法让几个月出现。我会继续玩它,但它可能会让某人走上正确的轨道。我在这里的另一篇文章中找到了这个解决方案:[link]stackoverflow.com/questions/25843255/…
-
这是我目前所拥有的:
db.transactions.aggregate([ { $match: { "postdate": {$gte: new Date("2016-01-01")}} }, { "$group": { "_id": { "category": "$category", "month": {"$month": "$postdate"} }, "total": { "$sum": "$total" } }}, { "$group": { "_id": "$_id.category", "month": { "$push": { "month": "$month", "total": "$total" } } }} ])
标签: mongodb