我有一个非常简单的文档 struct ,如:

{
  "_id": "...",
  "vector": [100,50,4000],
  //...
}

我想写一个update语句,它将一个给定的文档id的vector改变一个给定的delta(也是一个整数向量).[100,50,4000]加上Δ [-50,0,-2000]的结果是[50,50,2000].

如果结果向量有任何负值,我还希望语句失败.

我该怎么做?

推荐答案

您可以使用带有聚合管道的更新来实现这一点.为了只更新具有匹配id的文档,您需要对_id字段应用一个过滤器.

为了能够区分未找到和未修改(由于负值),您需要应用聚合管道:

  1. 计算新的矢量值并将其存储在字段vector_updated中.
  2. 判断是否有任何vector_updated的值小于0.如果是,则保持vector字段不变;否则,从`VECTOR_UPDATED中分配新值.
  3. 取消设置vector_updated字段.

这样,如果文档匹配,则更新操作的结果返回matchedCount的1,如果文档更新,则返回modifiedCount的1.

这是聚合管道的示例:

db.collection.update({
  _id: 1
},
[
  {
    $set: {
      vector_updated: {
        $reduce: {
          input: "$vector",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              [
                {
                  $add: [
                    "$$this",
                    {
                      $arrayElemAt: [
                        [
                          -50,
                          0,
                          -2000
                        ],
                        {
                          $size: "$$value"
                        }
                      ]
                    }
                  ]
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    $set: {
      vector: {
        $cond: {
          if: {
            $lt: [
              {
                $min: "$vector_updated"
              },
              0
            ]
          },
          then: "$vector",
          else: "$vector_updated"
        }
      }
    }
  },
  {
    $unset: "vector_updated"
  }
])

看看这个mongoplayground来测试一下.

Mongodb相关问答推荐

在出现错误时忽略mongodb事务回滚是好做法吗

MongoDB/Mongoose查询:使用优先约束检索从位置A到位置B的路径

如何在MongoDB中对两个数组进行分组?

获取响应周期中的特定键和值

多键索引,性能问题

从具有多个数组匹配 MongoDB 的两个集合中采样数据

随着时间的推移在 mongodb 中获得

使用名为 Object 键的 uuid 创建 mongodb 文档

如何将 MongoDB 集合中的 _id 字段更改为 User_id?

MongoDB:插入重复键更新

MongoDB - 如果新值更大,则更新字段

mongodb 中的 --bindip 配置选项有什么作用?

Mongodb插入没有_id字段的文档

NodeJS中的密码重置

有没有办法为 mongoose.js 聚合提供 allowDiskUse 选项?

无法连接到远程 mongodb 服务器

如何从 node.js 以编程方式执行 mongodump 命令?

使用 Java 驱动程序更新 MongoDB 中的数组

我如何将 mongodb 与electron一起使用?

如何在 Windows 上停止 mongodb 服务器?