php小编子墨今天为大家介绍减法聚合 Mongo 文档 Golang。在Golang开发中,使用MongoDB作为数据库是非常常见的选择。而MongoDB提供了强大的聚合框架,可以对文档进行各种复杂的聚合操作。其中,减法聚合是一种特殊的聚合操作,可以用来计算文档中某个字段的差值。本文将详细介绍如何在Golang中使用减法聚合来处理Mongo文档,帮助开发者更好地理解和应用这一功能。
我在 mongo 中有这个文档
{ "_id": { "$oid": "649d3d688a1f30bf82e77342" }, "test_value": { "$numberlong": "10" } }
我想用这个 golang 代码将“test_value”减一
jsonInput := []map[string]interface{}{ { "$match": map[string]interface{}{ "test_value": 10, }, }, { "$set": map[string]interface{}{ "test_value": map[string]interface{}{ "$subtract": []interface{}{"test_value", 1}}, }, }, }) value, bsonByte, errMarshal := bson.MarshalValue(jsonInput) if errMarshal != nil { modules.DoLog("ERROR", "", "MongoService", "aggregateDocument", "cannot Marshal jsonInput to BSONByte", true, errMarshal) ctx.IndentedJSON(200, gin.H{ "error": errMarshal.Error(), }) return } fmt.Println(value) bsonD := bson.A{} errUnmarshal1 := bson.UnmarshalValue(value, bsonByte, &bsonD) if errUnmarshal1 != nil { modules.DoLog("ERROR", "", "MongoService", "aggregateDocument", "cannot Unmarshal BSONByte to BSOND", true, errUnmarshal1) ctx.IndentedJSON(200, gin.H{ "error": errUnmarshal1.Error(), }) return } _, err := Client.Database("rhanov_queries").Collection(collectionName).Aggregate(ContextMongo, bsonD) if err != nil { modules.DoLog("ERROR", "", "MongoService", "aggregateDocument", "cannot aggregate document to Mongo", true, err) ctx.IndentedJSON(200, gin.H{ "error": err, }) }
我收到此错误
“无法将文档聚合到 mongo。无法将基元类型编组到 bson 文档:writearray 只能在位于元素或值上但位于顶层时写入数组”
我做错了什么?
"$subtract": []interface{}{"test_value", 1}
请注意,这里 "test_value"
是一个文字。该表达式的意思是从字符串test_value
中减去数字1,这是无效的,不是你想要的。您想改为引用字段路径。因此,您应该在其前面加上 $
前缀(请参阅 聚合表达式)。这是更正后的代码:
"$subtract": []interface{}{"$test_value", 1}
ps 1:
为了方便其他人调查问题,请在以后提供一个最小的可执行重现器,例如:
package main import ( "context" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { jsoninput := []map[string]interface{}{ { "$match": map[string]interface{}{ "test_value": 10, }, }, { "$set": map[string]interface{}{ "test_value": map[string]interface{}{ "$subtract": []interface{}{"test_value", 1}, // `test_value` should be prefixed with $ like this: // "$subtract": []interface{}{"$test_value", 1}, }, }, }, } typ, buf, err := bson.marshalvalue(jsoninput) if err != nil { panic(err) } fmt.println(typ) var bsond bson.a if err := bson.unmarshalvalue(typ, buf, &bsond); err != nil { panic(err) } client, err := mongo.connect(context.background(), options.client().applyuri("mongodb://localhost")) if err != nil { panic(err) } collection := client.database("demo").collection("values") cur, err := collection.aggregate(context.background(), bsond) if err != nil { panic(err) } defer cur.close(context.background()) for cur.next(context.background()) { fmt.printf("%+v", cur.current) } }
并初始化收集数据:
db.values.insert({ _id: objectid('649d3d688a1f30bf82e77342'), test_value: 10 })
(在 mongodb shell 中执行)
使用软件包 go.mongodb.org/87128337c06e8a1b9bab06a01f40021b[电子邮件受保护]5db79b134e9f6b82c0b36e0489ee08ed
和 mongo:5.0.8
,我得到的错误是:
panic: (typemismatch) failed to optimize pipeline :: caused by :: can't $subtract int from string
ps 2:
如果您不知道,您可以直接创建 bsond
变量,如下所示:
bsonD := bson.A{ bson.M{ "$match": bson.M{ "test_value": 10, }, }, bson.M{ "$set": bson.M{ "test_value": bson.M{ "$subtract": bson.A{"$test_value", 1}, }, }, }, }
ps 3:
您显示的代码存在语法错误(jsoninput
的简短声明末尾有一个额外的 )
)。更正此错误后,我认为它不会导致您在问题中显示的错误。我相信错误是针对另一个 jsoninput
值。
以上是减法聚合 Mongo 文档 Golang的详细内容。更多信息请关注PHP中文网其他相关文章!