node.js - 如何修复 mongodb 查询?

标签 node.js mongodb mongoose

我正在写一个从数据库获取统计信息的请求。代码如下:

Stats.aggregate([
    {
        $group: {
            _id: {
                'advertiser': '$advertiser',
                'offer': '$offer'
            },
            stats: {
                $push: {
                    'date': '$date',
                    'spent': '$spent',
                    'revenue': '$revenue'
                }
            }
        }
    },
    {
        $group: {
            _id: '$_id.advertiser',
            offers: {
                $push: {
                    _id: '$_id.offer',
                    stats: '$stats'
                }
            }
        }
    }], callback);

我希望广告商拥有他的所有优惠,并且优惠内有有关天数以及支出和收入的统计数据。问题是每天的统计数据可能不止一个,我得到了这个答案:

stats   […]
0   {…}
date    2018-01-30T22:00:00.000Z
spent   100
revenue 200
1   {…}
date    2018-01-30T22:00:00.000Z
spent   20
revenue 20

但是,我需要将相同的日子合并为一天并花费并增加收入 另外,我想将优惠集合中的优惠信息添加到结果优惠中,就像我对广告商所做的那样。也许有人知道如何做到这一点。谢谢

数据库中的统计信息:

{
"_id": {
    "$oid": "5a4f873d381727000404d171"
},
"advertiser": {
    "$oid": "5a4f74619f0251000438fe4a"
},
"offer": {
    "$oid": "5a4f748c9f0251000438fe4b"
},
"spent": 415.19,
"revenue": 780.92,
"date": "2018-01-02T22:00:00.000Z",
"user": {
    "$oid": "5a4f74259f0251000438fe40"
},
"__v": 0

}

统计架构

const StatsSchema = mongoose.Schema({
advertiser: {
    type: ObjectId,
    ref: 'Advertiser',
    required: true
},
offer: {
    type: ObjectId,
    ref: 'Offer',
    required: true
},
spent: {
    type: Number,
    required: true
},
revenue: {
    type: Number,
    required: true
},
date: {
    type: String,
    required: true
},
user: {
    type: ObjectId,
    ref: 'User',
    required: true
}});

最佳答案

您可以首先投影,然后按如下所示进行相应分组。这是一个相对较长的查询,您可以根据您的工作流程添加一些优化。

db.createCollection('statistics');

db.statistics.insertMany([
    {advertiser: "1", offer: "1", date: "2018-01-30T22:00:00.000Z", spent: 10, revenue: 20},
    {advertiser: "1", offer: "1", date: "2018-01-30T21:00:00.000Z", spent: 20, revenue: 20},
    {advertiser: "2", offer: "2", date: "2018-01-30T22:00:00.000Z", spent: 10, revenue: 20},
    {advertiser: "2", offer: "2", date: "2018-01-30T21:00:00.000Z", spent: 1000, revenue: 2000},
    {advertiser: "2", offer: "2", date: "2018-01-31T22:00:00.000Z", spent: 25, revenue: 50}
])

transform_date = {
    $project: {
        advertiser: 1,
        offer: 1,
        date: { $dateFromString: { dateString: { $arrayElemAt: [ {$split: ["$date", "Z"]}, 0 ] }, timezone: 'UTC' } },
        spent: 1,
        revenue: 1      
    }
}

project_year_month_day = {
    $project: {
        advertiser: 1,
        offer: 1,
        date: 1,
        spent: 1,
        revenue: 1,
        year: { $year: "$date" },
        month: { $month: "$date" },
        day: { $dayOfMonth: "$date" }
    }
}

group_by_date_advertiser_offer_and_sum = {
    $group: {
        _id: {
            advertiser: "$advertiser",
            offer: "$offer",
            day: "$day",
            month: "$month",
            year: "$year"
        },
        spent: { $sum: "$spent" },
        revenue: { $sum: "$revenue" },
        dates: { $push: "$date" }
    }
}

group_advertiser_offer_and_push = {
    $group: {
        _id: {
            advertiser: "$_id.advertiser",
            offer: "$_id.offer"
        },
        stats: {
            $push: {
                dates: "$dates",
                spent: "$spent",
                revenue: "$revenue"
            }
        }
    }
}

group_advertiser_and_push = {
    $group: {
        _id: "$_id.advertiser",
        offers: {
            $push: {
                _id: "$_id.offer",
                stats: "$stats"
            }
        }
    }
}

db.statistics.aggregate([
    transform_date, 
    project_year_month_day, 
    group_by_date_advertiser_offer_and_sum, 
    group_advertiser_offer_and_push, 
    group_advertiser_and_push
])

输出

[{
    "_id": "2",
    "offers": [{
        "_id": "2",
        "stats": [{
            "dates": [ISODate("2018-01-31T22:00:00Z")],
            "spent": 25,
            "revenue": 50
        }, {
            "dates": [ISODate("2018-01-30T22:00:00Z"), ISODate("2018-01-30T21:00:00Z")],
            "spent": 1010,
            "revenue": 2020
        }]
    }]
} {
    "_id": "1",
    "offers": [{
        "_id": "1",
        "stats": [{
            "dates": [ISODate("2018-01-30T22:00:00Z"), ISODate("2018-01-30T21:00:00Z")],
            "spent": 30,
            "revenue": 40
        }]
    }]
}]

关于node.js - 如何修复 mongodb 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48202816/

相关文章:

c++ - Hello World 和 V8

node.js - 如何在单次上传操作中将大小大于 5mb 的文件上传到 AWS

mongodb - MongoDb 日期的 hive 类型转换

javascript - 在 MERN 项目上使用 MongoDB 设置 ExpressJS

arrays - Mongoose /蒙戈 : Update Not Saving

javascript - 为什么 mongoose 在创建和更新文档时异步运行?

mysql - 如何在http服务器开始接受请求之前建立mysql2连接?

mongodb - 对不同集合的两个查询 - MongoDB

node.js - 如何从 Mongoose 模式中的嵌入对象中删除 _id?

javascript - 我如何传递这个变量以从我的模块中使用它?