Reputation: 83
I currently have three collections: artists
, albums
and users
. Every user has a list of albums he "likes" and I'm simply trying to set up a query (or an aggregation pipeline) that would return a boolean value whether a particular user likes an album. The collections look like so:
Artists
{
"_id" : ObjectId("5e2b5c922e1843a8ed16df3b"),
"name" : "Death Grips",
"formed" : "21 Dec 2010",
"members" : [
"Stefan Burnett",
"Zach Hill",
"Andy Morin"
],
"based_in" : "Sacramento, CS, United States",
"genres" : [
"Experimental Hip Hop",
"Industrial Hip Hop",
"Abstract Hip Hop",
"Hardcore Hip Hop",
"Glitch Hop",
"Noise Rock"
]
}
Albums
{
"_id" : ObjectId("5e2c41a4dce5f62fb2488ed8"),
"artist" : ObjectId("5e2b5c922e1843a8ed16df3b"),
"title" : "The Money Store",
"release_date" : "24 April 2012",
"image" : "5e2b9fd5b9be486f427f8331.jpg",
"rating" : 3.96,
"genres" : [
"Experimental Hip Hop",
"Industrial Hip Hop",
"Abstract Hip Hop",
"Hardcore Hip Hop",
"Glitch Hop",
"Noise Rock"
],
"descriptors" : [
"aggressive",
"angry",
"energetic",
"manic",
"noisy",
"nihilistic"
],
"lang" : "English",
"track_listing" : [
"Get Got",
"The Fever",
"Lost Boys",
"Black Jack",
"Hustle Bones",
"I've Seen Footage",
"Double Helix",
"System Blower",
"The Cage",
"Punk Weight",
"Fuck That",
"Bitch Please",
"Hacker"
]
}
Users
{
"_id" : ObjectId("5e2c610157053b19fb28ee4e"),
"username" : "stackoverflow_user",
"liked_albums" : [
"5e2c41a4dce5f62fb2488ed8"
]
}
And this is what I'm trying to do:
albums = col.aggregate([
{
"$lookup":{
"from": "artists",
"localField": "artist",
"foreignField": "_id",
"as": "artist"
}
}, ...something that would return true
if the a user with a particular id
likes that album.
This is the approximate return query I want to achieve with the user ObjectId("5e2c610157053b19fb28ee4e")
:
{
"_id" : ObjectId("5e2c41a4dce5f62fb2488ed8"),
"artist" : {
"_id" : ObjectId("5e2b5c922e1843a8ed16df3b"),
"name" : "Death Grips",
"formed" : "21 Dec 2010",
"members" : [
"Stefan Burnett",
"Zach Hill",
"Andy Morin"
],
"based_in" : "Sacramento, CS, United States",
"genres" : [
"Experimental Hip Hop",
"Industrial Hip Hop",
"Abstract Hip Hop",
"Hardcore Hip Hop",
"Glitch Hop",
"Noise Rock"
]
},
"title" : "The Money Store",
"release_date" : "24 April 2012",
"image" : "5e2b9fd5b9be486f427f8331.jpg",
"rating" : 3.96,
"genres" : [
"Experimental Hip Hop",
"Industrial Hip Hop",
"Abstract Hip Hop",
"Hardcore Hip Hop",
"Glitch Hop",
"Noise Rock"
],
"descriptors" : [
"aggressive",
"angry",
"energetic",
"manic",
"noisy",
"nihilistic"
],
"lang" : "English",
"track_listing" : [
"Get Got",
"The Fever",
"Lost Boys",
"Black Jack",
"Hustle Bones",
"I've Seen Footage",
"Double Helix",
"System Blower",
"The Cage",
"Punk Weight",
"Fuck That",
"Bitch Please",
"Hacker"
],
"liked": true
}
Thanks!
Upvotes: 0
Views: 306
Reputation: 13103
Does this solution meet your requirements?
In the last stage, we iterate all users who likes the album.
Change $filter
condition to filter user _id
.
db.albums.aggregate([
{
"$lookup": {
"from": "artists",
"localField": "artist",
"foreignField": "_id",
"as": "artist"
}
},
{
"$lookup": {
"from": "users",
"let": {
album_id: {
$toString: "$_id"
}
},
"pipeline": [
{
$match: {
$expr: {
$in: [
"$$album_id",
"$liked_albums"
]
}
}
}
],
"as": "users"
}
},
{
$addFields: {
liked: {
$toBool: {
$size: {
$filter: {
input: "$users",
cond: {
$eq: [
"$$this._id",
ObjectId("5e2c610157053b19fb28ee4e")
]
}
}
}
}
}
}
},
{
$unset: "users"
}
])
Upvotes: 2