Vì vậy, cuối cùng tôi đã làm được và tôi nghĩ rằng đó có lẽ là cách tốt nhất để làm điều đó với mongodb và mongoose
1. Tạo mô hình cho người dùng.
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. Tạo một mô hình cho những người bạn có thù địch được chấp nhận, bị từ chối, đang chờ xử lý và được yêu cầu.
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. Bây giờ api gọi -> Giả sử chúng ta có hai người dùng là UserA và UserB ... Vì vậy, khi UserA yêu cầu UserB làm bạn tại thời điểm đó, chúng tôi tạo các tài liệu kép để UserA có thể thấy được yêu cầu và UserB có thể thấy đang chờ xử lý cùng lúc chúng tôi đẩy _id của những tài liệu này trong bạn bè của người dùng
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. Nếu UserB chấp nhận yêu cầu
Friend.findOneAndUpdate(
{ requester: UserA, recipient: UserB },
{ $set: { status: 3 }}
)
Friend.findOneAndUpdate(
{ recipient: UserA requester: UserB },
{ $set: { status: 3 }}
)
5. Nếu UserB từ chối yêu cầu
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. Nhận tất cả bạn bè và kiểm tra xem người dùng đã đăng nhập có phải là bạn của người dùng đó hay không
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 ]
}
}}
])