为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Golang中运行MongoDB查询,并$cond

如何在Golang中运行MongoDB查询,并$cond

Go
江户川乱折腾 2022-09-05 10:06:20
我尝试在Golang中运行MongoDB查询并收到一些错误。如果字段“section.gateBack”等于0,我想用新的时间戳更新字段“expiresAt”。数据模型如下所示:{  "_id": "78b0e7de-c24c-11eb-8529-0242ac130003",  "expiresAt": "2021-04-22T14:06:55.069Z",  "section": {    "gateFront": 1,    "gateMiddle": 1,    "gateBack": 0  }}在第一次尝试中,我编写了查询,就像我执行其他(简单)$set操作一样,但这次使用$cond使用if-else:filter := bson.M{    "_id": iD,}update := bson.M{    "$set": bson.M{        "expiresAt": bson.M{            "$cond": bson.M{                "if": bson.M{                    "$and": []bson.M{                        {"section.gateBack": bson.M{"$eq": 0}},                        {"section.gateBack": bson.M{"$exists": true}},                    },                },                "then": time.Now().AddDate(0, 1, 0),                "else": time.Now().AddDate(0, 0, 1),            },        },    },}res, err := s.coll.UpdateOne(    ctx,    filter,    update,)但是使用此更新操作,我得到以下错误:multiple write errors: [{write errors: [{The dollar ($) prefixed field '$cond' in 'expiresAt.$cond' is not valid for storage.}]}, {<nil>}]我在MongoDB开发人员方面发现了一个问题,它说更新值必须是一个数组:https://developer.mongodb.com/community/forums/t/mongoerror-the-dollar-prefixed-field-cond-in-energy-cond-is-not-valid-for-storage/16448当我阅读MongoDB的官方文档时,这是有道理的,用于使用聚合管道的UpdateOne():https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/#example-2因此,我更改了我的更新值并将其附加到 bson 数组中。M:filter := bson.M{    "_id": iD,}var pipeline []bson.Mupdate := bson.M{    "$set": bson.M{        "expiresAt": bson.M{            "$cond": bson.M{                "if": bson.M{                    "$and": []bson.M{                        {"section.gateBack": bson.M{"$eq": 0}},                        {"section.gateBack": bson.M{"$exists": true}},                    },                },                "then": time.Now().AddDate(0, 1, 0),                "else": time.Now().AddDate(0, 0, 1),            },        },    },}pipeline = append(pipeline, update)res, err := s.coll.UpdateOne(    ctx,    filter,    pipeline,)
查看完整描述

2 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

在转换查询时,使用映射和切片类型并查找类型来代替 mongo 驱动程序别名。bson.A{bson.M{...}, bson.M{...}}[]bson.M{...}bson.M{}bson.A{}



查看完整回答
反对 回复 2022-09-05
?
湖上湖

TA贡献2003条经验 获得超2个赞

很抱歉回复晚了。我完全忘记了发布解决方案。就像@prasad_说的,我试图使用开关盒运算符,但使用.UpdateOne()


ctx := context.Background()


filter := bson.M{

    "_id": ID,

}


back := bson.M{

    "case": bson.M{

        "$and": []bson.M{

            {"$gt": []interface{}{"$section.gateBack", 0}},

            {"$exists": []interface{}{"$section.gateBack", true}},

        },

    },

    "then": time.Now().AddDate(0, 0, 1),

}


middle := bson.M{

    "case": bson.M{

        "$and": []bson.M{

            {"$gt": []interface{}{"$section.gateMiddle", 0}},

            {"$exists": []interface{}{"$section.gateMiddle", true}},

        },

    },

    "then": time.Now().AddDate(0, 1, 0),

}


front := bson.M{

    "case": bson.M{

        "$and": []bson.M{

            {"$gt": []interface{}{"$section.gateFront", 0}},

            {"$exists": []interface{}{"$section.gateFront", true}},

            {"$in": []interface{}{"$section.access", []string{"gate", "door"}}},

        },

    },

    "then": time.Now().AddDate(1, 0, 0),

}


cases := bson.A{back, middle, front}


update := []bson.M{

    {

        "$set": bson.M{

            "expiresAt": bson.M{

                "$switch": bson.M{

                    "branches": cases,

                    "default":  time.Now().AddDate(0, 0, 0),

                },

            },

        },

    },

}


res, err := coll.UpdateOne(

    ctx,

    filter,

    update,

)

if err != nil {

    return 0, err

}


查看完整回答
反对 回复 2022-09-05
  • 2 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号