I have 2 collections, users and tracks. When I fetch the user profile I want to get his tracks.
The user object has tracks as an array of track IDs, and the second collection is of the tracks.
Now I am running this code below:
users
.aggregate([
{
$match: { _id: ObjectId(userId) },
},
{
$lookup: {
from: "tracks",
localField: "tracks",
foreignField: "_id",
as: "tracks",
},
},
{
$unwind: {
path: "$tracks",
preserveNullAndEmptyArrays: true,
},
},
{
$group: {
_id: ObjectId(userId),
username: { $first: "$username" },
profileImg: { $first: "$profileImg" },
socialLinks: { $first: "$socialLinks" },
tracks: {
$push: {
_id: "$tracks._id",
name: "$tracks.name",
categoryId: "$tracks.categoryId",
links: "$tracks.links",
mediaId: isLogged ? "$tracks.mediaId" : null,
thumbnailId: "$tracks.thumbnailId",
views: { $size: { $ifNull: ["$tracks.views", []] } },
downloads: { $size: { $ifNull: ["$tracks.downloads", []] } },
uploadedDate: "$tracks.uploadedDate",
},
},
},
},
])
In case the user does not have tracks or there are no tracks, the $ifNull statement returns an object only with these fields so it looks like that:
user: {
// user data
tracks: [{ views: 0, downloads: 0, mediaId: null }]
}
There are no tracks found so "tracks.views" cannot be read so I added the $ifNull statement, how can I avoid it from returning an empty data? also, the API call knows whether the user is logged or not (isLogged), I set the mediaId to null.
If there are no tracks found, why does the code still add these 3 fields only? no tracks to go through them...
Edit:
Any track has downloads and views containing user IDs whom downloaded / viewed the track, the track looks like that
{
"name": "New Track #2227",
"categoryId": "61695d57893f048528d049e5",
"links": {
"youtube": "https://www.youtube.com",
"soundcloud": null,
"spotify": null
},
"_id": "616c90651ab67bbd0b0a1172",
"creatorId": "61695b5986ed44e5c1e1d29d",
"mediaId": "616c90651ab67bbd0b0a1171",
"thumbnailId": "616c90651ab67bbd0b0a1170",
"plays": [],
"status": "pending",
"downloads": [],
"uploadedDate": 1634504805
}
When the fetched user doesn't have any track post yet, I receive an array with one object that contains the fields mentioned above.
What I expect to get when the user has no tracks is an empty array, as you can see the response above, the track object isn't full and contains only the conditional keys with zero value and null.
Bottom line I want the length of views and downloads only if there is a track or more, also for the mediaId which I want to hide it in case the user isn't logged. If there are no tracks I don't understand why it returns these 3 fields
expected result when the user has one track or more
user: {
// user data
tracks: [
{
name: "New Track #2227",
categoryId: "61695d57893f048528d049e5",
links: {
youtube: "https://www.youtube.com",
soundcloud: null,
spotify: null,
},
_id: "616c90651ab67bbd0b0a1172",
creatorId: "61695b5986ed44e5c1e1d29d",
mediaId: "616c90651ab67bbd0b0a1171",
thumbnailId: "616c90651ab67bbd0b0a1170",
plays: 0,
status: "pending",
downloads: 0,
uploadedDate: 1634504805,
},
];
}
expected result when the user has no tracks
user: {
// user data
tracks: [];
}
$$REMOVEalso maybe it can help youviews: { $ifNull: ["$tracks.views", []] }orviews: { $ifNull: ["$tracks.views", "$$REMOVE"] }"$$REMOVE"instead of[]and it throws this errorThe argument to $size must be an array, but was of type: missing