3 votes

Démarchage des données BSON à l'aide de Gobson/Mgo

Je reçois différents documents BSON, dont voici un exemple :

{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }

J'essaie d'utiliser mgo/gobson pour démarshaliser ces données dans un map[string]interface{}, mais j'obtiens toujours une erreur. Le code de démarchage est le suivant

var record map[string]interface{}

err := bson.Unmarshal(data, &record)

Cela a donné lieu à une erreur indiquant que le document était corrompu. En regardant dans le code, j'ai vu qu'il s'attendait à ce que la longueur du tableau d'octets soit les premiers octets. J'ai donc ajouté un code similaire à celui trouvé dans les tests.

rec := make([]byte, len(data)+6)
binary.LittleEndian.PutUint32(rec, uint32(len(rec)))
copy(rec[4:], data)

Cela m'a permis de passer l'erreur de document corrompu, mais maintenant j'obtiens

Unknown element kind (0x7B)

Qu'est-ce qui ne va pas pour que je ne puisse pas facilement démarchander le document BSON ci-dessus dans une carte ? Y a-t-il un problème avec le document BSON lui-même ? Je ne suis pas le créateur du document BSON, mais je suis en mesure de leur fournir des informations en retour si nécessaire.

2voto

foecum Points 437

J'ai essayé votre code ci-dessus et j'ai réussi à le faire "fonctionner". La raison pour laquelle vous obtenez

Unknown element kind (0x7B)

c'est parce qu'il n'y a pas d'élément de type 0x7B dans la spécification BSON. Voir ici http://bsonspec.org/spec.html . L'élément inconnu particulier que je recevais était la valeur de l'octet pour la première accolade ({) dans votre document.

{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }

après avoir modifié un peu le code, j'ai réussi à le faire fonctionner sans l'option unknown kind error.

package main

import (
    "encoding/binary"
    "fmt"

    "gopkg.in/mgo.v2/bson"
)

func main() {
    bsonData := `{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }`

    var record map[string]interface{}

    rec := make([]byte, len(bsonData)+6)
    binary.LittleEndian.PutUint32(rec, uint32(len(rec)))
    copy(rec[4:], bsonData)
    //Adding a new line to the front of the rec byte variable seems to do the trick
    r := []byte("\n")
    rec[4] = r[0]
    err := bson.Unmarshal(rec, &record)
    if err != nil {
        panic(err)
    }
    fmt.Println(record)
}

J'ai également trouvé cette réponse d'une grande utilité https://stackoverflow.com/a/33129119/2627768

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X