仅当 golang 中未设置值时如何更新 MongoDB 文档字段

jas*_*135 6 go mongodb

我有一个包含以下文档的集合:

{ID: xxx, firstCreateDate: xxx, isActive: false}
Run Code Online (Sandbox Code Playgroud)
  1. 我想找到所有文档isActive = false,然后更新isActive为 true,如果之前未设置,也更新firstCreateDate为当前日期。我不确定如何有条件地更新提交的firstCreateDate。目前无法进行有条件更新。得到 firstCreateDate = {$cond:[{"firstCreateDate":{"$exists":false}}, "$firstCreateDate", newdata]}
  2. 我还想使用自定义函数根据原始ID字段生成新字段internalID。我尝试使用UpdateMany(),但似乎无法使用您自己的函数获取该值并计算新值。我正在考虑使用Find()查找所有文档,然后对其进行解码,然后根据id一一更新文档。对此有更好的解决方案吗?

这就是我现在所拥有的:

filter := bson.M{"isActive": false}
update := bson.M{"set": bson.M{"isActive": true, "firstCreateDate": bson.M{
  "$cond": bson.A{
    bson.M{"firstCreateDate", bson.M{"$exists", false}},
    "$firstCreateDate",
    newDate,
  }
}}}

collection.UpdateByID(
  context.Background(),
  id,
  update,
)
Run Code Online (Sandbox Code Playgroud)

我正在使用mongo-driver lib,任何人都可以提供帮助

Sco*_*ott -1

一些东西..

  1. 如果您使用 _id 默认值,它将为您生成,您可以直接从那里提取创建日期。老实说,这主要是一个偏好问题,您是否想在文档中看到清晰的日期以提高可读性,或者只是获取生成的 _id 中存在的内容。
  2. 我以前没有必要解决第二个要求。就我个人而言,我永远不会在子文档中生成 ObjectId,除非它们是另一个集合的外键。如果是这种情况,我将首先在另一个集合中生成 ObjectID,然后通过插入引用将该 _id 与此集合关联起来。
  3. 您可以在 updateMany 语句中使用聚合管道。$set采用与投影运算符基本相同的语法。

这是 updateMany 将解决您的第一个问题。它使用 mongosh 语法,但您应该能够将逻辑转换为 go。

db.collection.updateMany(
    { isActive: false }, 
    [{$set: {
        firstCreateDate: {
            $ifNull: [
                '$firstCreateDate',
                ISODate('2022-03-26T03:52:45.240Z')
            ]
        },
        isActive: {
            $toBool: true
        },
        _idExtractDate: {
            $convert: {
                input: '$_id',
                to: 'date'
            }
        }
    }}]
);
Run Code Online (Sandbox Code Playgroud)