MongoDB使用lookup关联外集合带条件查询用户可见文档问题
问题排查
两种写法的错误点如下:
- 第一种写法:
- 仅过滤了关联后的
user字段值,没有追加$match阶段过滤user为null的文档,导致所有文档都被保留,出现跨部门数据 - 最后的
$project语法错误,缺少结束单引号
- 仅过滤了关联后的
- 第二种写法:
$lookup的子管道$match中错误添加了"_id": user_department条件,users集合的_id是用户ID字符串,和部门数字ID完全不匹配,导致关联得到的user数组全为空,没有起到过滤作用- 同样缺少过滤空
user数组的阶段,所有文档都被返回
可行解决方案
核心逻辑:登录后先拿到当前用户的权限属性,再按用户类型走对应查询逻辑,避免不必要的关联操作。
首先获取登录用户的基础信息:
# 假设当前登录用户ID为current_user_id current_user = db.users.find_one({"_id": current_user_id})
1. writer类型用户
直接匹配文档的创建人ID即可,性能最优:
if current_user["user_type"] == "writer": accessible_docs = list(db.docs.find( {"user_id": current_user["_id"]}, {"name": 1, "_id": 0} ))
2. admin_writer类型用户
关联用户集合过滤同部门用户的所有文档:
elif current_user["user_type"] == "admin_writer": target_dept = current_user["department"]["value"] pipeline = [ { "$lookup": { "from": "users", "localField": "user_id", "foreignField": "_id", "as": "user" } }, {"$unwind": "$user"}, {"$match": {"user.department.value": target_dept}}, {"$project": {"name": 1, "_id": 0}} ] accessible_docs = list(db.docs.aggregate(pipeline))
3. admin类型用户
先查询当前用户所属集团的所有部门ID,再关联过滤对应部门的所有文档:
elif current_user["user_type"] == "admin": # 先查当前用户所属部门对应的集团 user_dept_id = int(current_user["department"]["value"]) current_group = db.departments.find_one({"_id": user_dept_id})["group"] # 查集团下所有部门的ID列表 group_dept_ids = [str(dept["_id"]) for dept in db.departments.find({"group": current_group}, {"_id": 1})] # 聚合查询 pipeline = [ { "$lookup": { "from": "users", "localField": "user_id", "foreignField": "_id", "as": "user" } }, {"$unwind": "$user"}, {"$match": {"user.department.value": {"$in": group_dept_ids}}}, {"$project": {"name": 1, "_id": 0}} ] accessible_docs = list(db.docs.aggregate(pipeline))
以上逻辑完全匹配你给出的预期返回结果。
内容的提问来源于stack exchange,提问作者yassine khelifa
相关产品推荐
相关产品推荐

