Node.js 如何获取从开始日期到当前日期的订户总数?
我对MongoDB和mongoose非常陌生,我想了解从开始日期到当前日期的每日订户总数。换句话说,我需要按天对我的所有订户进行分组,每天我需要对我以前的所有订户进行合计Node.js 如何获取从开始日期到当前日期的订户总数?,node.js,mongodb,mongoose,mapreduce,aggregation-framework,Node.js,Mongodb,Mongoose,Mapreduce,Aggregation Framework,我对MongoDB和mongoose非常陌生,我想了解从开始日期到当前日期的每日订户总数。换句话说,我需要按天对我的所有订户进行分组,每天我需要对我以前的所有订户进行合计 { "count" : 2, "subscribeDate" : "2016-05-28" } { "count" : 6, "subscribeDate" : "2016-05-29" } { "count" : 3, "subscribeDate" : "2016-05-30" } 以下是我的一些文件: { "_id"
{ "count" : 2, "subscribeDate" : "2016-05-28" }
{ "count" : 6, "subscribeDate" : "2016-05-29" }
{ "count" : 3, "subscribeDate" : "2016-05-30" }
以下是我的一些文件:
{ "_id" : ObjectId("574cef8ee62502d08f34c075"), "userId" : "a7zd609h54wm5kt", "subscribedAt" : ISODate("2016-05-30T18:22:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.098Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c076"), "userId" : "3q2tvd53zcap5mq", "subscribedAt" : ISODate("2016-05-30T19:52:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.113Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c077"), "userId" : "nvx8mnu1xis5jxt", "subscribedAt" : ISODate("2016-05-28T19:52:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.117Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c078"), "userId" : "l7eedg616r0zbdf", "subscribedAt" : ISODate("2016-05-28T16:28:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.122Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c079"), "userId" : "9r1wl8ao8bls7g7", "subscribedAt" : ISODate("2016-05-28T11:05:05Z"), "isSubscribed" : false, "createdAt" : ISODate("2016-05-31T01:57:34.125Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07a"), "userId" : "ygwve2e47p7fanl", "subscribedAt" : ISODate("2016-05-29T00:28:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.125Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07b"), "userId" : "1gxspx9jypwc9tu", "subscribedAt" : ISODate("2016-05-29T19:52:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.127Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07c"), "userId" : "hvy4xjppos8ch2b", "subscribedAt" : ISODate("2016-05-29T01:36:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.127Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07d"), "userId" : "bmpql2d7wkl0jnw", "subscribedAt" : ISODate("2016-05-29T21:50:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.127Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07e"), "userId" : "uir99sy6q3p6i0i", "subscribedAt" : ISODate("2016-05-29T08:22:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.131Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c07f"), "userId" : "qmzn3rz308ku017", "subscribedAt" : ISODate("2016-05-29T22:02:05Z"), "isSubscribed" : false, "createdAt" : ISODate("2016-05-31T01:57:34.132Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c080"), "userId" : "ok46sxaf8urrqtj", "subscribedAt" : ISODate("2016-05-29T07:33:05Z"), "isSubscribed" : false, "createdAt" : ISODate("2016-05-31T01:57:34.132Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c081"), "userId" : "ot4nmxqsn4o98vn", "subscribedAt" : ISODate("2016-05-29T23:52:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.138Z"), "__v" : 0 }
{ "_id" : ObjectId("574cef8ee62502d08f34c082"), "userId" : "2voy5ttkk39i1f0", "subscribedAt" : ISODate("2016-05-30T00:52:05Z"), "isSubscribed" : true, "createdAt" : ISODate("2016-05-31T01:57:34.138Z"), "__v" : 0 }
所以我在2016-05-28有2个订户,2016-05-29有6个订户,2016-05-30有3个订户
我希望达到的结果是这样的
{
"results" : [
{
"date" : ISODate("2016-05-28T00:00:00Z"),
"subscribers" : 2
},
{
"date" : ISODate("2016-05-29T00:00:00Z"),
"subscribers" : 8
},
{
"date" : ISODate("2016-05-30T00:00:00Z"),
"subscribers" : 11
},
]
}
我用以下代码尝试了聚合框架:
var express = require('express'),
router = express.Router(),
User = require('../models/user');
router.get('/', function(req, res, next) {
User.aggregate([
{
$match: { isSubscribed: true, subscribedAt: {$gte: new Date("2016-05-28T00:00:00+01:00"), $lte: new Date()}}
},
{
$group: {
_id: {$dateToString: { format: "%Y-%m-%d", date: "$subscribedAt" }},
count : { $sum : 1 }
},
},
{
$project: {
_id : 0,
subscribeDate : "$_id",
count : 1
}
},
{
$sort: {subscribeDate: 1}
}
], function(err, result){
if (err) {
console.log("This is an error find the user!")
}
res.render('dashboard', {results: result, title: "Welcome to analytics dashboard!"});
});
});
module.exports = router;
var express = require('express'),
router = express.Router(),
User = require('../models/user'),
DailySubscriber = require('../models/dailySubscriber');
router.get('/', function(req, res, next) {
var userObject = {
"query": {isSubscribed: true},
"out": "dailySubscriber"
};
userObject.map = function () {
var date = new Date(this.subscribedAt.valueOf() - (this.subscribedAt.valueOf() % (1000 * 60 * 60 * 24 )));
emit(date, 1)
}
userObject.reduce = function (k, vals) { return vals.length }
User.mapReduce(userObject, function (err, results) {
//console.log(results)
})
var subscriberObject = {
"scope": { "total": 0 },
"finalize": function(key, value) {
total += value;
return total;
},
"out": "totalSubscriber"
};
subscriberObject.map = function () {
emit(this._id, this.value)
}
subscriberObject.reduce = function (k, vals) { return vals.length }
DailySubscriber.mapReduce(subscriberObject, function (err, total) {
console.log("This is the result" + total)
})
res.render('dashboard', {title: "Welcome to analytics dashboard!"});
});
module.exports = router;
但这只给出了每天的总订户,而不是之前所有订户的总和
{ "count" : 2, "subscribeDate" : "2016-05-28" }
{ "count" : 6, "subscribeDate" : "2016-05-29" }
{ "count" : 3, "subscribeDate" : "2016-05-30" }
我还尝试了mapReduce,建议使用以下代码:
var express = require('express'),
router = express.Router(),
User = require('../models/user');
router.get('/', function(req, res, next) {
User.aggregate([
{
$match: { isSubscribed: true, subscribedAt: {$gte: new Date("2016-05-28T00:00:00+01:00"), $lte: new Date()}}
},
{
$group: {
_id: {$dateToString: { format: "%Y-%m-%d", date: "$subscribedAt" }},
count : { $sum : 1 }
},
},
{
$project: {
_id : 0,
subscribeDate : "$_id",
count : 1
}
},
{
$sort: {subscribeDate: 1}
}
], function(err, result){
if (err) {
console.log("This is an error find the user!")
}
res.render('dashboard', {results: result, title: "Welcome to analytics dashboard!"});
});
});
module.exports = router;
var express = require('express'),
router = express.Router(),
User = require('../models/user'),
DailySubscriber = require('../models/dailySubscriber');
router.get('/', function(req, res, next) {
var userObject = {
"query": {isSubscribed: true},
"out": "dailySubscriber"
};
userObject.map = function () {
var date = new Date(this.subscribedAt.valueOf() - (this.subscribedAt.valueOf() % (1000 * 60 * 60 * 24 )));
emit(date, 1)
}
userObject.reduce = function (k, vals) { return vals.length }
User.mapReduce(userObject, function (err, results) {
//console.log(results)
})
var subscriberObject = {
"scope": { "total": 0 },
"finalize": function(key, value) {
total += value;
return total;
},
"out": "totalSubscriber"
};
subscriberObject.map = function () {
emit(this._id, this.value)
}
subscriberObject.reduce = function (k, vals) { return vals.length }
DailySubscriber.mapReduce(subscriberObject, function (err, total) {
console.log("This is the result" + total)
})
res.render('dashboard', {title: "Welcome to analytics dashboard!"});
});
module.exports = router;
当我运行我的节点应用程序时,这不起作用,我在控制台中得到了错误这是未定义的结果
,但它在MongoDB Shell中起作用,结果非常接近我想要的,但仍然不太理想,因为它总是显示\u id
和value
作为键和值
{
"results" : [
{
"_id" : ISODate("2016-05-28T00:00:00Z"),
"value" : 2
},
{
"_id" : ISODate("2016-05-29T00:00:00Z"),
"value" : 8
},
{
"_id" : ISODate("2016-05-30T00:00:00Z"),
"value" : 11
},
]
}
最好的方法是什么?如果有帮助的话,我正在使用Node.js、Express和Mongoose
任何帮助都将不胜感激!提前谢谢 imho-我们可以从mongo中榨取的最好的东西是使用聚合框架来进行每日汇总。由于(来自sql world)我们没有CTE,我们无法参考之前的文档,这使得一些分析变得困难 在这种情况下,我将只做简单的forEach循环,并在这种特殊情况下更新sum值,创建移动sum。这将要求数据需要从最旧到最新进行排序。下面是一个sudocode:
var previous = 0;
forEach (var r in result)
{
r.count += previous;
previous = r.count;
}