能否在单个MongoDB聚合管道中查询多文档并添加is_following字段?
实现单次聚合查询添加
is_following字段的解决方案 当然可以实现!你不需要分开两次查询,通过MongoDB的$lookup操作符配合聚合管道,就能在单次查询里同时获取认证用户的关注列表和目标用户的详情,然后计算出is_following字段。
具体聚合管道实现
这里直接给出针对你需求的完整聚合代码,我会一步步解释每个阶段的作用:
db.users.aggregate([ // 1. 先定位目标用户(用户B)的文档 { $match: { _id: <目标用户B的_id> } }, // 2. 通过嵌套管道查询认证用户(用户A)的关注列表 { $lookup: { from: "users", pipeline: [ { $match: { _id: <认证用户A的_id> } }, { $project: { following: 1, _id: 0 } } // 只保留following字段,减少数据传输 ], as: "auth_user_data" } }, // 3. 展开lookup返回的数组(因为只会匹配到一个认证用户,展开后方便后续操作) { $unwind: "$auth_user_data" }, // 4. 添加is_following字段,判断目标用户是否在认证用户的关注列表中 { $addFields: { is_following: { $in: ["$_id", "$auth_user_data.following"] } } }, // 5. 移除临时的auth_user_data字段,输出干净的用户详情 { $project: { auth_user_data: 0 } } ])
步骤详解
- $match:首先精准匹配我们要返回详情的目标用户(用户B),这是聚合的起点,减少后续处理的数据量。
- $lookup:利用嵌套的
pipeline单独查询认证用户(用户A)的following数组,避免获取无关数据。查询结果会被存入auth_user_data字段(一个数组)。 - $unwind:因为
$lookup返回的是数组格式(哪怕只有一个匹配结果),展开后可以直接访问数组内的following字段,方便后续判断。 - $addFields:使用
$in操作符检查目标用户的_id是否存在于认证用户的following数组中,生成布尔值的is_following字段。 - $project:移除之前生成的临时字段
auth_user_data,让输出结果只保留目标用户的原始信息和新增的is_following字段。
验证预期输出
当认证用户A的_id为2,查看用户B的_id为1时,执行上述聚合会得到:
{ _id: 1, name: 'David', following: [2, 3], is_following: true }
当认证用户A的_id为2,查看用户B的_id为3时,输出:
{ _id: 3, name: 'Lucy', following: [1, 2], is_following: false }
完全符合你的预期需求,而且整个逻辑只需要一次数据库查询,相比两次查询效率更高。
内容的提问来源于stack exchange,提问作者Jamie Street
相关产品推荐
相关产品推荐

