【问题标题】:how can we use $subtract aggregation pipeline operators along side with The positional $ operator in update?我们如何在更新中使用 $subtract 聚合管道运算符和位置 $ 运算符?
【发布时间】:2020-04-10 01:36:02
【问题描述】:

我有如下文件:

{

    "_id": "5e8ecce4cf2647202dfd4551",
    "logout_time": null,
    "apps": [{
        "name": "notepad",
        "open_time": "1584351875000",
        "close_time": null,
        "duration": null,
        "tasks": []
    }],
    "duration": null,
    "user_id": "5e8109ea5bc5822aa531a57d",
    "comp_id": "5e8d16a0c1834fd3d8e9e1eb",
    "org_id": "5e8c7a34c358958a58be4755",

}

所以现在当我接近时间时,我会使用以下函数在 apps.close_time 中更新它:

async function closeApp(app_name, session_id, time) {
  try {
    let updateObj = await Session.updateMany(
      { _id: session_id, "apps.name": app_name, "apps.close_time": null },
      {
        $set: {
          "apps.$[].close_time": new Date(time),
        },
      }
    );

    return {
      status: "success",
      msg: "App Added successfully",
      update_info: updateObj,
    };
  } catch (err) {
    return { status: "failed", message: err.message };
  }
}

但现在我也想将持续时间更新为close_time-open_time。 我知道它可以使用 $subtract 聚合管道来实现,它对我来说适用于非嵌套对象。 我尝试了以下不起作用的代码:

async function closeApp(app_name, session_id, time) {
  try {
    let updateObj = await Session.updateMany(
      { _id: session_id, "apps.name": app_name, "apps.close_time": null },
      [
        {
          $set: {
            "apps.$.close_time": new Date(time),
            "apps.$.duration": {
              $toInt: {
                $divide: [
                  { $subtract: [new Date(time), "$apps.$.$open_time"] },
                  60000,
                ],
              },
            },
          },
        },
      ]
    );

    return {
      status: "success",
      msg: "App Added successfully",
      update_info: updateObj,
    };
  } catch (err) {
    return { status: "failed", message: err.message };
  }
}

所以我的问题是我们如何使用 $subtract 聚合管道运算符以及位置 $ 运算符来使用 mongoose 更新 mongoDB 中的嵌套对象数组

我使用的是 mongoDB 4.2.2 版

【问题讨论】:

  • 当您在更新中使用聚合管道时,我猜$ 将不起作用,因此您需要使用聚合运算符进行更新,我没有测试我的答案,但请尝试一下知道是否有任何问题:-)
  • 效果很好,谢谢

标签: node.js mongodb mongoose


【解决方案1】:

根据评论 - 由于 'apps' 是一个数组,您需要在聚合中使用 $map 来更新元素中的值。

查询:

[
  {
    $addFields: {
      apps: {
        $map: {
          input: "$apps", /** Iterate through 'apps' array & re-create it */
          in: {
            $cond: [ /** Check for required conditions */
              { $and: [ { $eq: ["$$this.name", app_name] }, { $eq: ["$$this.close_time", null] }] },
              { /** If Yes, merge existing object with new field values */
                $mergeObjects: [
                  "$$this",
                  {
                    close_time: new Date(time),
                    duration: { $toInt: { $divide: [ { $subtract: [new Date(time), "$$this.open_time"] },60000 ]}}
                  }
                ]
              },
              "$$this" /** If No, Return the element of 'apps' to apps array */
            ]
          }
        }
      }
    }
  }
];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 2018-04-24
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多