MongoDB添加/替换来自单独集合的元素

ruarlubt  于 2023-02-03  发布在  Go
关注(0)|答案(1)|浏览(118)

我收集了两个mongodb,* * 流程用户**及以下我有它们的示例文档。我尝试查询流程文档,但将嵌套在事件对象中的用户ID替换为用户名而不是用户ID。如果我在"历史"对象中可能有多个嵌套对象,最好的方法是什么?(在节点上运行并使用本机驱动程序,而不是使用mongoose)。

    • 工艺文件**
{
    _id: ObjectId('63d96b68e7b92dceb334f4cb'),
    status: 'active',
    history: {
        {
            type: 'created',
            userID: '61e77cdedde2dbe1cbf8a250',
            date: 'Tue Jan 31 2023 17:31:32 GMT+0000 (Coordinated Universal Time)'
        },
        {
            type: 'updated',
            userID: 'd6xMtHTIX3QO0FifUPgoJLOLz872',
            date: 'Tue Jan 31 2023 18:31:32 GMT+0000 (Coordinated Universal Time)'
        },
        {
            type: 'updated',
            userID: '61e77cdedde2dbe1cbf8a250',
            date: 'Tue Jan 31 2023 19:31:32 GMT+0000 (Coordinated Universal Time)'
        },

    }
}
    • 用户1文档**
{
    _id: ObjectId('d6xMtHTIX3QO0FifUPgoJLOLz872'),
    email: 'something@something.com',
    firstname: 'Bobby',
    lastname: 'Tables',
}
    • 用户2文档**
{
    _id: ObjectId('61e77cdedde2dbe1cbf8a250'),
    email: 'something2@something.com',
    firstname: 'Jenny',
    lastname: 'Tables',
}
    • 我要找的实际产量**
{
    _id: ObjectId('63d96b68e7b92dceb334f4cb'),
    status: 'active',
    history: {
        {
            type: 'created',
            userName: 'Jenny Tables',
            date: 'Tue Jan 31 2023 17:31:32 GMT+0000 (Coordinated Universal Time)'
        },
        {
            type: 'updated',
            userName: 'Bobby Tables',
            date: 'Tue Jan 31 2023 18:31:32 GMT+0000 (Coordinated Universal Time)'
        },
        {
            type: 'updated',
            userName: 'Jenny Tables',
            date: 'Tue Jan 31 2023 19:31:32 GMT+0000 (Coordinated Universal Time)'
        },

    }
}
    • 下面是我尝试过的方法**,我可以生成现有数据并更新一条记录的名称,但不是所有记录:
try {
    const db = mongo.getDB();
    const data = db.collection("processes");
    data.aggregate([
        {$sort: {_id: -1}}, 
        {$lookup: {from: 'users', localField: 'history.userID', foreignField: '_id', as: 'User'}},
        {$unwind: '$User'},
        {$addFields: {"history.userName": { '$concat': ['$User.firstname', ' ', '$User.lastname']}}},
        {$project:{_id: 1, status: 1, history: 1}}
    ]).toArray(function(err, result) {
        if (err)
            res.status(500).send('Database array error.');
        console.log(result);
        res.status(200).send(result);
    });

} catch (err) {
    console.log(err);
    res.status(500).send('Database error.');
}
    • 编辑:**

前一个答案很可能是正确的,我得到的错误是由于在用户集合上使用uid而不是_id(我相信):
下面是我的尝试:

data.aggregate([
    {$unwind: "$history"},
    {"$lookup": {from: "users", localField: "history.userID", foreignField: "uid", as: "userLookup"}},
    {$unwind: "$userLookup"},
    {$project: {status: 1, history: {type: "$history.type", userName: {"$concat": ["$userLookup.firstname"," ","$userLookup.lastname"]}, date: "$history.date"}}},
    {$group: {_id: "$_id",status: {$first: "$status"}, history: {push: "$history"}}},
    {"$merge": {into: "process", on: "_id",whenMatched: "merge"}}
]).toArray(function(err, result) {
    console.log(result);
    if (err)
    {
        res.status(500).send('Database array error.');
        console.log(err);
    }
    else
        res.status(200).send(result);
});

用户文档(现在):

{
    _id: ObjectId('d6xMtHTIX3QO0FifUPgoJLOLz872'),
    uid: 'werwevmA5gZ2Ky2MUuSAj6TJiZz1',
    email: 'something@something.com',
    firstname: 'Bobby',
    lastname: 'Tables',
}
s1ag04yj

s1ag04yj1#

您可以先对历史数组执行$unwind。对user集合执行$lookup。构建新的历史对象。最后将$group恢复为原始形式,并对集合执行$merge更新。

db.processes.aggregate([
  {
    $unwind: "$history"
  },
  {
    "$lookup": {
      from: "users",
      localField: "history.userID",
      foreignField: "_id",
      as: "userLookup"
    }
  },
  {
    $unwind: "$userLookup"
  },
  {
    $project: {
      status: 1,
      history: {
        type: "$history.type",
        userName: {
          "$concat": [
            "$userLookup.firstname",
            " ",
            "$userLookup.lastname"
          ]
        },
        date: "$history.date"
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      status: {
        $first: "$status"
      },
      history: {
        $push: "$history"
      }
    }
  },
  {
    "$merge": {
      into: "process",
      on: "_id",
      whenMatched: "merge"
    }
  }
])

Mongo Playground

相关问题