在将新的值追加到mongo db之前,我try 判断mongo db上是否存在值,但每次都收到错误.

    obId, _ := primitive.ObjectIDFromHex(id)
        query := bson.D{{Key: "_id", Value: obId}}
    
        var result bson.M
        er := r.collection.FindOne(ctx, bson.M{"_id": obId, "statusData.status": bson.M{"$in": []string{string(p.Status)}}}).Decode(&result)
        if er != nil {
            if er == mongo.ErrNoDocuments {
                return nil, errors.New(fmt.Sprintf("ERR NA  %v, %v", er.Error(), p.Status))
            }
            return nil, errors.New(fmt.Sprintf("ERR NORR  %v", er.Error()))
        }

doc, err := Utils.ToDoc(p)
    if err != nil {
        return nil, errors.New(err.Error())
    }

    update := bson.D{{Key: "$set", Value: doc}}
    res := r.collection.FindOneAndUpdate(ctx, query, update, options.FindOneAndUpdate().SetReturnDocument(1))

我的文档如下所示

{
  "statusData": [
                {
                    "status": "new",
                    "message": "You created a new dispatch request",
                    "createdAt": "1657337212751",
                    "updatedAt": null
                },
                {
                    "status": "assigned",
                    "message": "Justin has been assigned to you",
                    "createdAt": "1657412029130",
                    "updatedAt": null,
                    "_id": "62ca19bdf7d864001cabfa4a"
                }
            ],
            "createdAt": "2022-07-10T00:09:01.785Z",

. }

存在不同的状态,我希望确保在使用新值更新数据库之前,相同的状态不会多次发送到数据库.

type StatusType string

const (
    NEW              StatusType = "new"
    ACKNOWLEDGED     StatusType = "acknowledged"
    ASSIGNED         StatusType = "assigned"
    REJECT           StatusType = "rejected"
    CANCEL           StatusType = "cancelled"
    COMPLETE         StatusType = "completed"
)

Utils.ToDoc

func ToDoc(v interface{}) (doc *bson.D, err error) {
    data, err := bson.Marshal(v)
    if err != nil {
        return
    }

    err = bson.Unmarshal(data, &doc)
    return
}

已try 更新

filter := bson.M{
        "_id":               obId,
        "statusData.status": bson.M{"$ne": p.Status},
    }
    update := bson.M{
        "$push": bson.M{
            "statusData": newStatusToAdd,
        },
        "$set": bson.D{{Key: "$set", Value: doc}},
    }

    result, err := r.collection.UpdateOne(ctx, filter, update)
    if err != nil {
        // Handle error
        return nil, errors.New(err.Error())
    }
    if result.MatchedCount == 0 {
        // The status already exists in statusData
    } else if result.ModifiedCount == 1 {
        // new status was added successfuly
    }

返回错误

"写入异常:写入错误:[美元($)前缀字段‘$set’ 在更新替换的上下文中不允许使用‘$set’中的 文件.考虑使用具有$replaceWith的聚合管道.]"

推荐答案

使用同时排除具有要添加的状态的文档的筛选器.如果数组中已存在状态,则此筛选器将不匹配任何文档.只有当状态尚未添加时,才会执行更新操作:

var newStatusToAdd = ... // This is the new statusData document you want to add

filter := bson.M{
    "_id": obId,
    "statusData.status": bson.M{"$ne": p.Status},
}
update := bson.M{
    "$push": bson.M{
        "statusData": newStatusToAdd,
    },
    "$set": doc,
}

result, err := r.collection.UpdateOne(ctx, filter, update)
if err != nil {
    // Handle error
    return
}
if result.MatchedCount == 0 {
    // The status already exists in statusData
} else if result.ModifiedCount == 1 {
    // new status was added successfuly
}

Mongodb相关问答推荐

如何在Golang保存到MongoDB时排除空数据值的问题?

Golang中的Mongo中值运算

MongoDB Aggregate 根据时间进行多重分组

如何向所有文档添加一个字段,其中前 100 个文档的值为 1,接下来的 100 个文档的值为 2,依此类推?

MongoDB:嵌套数组计数+原始文档

为什么使用整数作为 pymongo 的键不起作用?

查找对象是否在预保存钩子mongoose中更改

如何使用 Spring Data MongoDB 通过 GridFS ObjectId 获取二进制流

如何在任意深度查找 MongoDB 字段名称

ExpressJS & Mongoose REST API struct :最佳实践?

mongodb无法启动

在 mongodb 的一次更新调用中推送到两个单独的数组

MongoError: The dollar ($) prefixed field '$push' in '$push' is not valid for storage

在 mongodb 中插入当前日期时间

如何使用 MongoDB C# 驱动程序有条件地组合过滤器?

Mongoose Select 要从 findOneAndUpdate 返回的字段

MongoDB聚合框架的索引优化

MongoDB:删除唯一约束

MongoDB 引用的最佳实践

MongoMapper 和迁移