Reputation: 407
I was trying something with events and had to run a group by query but I couldn't get through it because it was mostly on subdocument.
Here is my DB currently:
{
"_id" : ObjectId("5bbb6e1c7f3fc62db401d05a"),
"type" : "ADD_BOOK",
"metadata" : {
"_id" : ObjectId("5bbb6e1c7f3fc62db401d05b"),
"name" : "ad",
"author" : "ad",
"imgUrl" : "https://vignette.wikia.nocookie.net/simpsons/images/6/60/No_Image_Available.png"
},
"timestamp" : 1539010076240.0,
"__v" : NumberInt(0)
},
{
"_id" : ObjectId("5bbb736ad441d505589ccecc"),
"type" : "ADD_BOOK",
"metadata" : {
"_id" : ObjectId("5bbb736ad441d505589ccecb"),
"name" : "ada",
"author" : "ada",
"imgUrl" : "https://vignette.wikia.nocookie.net/simpsons/images/6/60/No_Image_Available.png"
},
"timestamp" : 1539011434826.0,
"__v" : NumberInt(0)
},
{
"_id" : ObjectId("5bbb7373d441d505589ccecd"),
"type" : "DELETE_BOOK",
"metadata" : {
"_id" : "5bbb736ad441d505589ccecb"
},
"timestamp" : 1539011443792.0,
"__v" : NumberInt(0)
}
and I want the output to be like:
[
{
"_id": ObjectId("5bbb736ad441d505589ccecb"),
"books": [
{
"type": "ADD_BOOK",
"metadata": {
"_id": ObjectId("5bbb736ad441d505589ccecb"),
"name": "ada",
"author": "ada",
"imgUrl": "https://vignette.wikia.nocookie.net/simpsons/images/6/60/No_Image_Available.png"
}
}
{
"type": "DELETE_BOOK",
"metadata": {
"_id": ObjectId("5bbb736ad441d505589ccecb")
}
}
]
},
{
"_id": ObjectId("5bbb6e1c7f3fc62db401d05b"),
"books": [
{
"type": "ADD_BOOK",
"metadata": {
"_id": ObjectId("5bbb6e1c7f3fc62db401d05b"),
"name": "ad",
"author": "ad",
"imgUrl": "https://vignette.wikia.nocookie.net/simpsons/images/6/60/No_Image_Available.png"
}
}
]
}
]
My current implementation tries something like this:
db.bookevents.aggregate([
{ $match: { }},
{ $group: { _id: "$metadata._id", books: { $push: "$$ROOT" } } }
])
This doesn't work as expected. I am trying to read the documentation but I can't figure this one out yet.
Is it possible that the solution to this is something else and not $group
? Also can we put a $sort
on timestamp for each books[]
?
P.S. I know the question is mostly code but I don't know how to put it in any other way.
Upvotes: 1
Views: 735
Reputation: 49945
You're getting 3
groups instead of expected 2
because metadata._id
for DELETE_BOOK
is of type string whereas all the others are of type ObjectId. You have to manually fix that or if can use MongoDB 4.0 then you can use $toObjectId operator to convert that value before $group
. Additionally you can apply $sort
before grouping and get rid of unnecessary fields using $project
. Try:
db.bookevents.aggregate([
{ $addFields: { "metadata._id": { $toObjectId: "$metadata._id" } } }, // or fix manually
{ $sort: { timestamp: 1 } },
{ $group: { _id: "$metadata._id", books: { $push: "$$ROOT" } } },
{ $project: { "books.timestamp": 0, "books.value": 0, "books.__v": 0 } }
])
Upvotes: 1