Reputation: 542
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
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
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
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
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