Home > Backend Development > Golang > Subtractive Aggregation Mongo Documentation Golang

Subtractive Aggregation Mongo Documentation Golang

WBOY
Release: 2024-02-08 21:05:36
forward
1159 people have browsed it

减法聚合 Mongo 文档 Golang

php editor Zimo will introduce to you the subtractive aggregation Mongo document Golang today. In Golang development, using MongoDB as the database is a very common choice. MongoDB provides a powerful aggregation framework that can perform various complex aggregation operations on documents. Among them, subtractive aggregation is a special aggregation operation that can be used to calculate the difference of a certain field in the document. This article will introduce in detail how to use subtractive aggregation to process Mongo documents in Golang, helping developers better understand and apply this function.

Question content

I have this document in mongo

{
  "_id": {
    "$oid": "649d3d688a1f30bf82e77342"
  },
  "test_value": {
    "$numberlong": "10"
  }
}
Copy after login

I want to use this golang code to decrement "test_value" by one

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,
        })
    }
Copy after login

I'm getting this error

"Cannot aggregate document to mongo. Unable to marshal primitive type to bson document: writerarray can only write to array when on element or value but at top level"

What did i do wrong?


Correct answer


"$subtract": []interface{}{"test_value", 1}
Copy after login

Please note that here "test_value" is a literal. The expression means to subtract the number 1 from the string test_value, which is invalid and not what you want. You want to quote the field path instead. Therefore, you should prefix it with $ (see Aggregation Expressions). Here is the corrected code:

"$subtract": []interface{}{"$test_value", 1}
Copy after login

ps 1

To make it easier for others to investigate the issue, please provide a minimal executable reproducible in the future, for example:

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)
    }
}
Copy after login

And initialize data collection:

db.values.insert({ _id: objectid('649d3d688a1f30bf82e77342'), test_value: 10 })
Copy after login

(Executed in mongodb shell)

Use packagego.mongodb.org/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5e3331303931733a2c37283b2c1e286f706f6c706e">[Email protected protect]</a> and mongo:5.0.8, the error I get is:

panic: (typemismatch) failed to optimize pipeline :: caused by :: can't $subtract int from string
Copy after login

ps 2:

If you don't know, you can directly create the bsond variable like this:

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},
            },
        },
    },
}
Copy after login

ps 3

The code you show has a syntax error (an extra ) at the end of the short declaration of jsoninput). After correcting this I don't think it will cause the error you show in your question. I believe the error is for another jsoninput value.

The above is the detailed content of Subtractive Aggregation Mongo Documentation Golang. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template