当我在其他用户个人资料上时,如何建模我的猫鼬模式以获取这三个按钮?
我的用户架构
const schema = new Mongoose.Schema({
firstName: { type: String, default: '', trim: true },
lastName: { type: String, default: '', trim: true },
}, { timestamps: true })
我找不到正确的建模......还请在建模后建议聚合......
答案 0 :(得分:5)
所以最后我做到了,我认为这可能是用mongodb做到这一点的最好方法
1。为用户创建模型。
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。为拥有已接受,已拒绝,待处理和已请求的枚举的朋友创建模型。
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. 现在api致电 - >让我们说我们有两个用户UserA和UserB ...所以当UserA请求UserB成为朋友的时候我们做两个 文档,以便UserA可以看到请求和UserB可以看到挂起 同时我们将这些文件的_id推送到用户手中 朋友
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. 如果UserB接受请求
Friend.findOneAndUpdate(
{ requester: UserA, recipient: UserB },
{ $set: { status: 3 }}
)
Friend.findOneAndUpdate(
{ recipient: UserA requester: UserB },
{ $set: { status: 3 }}
)
5. 如果UserB拒绝请求
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。获取所有朋友并检查登录用户是否是该用户的朋友
User.aggregate([
{ "$lookup": {
"from": Friend.collection.name,
"let": { "friends": "$friends" },
"pipeline": [
{ "$match": {
"recipient": ObjectId("5afaab572c4ec049aeb0bcba"),
"$expr": { "$in": [ "$_id", "$$friends" ] }
}},
{ "$project": { "status": 1 } }
],
"as": "friends"
}},
{ "$addFields": {
"friendsStatus": {
"$ifNull": [ { "$min": "$friends.status" }, 0 ]
}
}}
])
答案 1 :(得分:0)
这个问题有点晚了,但这是我的解决方法:
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
friends: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'users',
},
status: Number,
enums: [
0, //'add friend',
1, //'requested',
2, //'pending',
3, //'friends'
]
}
]
})
现在,如果要查询朋友,则可以使用聚合函数并匹配朋友列表中的所有用户:
exports.getFriends = async (req, res) => {
let {id} = req.params
let user = await User.aggregate([
{ "$match": { "_id": ObjectId(id) } },
{ "$lookup": {
"from": User.collection.name,
"let": { "friends": "$friends" },
"pipeline": [
{ "$match": {
"friends.status": 1,
}},
{ "$project": {
"name": 1,
"email": 1,
"avatar": 1
}
}
],
"as": "friends"
}},
])
res.json({
user
})
}
使用这种方法而不是创建“友谊”联接表的专业人士之一是,您可以进行较小的查询,而这些查询的成本可能较低。对我来说,这似乎也更直观。但是,我对mongo还是很陌生,所以我不太确定最佳做法是什么。