Issues with merging arrays of objects in MoongoDb
Clash Royale CLAN TAG#URR8PPP
Issues with merging arrays of objects in MoongoDb
I trying to build an aggregation quarry in MoongoDb that will merge arrays from
2 different collection (one of the collections is of type TTL). And I facing with 2 issues that I can’t resolve.
First Issue:
I would like to merge the TakenSeats
fields of my temp collations and permanent collection and set the result instead of my correct TakenSeats
field, Using my aggregation in the bottom i manage to merge the arrays with the $push
operator, But I cant replace the result field with the TakenSeats
field that is in my permanent document.
TakenSeats
TakenSeats
$push
TakenSeats
Second Issue:
In case that I don’t have any documents in my temp collection, how can I still receive the document from the permanent one?
Sample of document in the permanent collection: (extracting data from one document)
"_id" : ObjectId("5b6b656818883ec018d1542d"),
"showsHall" : [
ObjectId("5b64cb758ad5f81a6cb7e6ae")
],
"movie" : [
ObjectId("5b6b614218883ec018d15428")
],
"takenSeats" : [
"id" : 11
,
"id" : 12
],
"showDate" : "8/14/2018",
"showStartTime" : "3:00 PM",
"showEndTime" : "5:00 PM",
"creteDate" : ISODate("2018-08-08T21:49:28.020Z"),
"__v" : 0
From the TTL collection: (extracting data from multiple documents)
"_id" : ObjectId("5b6f35023f64851baa70c61b"),
"createdAt" : ISODate("2018-08-11T19:12:02.951Z"),
"showId" : [
ObjectId("5b6b656818883ec018d1542d")
],
"takenSeats" : [
"id" : 22
,
"id" : 25
]
This is the aggregation that I used:
db.getCollection('shows').aggregate([
$match: _id: ObjectId("5b6b656818883ec018d1542d") ,
$lookup:
from: "temp",
localField: "_id",
foreignField: "showId",
as: "fromItems"
,
$unwind: "$fromItems" ,
"$project": "takenSeats": "$setUnion": ["$takenSeats", "$fromItems.takenSeats"], _id: 1, showsHall: 1, movie: 1, takenSeats: 1 , showDate: 1, showStartTime: 1, showEndTime: 1 ,
$unwind:"$takenSeats",
$group:_id: "$_id", takenSeats: $push : "$takenSeats" ,
])
Result:
[Edit]
I manage to maintain my original data with $first
operator.
But now i cant resolve issue no 2 (prevent result if null), I tried to use preserveNullAndEmptyArrays
in both of the unwind
stages but the result is that it pushes an empty array.
My wanted result is that it should push
to a new array only if there is values to push
$first
preserveNullAndEmptyArrays
unwind
push
push
This is my aggregation :
db.getCollection('shows').aggregate([
$match: _id: ObjectId("5b6b656818883ec018d1542d") ,
$lookup:
from: "temp",
localField: "_id",
foreignField: "showId",
as: "fromItems"
,
$unwind:path:"$fromItems" ,preserveNullAndEmptyArrays:true,
"$project": "takenSeats": "$setUnion": ["$takenSeats", "$fromItems.takenSeats"], _id: 1, showsHall: 1, movie: 1, showDate: 1, showStartTime: 1, showEndTime: 1 ,
$unwind:path:"$takenSeats" ,preserveNullAndEmptyArrays:true,
,
$group:
_id: "$_id",
showsHall : $first: '$showsHall' ,
movie : $first: '$movie' ,
showDate : $first: '$showDate' ,
showStartTime : $first: '$showStartTime' ,
showEndTime : $first: '$showEndTime' ,
takenSeats: $push : "$takenSeats"
])
This is the result that i getting if there is no documents in the temp collection
"_id" : ObjectId("5b6b656818883ec018d1542d"),
"showsHall" : [
ObjectId("5b64cb758ad5f81a6cb7e6ae")
],
"movie" : [
ObjectId("5b6b614218883ec018d15428")
],
"showDate" : "8/14/2018",
"showStartTime" : "3:00 PM",
"showEndTime" : "5:00 PM",
"takenSeats" : [
null
]
$unwind
$replaceRoot: newRoot: "$takenSeats"
second issue solve by use
preserveNullAndEmptyArrays
property in unwind
as $unwind:path:"$fromItems" ,preserveNullAndEmptyArrays:true
– IftekharDani
Aug 13 at 6:46
preserveNullAndEmptyArrays
unwind
$unwind:path:"$fromItems" ,preserveNullAndEmptyArrays:true
Please provide sample output data for results you want. so getting more understanding on your first issue.
– IftekharDani
Aug 13 at 6:49
Thanks for youre help guys, I am edited my question. @IftekharDani I tried to use yore solution for issue number 2, But as you can see in my edit that it didnt quite work .
– Igor romanovsky
Aug 13 at 8:38
same condition use for
$unwind:"$takenSeats"
and check it.– IftekharDani
Aug 13 at 8:47
$unwind:"$takenSeats"
1 Answer
1
Here Please add ifNull Condition for solution 2
db.getCollection('shows').aggregate([
$match: _id: ObjectId("5b6b656818883ec018d1542d") ,
$lookup:
from: "tempShows",
localField: "_id",
foreignField: "showId",
as: "fromItems"
,
$unwind:path:"$fromItems" ,preserveNullAndEmptyArrays:true,
"$project": "takenSeats": $ifNull: [ "$setUnion": ["$takenSeats", "$fromItems.takenSeats"], '$takenSeats'] ,_id: 1, showsHall: 1, movie: 1, showDate: 1, showStartTime: 1, showEndTime: 1 ,
$unwind:path:"$takenSeats" ,preserveNullAndEmptyArrays:true,
$group:
_id: "$_id",
showsHall : $first: '$showsHall' ,
movie : $first: '$movie' ,
showDate : $first: '$showDate' ,
showStartTime : $first: '$showStartTime' ,
showEndTime : $first: '$showEndTime' ,
takenSeats: $push : "$takenSeats"
])
Thank you very very much!
– Igor romanovsky
Aug 13 at 9:16
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
After the
$unwind
stage use this$replaceRoot: newRoot: "$takenSeats"
– Anthony Winzlet
Aug 13 at 1:31