Proper Mongoose Subdocument Relation
Proper Mongoose Subdocument Relation
I have a model
const userSchema = Schema({
username: String
})
const invitationSchema = Schema({
decision: String,
user: {
type: Schema.ObjectId,
ref: 'User'
}
})
const groupSchema = Schema({
name: String,
invitations: [{
type: Schema.ObjectId,
ref: 'Invitation'
}]
})
So the basic model looks like
group {
name
invitations [
user {
username
}
]
}
As user i would like to get all groups that i have invitations for
const user = getContextUser()
Group.find({
'invitations.user': user._id
})
But it doesn't seem to work, i could use a property group referring to Group
schema in Invitation
model, but i want the good way approach
Group
Invitation
How to i get all groups that user have invitations for
Don't look at this below, this is my actual model representation in json, just in case
// GROUP
{
"_id": ObjectId("5b3901dd9a8c0e6790af4ee8"),
"image": {
"filename": "8547aa2a-d16c-4da7-8d51-6c9bf8038037.jpg",
"width": 236,
"height": 156
},
"geolocation": {
"coordinates": [-152.1997, -24.7718],
"type": "Point"
},
"invitations": [
ObjectId("5b3901dd9a8c0e6790af4eea"),
ObjectId("5b3901dd9a8c0e6790af4eeb"),
ObjectId("5b3901dd9a8c0e6790af4eec"),
ObjectId("5b3901dd9a8c0e6790af4eed"),
ObjectId("5b3901dd9a8c0e6790af4eee"),
ObjectId("5b3901dd9a8c0e6790af4eef"),
ObjectId("5b3901dd9a8c0e6790af4ef0")
],
"messages": ,
"title": "id in magnam",
"description": "Cupiditate doloremque sunt placeat beatae et ex rerum nisi voluptate. Aliquam hic voluptas quas iure assumenda rerum aut. Quisquam vero beatae odit aut ut quod magnam.",
"created_at": ISODate("2018-07-01T16:31:25.237Z"),
"created_by": ObjectId("5b3901dc9a8c0e6790af4ee1"),
"color": "#347303",
"require_people_decision": true,
"is_public": true,
"start_date": ISODate("2019-03-18T20:05:03.116Z"),
"end_date": ISODate("2019-03-18T20:05:03.116Z"),
"location": "25498 Berniece Prairie",
"__v": 1
}
// INVITATION
{
"_id": ObjectId("5b3901dd9a8c0e6790af4eea"),
"created_at": ISODate("2018-07-01T16:31:25.348Z"),
"have_seen": false,
"user": ObjectId("5b3901dc9a8c0e6790af4ee0"),
"__v": 0
}
// USER
{
"_id": ObjectId("5b3901dc9a8c0e6790af4ee0"),
"avatar": {
"filename": "d438befb-2ea3-4582-b6bf-b8dd3b9bcf66.jpeg",
"width": 200,
"height": 200
},
"phone": "5556106679",
"password": "$2b$10$mbx9Yhj5mAKyVxwmxcumaepXYkCTiF/9VM2KJRARZkPOVN300pKc.",
"version": 1,
"friends": ,
"__v": 0
}
@AnthonyWinzlet what do you mean by sample collection? i have posted schema
– Medet Tleukabiluly
Jul 1 at 16:11
data you want to be returned after the query... you can copy it from mongo shell or any GUI you are using
– Anthony Winzlet
Jul 1 at 16:12
i want the groups, filtered by user which is in group's invitation
– Medet Tleukabiluly
Jul 1 at 16:13
I understood that but your query seem to be correct and that's why I am asking for your collection
– Anthony Winzlet
Jul 1 at 16:14
1 Answer
1
You can try below aggregation
Group.aggregate([
{ "$lookup": {
"from": Invitations.collection.name,
"let": { "invitations": "$invitations" },
"pipeline": [
{ "$match": { "$expr": { "$in": [ "$_id", "$$invitations" ] } } }
],
"as": "invitations"
}},
{ "$match": { "invitations.user": user._id } }
])
or this
Group.aggregate([
{ "$lookup": {
"from": Invitations.collection.name,
"let": { "invitations": "$invitations" },
"pipeline": [
{ "$match": {
"user": user._id,
"$expr": { "$in": [ "$_id", "$$invitations" ] }
}}
],
"as": "invitations"
}},
{ "$match": { "invitations.user": user._id } }
])
And the last one which I think is the best option to start with User
collection
User
User.aggregate([
{ "$match": { "_id": user._id }},
{ "$lookup": {
"from": Groups.collection.name,
"let": { "userId": "$_id" },
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$created_by", "$$userId" ] }}}
],
"as": "groups"
}}
])
is
Invitations.collection.name
intentional? why not just 'Invitation'
– Medet Tleukabiluly
Jul 1 at 16:46
Invitations.collection.name
'Invitation'
you need to replace it by your collection name... It might be
invitations
or Invitation
or whatever it is– Anthony Winzlet
Jul 1 at 16:47
invitations
Invitation
This approach it too hard to modify, operation is typical tho, maybe there's a simpler solution...?
– Medet Tleukabiluly
Jul 1 at 18:34
see the updated answer
– Anthony Winzlet
Jul 1 at 18:50
Altho this answers my initial question, the approach ain't perfect, the returning result will not contain all Invitations from
invitations
property, only the filtered ones– Medet Tleukabiluly
Jul 3 at 19:48
invitations
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.
can you please post your sample collection
– Anthony Winzlet
Jul 1 at 16:02