2016-06-01 8 views
4

Ich bin sehr neu zu MongoDB und Mungo und ich möchte die Gesamtzahl der Abonnenten vom Startdatum bis zum aktuellen Tag für Tag erhalten. Mit anderen Worten, ich muss alle meine Abonnenten am Tag gruppieren, und für jeden Tag muss ich alle meine bisherigen Abonnenten zusammenfassen.Wie erhält man die Gesamtzahl der Abonnenten vom Startdatum bis zum aktuellen Datum?

Hier sind einige meiner meine Dokumente:

{ "_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 } 

So habe ich 2 Abonnenten auf 2016.05.28, 6 Abonnenten auf 2016.05.29 und 3 Abonnenten auf 2016.05.30 ,

Das Ergebnis ich hoffe, zu erreichen ist so etwas wie dieses

{ 
    "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 
     }, 
    ] 
} 

I Aggregation Rahmen mit dem folgenden Code versucht haben:

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; 

Aber das gibt mir nur die Gesamtzahl der Abonnenten eines jeden Tages, NICHT die die SUMUP aller vorherigen Abonnenten.

{ "count" : 2, "subscribeDate" : "2016-05-28" } 
{ "count" : 6, "subscribeDate" : "2016-05-29" } 
{ "count" : 3, "subscribeDate" : "2016-05-30" } 

Ich habe auch versucht verkleinern als here mit dem folgenden Code vorgeschlagen:

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; 

Diese NICHT Arbeit tat, als ich meine Knoten app lief und ich habe den Fehler This is the result undefined in der Konsole, ABER hat es in MongoDB Shell mit dem folgenden Ergebnis funktioniert, das ist sehr nah an dem, was ich will, aber immer noch nicht so ideal, wie es immer _id undzeigtals Schlüssel und Wert.

{ 
    "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 
     }, 
    ] 
} 

Was wäre der beste Weg, es zu tun? Ich benutze Node.js, Express und Mongoose, wenn das hilft.

Jede Hilfe wäre sehr willkommen! Danke im Voraus!

Antwort

0

imho - Aggregation Framework zu haben, um eine tägliche Summe zu haben, ist das Beste, was wir aus Mongo quetschen können. Da (von sql world) wir kein CTE haben, können wir uns nicht auf das vorherige Dokument beziehen, und das macht einige Analysen schwierig.

Was ich in diesem Fall tun werde, ist nur einfach forEach Schleife und aktualisieren Sie den Summenwert, um bewegliche Summe in diesem speziellen Fall zu erstellen. Dies erfordert, dass Daten vom ältesten zum neuesten sortiert werden müssen. Ein Sudocode dafür:

var previous = 0; 
forEach (var r in result) 
{ 
    r.count += previous; 
    previous = r.count; 
} 
Verwandte Themen