Reputation: 1636
I have many documents - each with a date field, each with different keys.... (well, they vary... such is the nature of mongo).
{
"_id" : ObjectId("5b5e5107b3218221345cb198"),
"category" : "A",
"type" : "toilet",
"cleaned" : "yes",
"date" : ISODate("2018-07-29T23:43:03.178+0000")
}
{
"_id" : ObjectId("5b5e5119b3218221345cb199"),
"category" : "B",
"housed" : "no",
"temp" : "44",
"date" : ISODate("2018-08-10T10:22:22.774+0000")
}
I am trying to group and paginate. I need to be able to group all the documents by date - ignoring the time. This way, I can display all documents belonging to a date.
When a viewer clicks next / previous, it shows the next / previous date etc... So I would need to also test to see if next and previous documents exist in order to build the pagination.
So far, my attempts have failed. My thoughts are - I need to find and group, but that didn't work. I read this blog post https://dzone.com/articles/aggregate-mongo-using-only and adapted it - but this also doesn't work... it returns only a date field (the datePartDay bit splits the date string up)
db.getCollection("log").aggregate(
{
"$project":
{
_id: 0,
"datePartDay": {
"$concat": [
{"$substr": [{"$dayOfMonth": "$date"}, 0, 2]}, "-",
{"$substr": [{"$month": "$date"}, 0, 2]}, "-",
{"$substr": [{"$year": "$date"}, 0, 4]}
]
}
}
},
{
"$group":
{"date": "$datePartDay"}
}
)
My app is running on node - and I'm not using mongoose.
** EDIT **
@Anthony Winzlet
I couldn't get $slice to work - but I can set my match to only look within 3 days, thus limiting my results to only those which fall within 3 days.
db.collection.aggregate(
[
{
"$match" : {
// find the date range we want to look up
"date" : {
"$gte" : ISODate("2018-07-29T00:00:00.000+0000"),
"$lte" : ISODate("2018-09-10T00:00:00.000+0000")
}
}
},
{
"$group" : {
"_id" : {
"$dateToString" : {
"format" : "%Y-%m-%d",
"date" : "$date"
}
},
"data" : {
"$push" : "$$ROOT"
}
}
}
]
);
However, I'm not sure how performant this is?
Upvotes: 1
Views: 624
Reputation: 46441
You can $group
using $dateToString
and then simply $push
the $$ROOT
elements to an array
db.collection.aggregate([
{ "$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$date"
}
},
"data": {
"$push": "$$ROOT"
}
}}
])
Upvotes: 1