Så endelig lavede jeg det, og jeg tror, det er nok den bedste måde at gøre det med mongodb og mongoose
1. Opret en model til brugerne.
var Schema = mongoose.Schema
const usersSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
friends: [{ type: Schema.Types.ObjectId, ref: 'Friends'}]
}, {timestamps: true})
module.exports = mongoose.model('Users', usersSchema)
2. Opret en model for venner, der har enums for accepteret, afvist, afventende og anmodet.
const friendsSchema = new Schema({
requester: { type: Schema.Types.ObjectId, ref: 'Users'},
recipient: { type: Schema.Types.ObjectId, ref: 'Users'},
status: {
type: Number,
enums: [
0, //'add friend',
1, //'requested',
2, //'pending',
3, //'friends'
]
}
}, {timestamps: true})
module.exports = mongoose.model('Friends', friendsSchema)
3. Nu kalder api --> Lad os sige, at vi har to brugere BrugerA og BrugerB... Så når BrugerA anmoder BrugerB om at være venner på det tidspunkt laver vi to dokumenter, så BrugerA kan se anmodet, og BrugerB kan se afventende, og samtidig skubber vi _id'et for disse dokumenter i brugerens venner
const docA = await Friend.findOneAndUpdate(
{ requester: UserA, recipient: UserB },
{ $set: { status: 1 }},
{ upsert: true, new: true }
)
const docB = await Friend.findOneAndUpdate(
{ recipient: UserA, requester: UserB },
{ $set: { status: 2 }},
{ upsert: true, new: true }
)
const updateUserA = await User.findOneAndUpdate(
{ _id: UserA },
{ $push: { friends: docA._id }}
)
const updateUserB = await User.findOneAndUpdate(
{ _id: UserB },
{ $push: { friends: docB._id }}
)
4. Hvis BrugerB accepterer anmodningen
Friend.findOneAndUpdate(
{ requester: UserA, recipient: UserB },
{ $set: { status: 3 }}
)
Friend.findOneAndUpdate(
{ recipient: UserA requester: UserB },
{ $set: { status: 3 }}
)
5. Hvis BrugerB afviser anmodningen
const docA = await Friend.findOneAndRemove(
{ requester: UserA, recipient: UserB }
)
const docB = await Friend.findOneAndRemove(
{ recipient: UserA, requester: UserB }
)
const updateUserA = await User.findOneAndUpdate(
{ _id: UserA },
{ $pull: { friends: docA._id }}
)
const updateUserB = await User.findOneAndUpdate(
{ _id: UserB },
{ $pull: { friends: docB._id }}
)
6. Få alle venner og tjek, om den loggede bruger er ven af denne bruger eller ej
User.aggregate([
{ "$lookup": {
"from": Friend.collection.name,
"let": { "friends": "$friends" },
"pipeline": [
{ "$match": {
"recipient": mongoose.Types.ObjectId("5afaab572c4ec049aeb0bcba"),
"$expr": { "$in": [ "$_id", "$$friends" ] }
}},
{ "$project": { "status": 1 } }
],
"as": "friends"
}},
{ "$addFields": {
"friendsStatus": {
"$ifNull": [ { "$min": "$friends.status" }, 0 ]
}
}}
])