Node.js 如何修复mongo db查询?
我正在写一份db的统计请求。代码如下:Node.js 如何修复mongo db查询?,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在写一份db的统计请求。代码如下: Stats.aggregate([ { $group: { _id: { 'advertiser': '$advertiser', 'offer': '$offer' }, stats: { $push: { 'date': '
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
}]
}]
}]
请从
Stats
集合中添加一些示例文档,以便人们更容易提供帮助。如果我的日期类型为字符串,这会有大问题吗?我是否可以将$project date转换为new date(“$date”)。我更新了代码段,检查这是否适用于您的用例。您可以在项目中使用dateFromString
,但要使用该Z
,日期字符串中不应出现该值,这就是我使用拆分(“Z”)并获取预期解析的第一个元素的原因。确定。如何将报价信息从报价集合推送到结果中的报价中?您可以尝试使用mongoose中的QueryPopulation API使用ref
,或者使用$lookup
聚合,这可能会非常费劲。我已修复。谢谢你的时间和帮助