MongoDB: link to another document with additional information

I have a situation where I have a group document type. I want to have a list box that contains the link identifier for users in the group. I need to specify which users have administrator access. Should I have two lists, one of ordinary users and one of admins, or should I have my own document that I embed in a list that has only the link identifier and the bool value? This is basically a lot for many, with both documents having a list of reference identifiers for other documents. I'm just not sure how to incorporate this other value.

If that matters, I use Python / Mongoengine to access MongoDB

+4
source share
1 answer

There are various ways to model your requirement in the current form. I will try to show you one such method and use $ lookup . You should try with two separate collections, one for each group and users, as shown below.

Another option would be to use $ DBRef , which will load all users in the group when you receive the group collection. This option will depend on the python driver, and I'm sure the driver supports this.

Groups document

{
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"),
    "name": "newGroup",
    "usersId": ["user1", "user2"]
}

User Document

{ "_id" : "user1", "isAdmin" : true }
{ "_id" : "user2" }

Get all users in a group

db.groups.aggregate({
    $unwind: '$usersId'
}, {
    $lookup: {
        from: "users",
        localField: "usersId",
        foreignField: "_id",
        as: "group_users"
    }
})

answer

{
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"),
    "name": "newGroup",
    "usersId": "user1",
    "group_users": [{
        "_id": "user1",
        "isAdmin": true
    }]
} {
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"),
    "name": "newGroup",
    "usersId": "user2",
    "group_users": [{
        "_id": "user2"
    }]
}

Admin

db.groups.aggregate({
    $unwind: '$usersId'
}, {
    $lookup: {
        from: "users",
        localField: "usersId",
        foreignField: "_id",
        as: "group_users"
    }
}, {
    $match: {
        "group_users.isAdmin": {
            $exists: true
        }
    }
})

{
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"),
    "name": "newGroup",
    "usersId": "user1",
    "group_users": [{
        "_id": "user1",
        "isAdmin": true
    }]
}

:

- admin , . -.

, , -. , , .

{ "_id" : "newGroup", "userIds" : [ "user1" ], "adminIds" : [ "user2" ] }

{ "_id" : "user1", "groupIds" : [ "newGroup" ] } -- regular user in newGroup
{ "_id" : "user2", "groupIds" : [ "newGroup" ] } -- admin user in newGroup.
{ "_id" : "user3", "groupIds" : [ ] }

db.groups.aggregate({
    $unwind: '$userIds'
}, {
    $lookup: {
        from: "users",
        localField: "userIds",
        foreignField: "_id",
        as: "group_users"
    }
})

Admin

db.groups.aggregate({
    $unwind: '$adminIds'
}, {
    $lookup: {
        from: "users",
        localField: "adminIds",
        foreignField: "_id",
        as: "group_users"
    }
})
+2

Source: https://habr.com/ru/post/1664021/


All Articles