Schüler
Schüler

Reputation: 542

how to group records based on dates in mongodb

How to group data by dates? I have some docs in mongo that looks something like this: yes i have added my actuall mongo doc and my code too

    {
            "_id" : ObjectId("58c0e32161ccc654160b776a"),
            "consumer_id" : ObjectId("579f03069b49a0840409df83"),
            "user_id" : "579f034c9b49a0840409df85",
            "values" : [
                    {
                            "date" : "2017/2/9",
                            "point" : 1
                    },
                    {
                            "date" : "2017/2/10",
                            "point" : -1
                    },
                    {
                            "date" : "2017/2/11",
                            "point" : -1
                    }
            ]
    }
    {
            "_id" : ObjectId("58c0e3db61ccc654160b776b"),
            "consumer_id" : ObjectId("579f03069b49a0840409df83"),
            "user_id" : "579ef6f5a15b0eac1332034e",
            "values" : [
                    {
                            "date" : "2017/2/9",
                            "point" : 1
                    },
                    {
                            "date" : "2017/2/10",
                            "point" : 1
                    },
                    {
                            "date" : "2017/2/11",
                            "point" : -1
                    }
            ]
    }

I'd like to be able to count the no of points by date my code is like this

var array = [];
    var array2 = [];
    db.coll.find({}).toArray(function(err, result) {
        result.map(function(data) {
            array.push(data.values)
        })

Upvotes: 1

Views: 110

Answers (4)

Yashwin Munsadwala
Yashwin Munsadwala

Reputation: 514

The following code works for your problem.

db.Stack.aggregate([
  {$unwind: "$values"},
  {$group: {
    _id: "$values.date",
    sum: {$sum: "$values.point"}
    }
  }
])

This is the output for your code

/* 1 */ { "_id" : "2017/2/11", "sum" : -2.0 }

/* 2 */ { "_id" : "2017/2/10", "sum" : 0.0 }

/* 3 */ { "_id" : "2017/2/9", "sum" : 2.0 }

Upvotes: 0

Mihir Bhende
Mihir Bhende

Reputation: 9045

You would use following :

db.your_collection.aggregate([
    { $unwind : '$values'},
    { $group : {
        _id : '$values.date',
        point : { $sum : '$values.point' }
        }
    }
]);

Which will give you below result :

{ "_id" : "2017/2/11", "point" : -2 }
{ "_id" : "2017/2/10", "point" : 0 }
{ "_id" : "2017/2/9", "point" : 2 }

However, its always good to have date stored in proper date format and not as a string.

Upvotes: 1

MDH
MDH

Reputation: 132

You need to perform a map/reduce

I assume your array of objects are stored in the data field of your documents, themselves in an items collection.

// map function which pushes the points in an array associated to the given date date
var mapDataPoints = function() {
  for (var i=0; i<this.data.length; i++) emit(this.data[i].date, this.data[i].points);
};

// reduce function, which sums the array of points for a given date
var reduceDataPoints = function(dateId, points) {
  return Array.sum(points);
};

// map-reduce operation over the collection, which takes each document and apply the map function, then run the reduce function on the result of the map operation
// result is stored in a new collection, called pointsByDate
db.items.mapReduce(
  mapDataPoints,
  reduceDataPoints,
  { out: "pointsByDate" }
)

// pointsByDate can be queried just like any collection
db.pointsByDate.find({ "_id": "2017/2/10" });

Upvotes: 0

FrankTheTank_12345
FrankTheTank_12345

Reputation: 580

You need to use the sort function from mongodb:

sort({datefield: -1}}

in Mongodb for example

db.products.find().sort({"created_at": 1}) --- 1 for asc and -1 for desc

in nodejs for example:

collection.find().sort({datefield: -1}, function(err, cursor){...});

Upvotes: 0

Related Questions