我有user schema和invitation schema。当用户搜索用户时,我希望返回具有属性invited的对象的数组。
const InvitationSchema = new Schema<IInvitation>(
{
sender: {
type: Schema.Types.ObjectId,
ref: 'user'
},
receiver: {
type: Schema.Types.ObjectId,
ref: 'user'
}
}
)
const IUserSchema = new Schema<IUser>(
{
email: {
type: String,
},
invitedUsers: [
{
type: Schema.Types.ObjectId,
ref: 'user'
}
]
}
)我的问题是:
user1:{
id:userId1,
invitedUsers:[userId2]
}
invitation1:{
id:someId,
sender:userId1,
receiver:userId2
}users:[
{
id:userId2,
invited:true
},
{
id:userId3,
invited:false
},
]我还想对用户进行分页,但它不是当前问题的目标。
我尝试了一些使用聚合$addFields的变体,但是没有任何效果。另一种方法是增加10个查询,因为每个页面的用户是10个,这当然是个坏主意。
发布于 2022-06-15 18:52:08
这是个不错的问题。一种选择是使用$lookup来完成它。
id中。db.users.aggregate([
{$match: {id: {$ne: requestingUserId}}},
{$sort: {id: 1}},
{$skip: 1},
{$limit: 2},
{$addFields: {invitedBy: requestingUserId }},
{
$lookup: {
from: "users",
localField: "invitedBy",
foreignField: "id",
as: "invited"
}
},
{$set: {invited: {$first: "$invited"}}},
{
$project: {
invited: {$cond: [{$in: ["$id", "$invited.invitedUsers"]}, true, false] },
id: 1, _id: 0
}
}
])看看它如何在操场实例上工作
还可以通过使用$lookup管道来只带来所需的部分来提高性能:
db.users.aggregate([
{$match: {id: {$ne: requestingUserId}}},
{$sort: {id: 1}},
{$skip: 1},
{$limit: 2},
{
$lookup: {
from: "users",
let: {myId: "$id"},
pipeline: [
{$match: {id: "userId1"}},
{$project: {res: {$cond: [{$in: ["$$myId", "$invitedUsers"]}, true, false]}}}
],
as: "invited"
}
},
{$project: {invited: {$first: "$invited.res"}, id: 1, _id: 0}}
])看看它如何在操场示例.查找-管道上工作
发布于 2022-06-15 08:05:16
如果要检查invitedUsers数组是否具有一定长度,则返回true,否则为false,则可以使用聚合完成这一操作。
User.aggregate([
{
$project: {
_id: 1,
invitedUsers: {
$cond: [
{ $gt: [{ $size:"$invitedUsers" }, 0] },
true,
false,
],
}
}
}
])探索聚合这里
https://stackoverflow.com/questions/72622107
复制相似问题