从mongodb中的参考文档访问数据

时间:2018-12-06 18:45:32

标签: mongodb mongodb-query aggregation-framework

我有类似的用户集合

{
    "_id" : "xyz@xyz.com",
    "name" : "First Last",
    "permission" : ObjectId("5bf4e199e2a30916d6eaeb8c")
}
{
    "_id" : "abc@xyz.com",
    "name" : "Name Last",
    "permission" : ObjectId("5bf4e199e2a30916d6eaeb8c")
}

权限是参考字段,是另一个集合Permission的一部分。 权限收集就像

{
    "_id" : ObjectId("5bf4e199e2a30916d6eaeb8c"),
    "name" : "Admin"
}
{
    "_id" : ObjectId("5548e199e2a30916d6kj7856"),
    "name" : "Super Admin"
}

我正在使用汇总之类的方法从用户集合中获取数据

    db.user.aggregate([{'$project': {
        '_id' : 1,
        'name' : "$name",
        'permission' : "$permission.name"
        } 
    }])

我想从权限收集中获取名称的内容。 输出是

{'name': 'First Last', 'user_company': 'abc', '_id': 'xyz@xyz.com'}
{'name': 'Last Name', 'user_company': 'NEW COMPANY', '_id': 'abc@abc.com'}

应该像

{'name': 'First Last', 'user_company': 'abc', '_id': 'xyz@xyz.com', permission : "Admin"}
{'name': 'Last Name', 'user_company': 'NEW COMPANY', '_id': 
'abc@abc.com', 'permission' : "Super Admin"
}

如何获得结果?

2 个答案:

答案 0 :(得分:1)

您可以在mongodb 3.6 及更高版本

中使用以下聚合
db.users.aggregate([
  { "$lookup": {
    "from": "permissions",
    "let": { "permission": "$permission" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$_id", "$$permission"] }}}
    ],
    "as": "permission"
  }},
  { "$addFields": { 
    "permission": { "$arrayElemAt": ["$permission.name", 0] }
  }}
])

或者使用 3.6

之前的mongodb版本
db.users.aggregate([
  { "$lookup": {
    "from": "permissions",
    "localField": "permission",
    "foreignField": "_id",
    "as": "permission"
  }},
  { "$addFields": { 
    "permission": { "$arrayElemAt": ["$permission.name", 0] }
  }}
])

答案 1 :(得分:1)

如果您将经常运行这种查询,建议将权限直接存储在user集合中作为字符串或嵌入式数组(如果一个用户映射到多个用户) ,这样您就不必加入。

通常,要进行联接,请使用$lookup。要实现您想要的目标,您可以执行以下操作:

db.user.aggregate([
{ $lookup: { from: "permission", localField: "permission", foreignField: "_id", as: "perm" } },
{ $unwind: "$perm"}, 
{ $project: {  '_id' : 1,  'name' : "$name",  'permission' : "$perm.name" }}
])

需要$unwind阶段来平整“权限”。如果不需要,可以跳过。

相关问题