Maison  >  Article  >  développement back-end  >  Agrégation soustractive Documentation Mongo Golang

Agrégation soustractive Documentation Mongo Golang

WBOY
WBOYavant
2024-02-08 21:05:361114parcourir

减法聚合 Mongo 文档 Golang

L'éditeur PHP Zimo vous présentera aujourd'hui le document d'agrégation soustractive Mongo Golang. Dans le développement Golang, utiliser MongoDB comme base de données est un choix très courant. MongoDB fournit un cadre d'agrégation puissant qui peut effectuer diverses opérations d'agrégation complexes sur des documents. Parmi eux, l'agrégation soustractive est une opération d'agrégation spéciale qui peut être utilisée pour calculer la différence d'un certain champ dans le document. Cet article présentera en détail comment utiliser l'agrégation soustractive pour traiter les documents Mongo dans Golang, aidant ainsi les développeurs à mieux comprendre et appliquer cette fonction.

Contenu de la question

J'ai ce document en mongo

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

Je veux décrémenter "test_value" de un en utilisant ce code golang

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,
        })
    }

J'ai eu cette erreur

"Impossible d'agréger le document dans mongo. Impossible de rassembler le type primitif vers le document bson : Writerarray ne peut écrire dans un tableau que lorsqu'il est sur un élément ou une valeur mais au niveau supérieur"

Qu'est-ce que j'ai fait de mal ?


Bonne réponse


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

Notez qu'il existe un préfixe "test_value" 是一个文字。该表达式的意思是从字符串test_value中减去数字1,这是无效的,不是你想要的。您想改为引用字段路径。因此,您应该在其前面加上 $ (voir Expressions d'agrégation). Voici le code corrigé :

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

ps 1:

Pour permettre aux autres d'enquêter plus facilement sur le problème, veuillez fournir un exécutable minimal reproductible à l'avenir, par exemple :

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)
    }
}

Et initialisez la collecte de données :

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

(exécuté dans mongodb shell)

En utilisant le package go.mongodb.org/87128337c06e8a1b9bab06a01f40021b[电子邮件受保护]5db79b134e9f6b82c0b36e0489ee08edmongo:5.0.8, l'erreur que j'obtiens est :

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

ps 2 :

Si vous ne le savez pas, vous pouvez directement créer la variable bsond comme ceci :

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:

Le code que vous avez montré comporte une erreur de syntaxe (jsoninput 的简短声明末尾有一个额外的 ))。更正此错误后,我认为它不会导致您在问题中显示的错误。我相信错误是针对另一个 jsoninput valeur.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer