卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34438本站已运行393

减法聚合 Mongo 文档 Golang

减法聚合 mongo 文档 golang

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/[电子邮件受保护]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 值。

卓越飞翔博客
上一篇: 仅当满足特定条件时才创建 GO 结构
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏