在嵌入的子文档下插入一个新对象

Insert a new object under embedded subdocument

这是我的示例记录:

如上图突出显示的建筑物 id,有一个子文档 gateways。 我能够找到建筑物 ID,但不确定如何在 gateways 子文档下推送/插入新的对象网关。

这是我要从请求中插入的新网关对象的正文。

{
    "gatewayName": "gatewayName",
    "gatewayKey": "sampleKey",
    "suite": "3300"
}

这就是我目前正在尝试的。它returns同一个文件。
首先我找到帐户,然后开始构建。然后根据提供的buildingId查找建筑物。 我需要在 Gateways 子文档

下插入一个新的网关对象
   const account = await Account.findOne({ _id: new ObjectId(req.query.id) });
      const allBuildings = account.buildings;
      const filteredBuildings = _.filter(allBuildings, { _id: ObjectId(req.query.buildingId) });
      const gateways = _.flatMap(filteredBuildings, b => b.gateways);

      gateways.push({
        "gatewayName": "TD Bank Tower22223",
        "gatewayKey": "sdasdasdasd",
                  "suite": "3300"
      }
      );
      const updatedAccount = await account.save();
      console.log(updatedAccount)
res.json(updatedAccount);

是的,您可以使用 $elemMatch, $addToSet and the $ 运算符在单个 findOneAndUpdate 中完成查找和更新。

首先匹配数组中的文档 ID 和建筑物 ID。 然后,您可以使用 $ 运算符访问匹配的建筑物,并使用 $addToSet 插入新的数组元素。

示例:

const gateway = {
    "gatewayName": "gatewayName",
    "gatewayKey": "sampleKey",
    "suite": "3300"
};

const update = await Account.findOneAndUpdate(
    {
        _id: new ObjectId(req.query.id),
        buildings: {$elemMatch: {_id: {$eq: ObjectId(req.query.buildingId)}}}
    },
    {
        $addToSet: {"buildings.$.gateways": gateway}
    },
    {
        new: true
    }
);

我能够使用更简单的方法挖掘子文档。 我在这里发布答案,以便其他人可以使用它。

如果要查找嵌入的子文档:

var gateway = account.buildings.id(req.params.buildingId).gateways.id(req.params.gatewayId);

使用 .id(_id) 有助于更快地通过 ID 查找对象。

如果您想从深层嵌套的子文档中删除对象:

account.buildings.id(req.params.buildingId).gateways.id(req.params.gatewayId).devices.pull(req.params.deviceId);

以上将删除该元素。那么您只需使用 collectionName.save()

保存文档