Så äntligen gjorde jag det och jag tror att det förmodligen är det bästa sättet att göra det med mongodb och mongoose
1. Skapa en modell för användare.
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. Skapa en modell för vänner som har uppräkningar för accepterade, avvisade, väntande och begärda.
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 anropar api --> Låt oss säga att vi har två användare AnvändareA och AnvändareB... Så när AnvändareA begär att AnvändareB ska vara en vän vid den tiden skapar vi två dokument så att AnvändareA kan se efterfrågade och AnvändareB kan se väntande och samtidigt trycker vi _id för dessa dokument i användarens vänner
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. Om UserB accepterar begäran
Friend.findOneAndUpdate(
{ requester: UserA, recipient: UserB },
{ $set: { status: 3 }}
)
Friend.findOneAndUpdate(
{ recipient: UserA requester: UserB },
{ $set: { status: 3 }}
)
5. Om UserB avvisar begäran
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. Skaffa alla vänner och kontrollera om den inloggade användaren är vän med den användaren eller inte
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 ]
}
}}
])