Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Trabaje con BSON

En esta guía, puedes aprender cómo el driver de Go maneja las conversiones entre tipos BSON y tipos de Go. El proceso de convertir un tipo de Go a BSON se denomina marshallización, mientras que el proceso inverso se denomina unmarshallización.

Las siguientes secciones explican cómo el controlador Go representa los datos BSON y cómo puedes ajustar los comportamientos de serialización y deserialización por defecto.

MongoDB almacena documentos en una representación binaria llamada BSON que permite un procesamiento de datos sencillo y flexible.

El driver de Go proporciona cuatro tipos principales para trabajar con datos BSON:

  • D:: Una representación ordenada de un documento BSON (fracción)

  • MUna representación no ordenada de un documento BSON (mapa)

  • AUna representación ordenada de un arreglo BSON

  • E: Un único elemento dentro de un tipo D

El siguiente ejemplo demuestra cómo construir un filtro de query utilizando el tipo bson.D para encontrar documentos en los que el valor del campo quantity sea mayor que 100:

filter := bson.D{{"quantity", bson.D{{"$gt", 100}}}}

Para obtener más información sobre cómo el driver de Go gestiona datos BSON, consulta la documentación API del paquete bson.

En Go, una estructura es una colección de campos de datos con tipos de datos declarados. Puedes modificar el comportamiento predeterminado de serialización y deserialización de un campo de estructura utilizando etiquetas de estructura, que son piezas opcionales de metadatos adjuntas a los campos de la estructura. El uso más común de las etiquetas de estructura es especificar el nombre del campo en el documento BSON que corresponde al campo de la estructura. La siguiente tabla describe las etiquetas de estructura adicionales que puedes utilizar en el driver de Go:

Etiqueta de Struct
Descripción

omitempty

El campo no será agrupado si se establece en el valor cero correspondiente al tipo de campo.

minsize

Si el campo es de tipo int64, uint, uint32 o uint64, y el valor del campo puede ajustarse a un int32 firmado, el campo se serializará como un BSON int32 en vez de un BSON int64. Si el valor no puede ajustarse a un int32 con signo, esta etiqueta se ignora.

truncate

Si el tipo de campo es un tipo numérico que no sea de punto flotante, los BSON dobles no asignados a ese campo se truncarán en el punto decimal.

inline

Si el tipo de campo es un campo struct o map, el campo se aplanará al realizar el marshalling y se des-aplanará al realizar el unmarshalling.

Si no especificas etiquetas de estructura, el controlador de Go serializa las estructuras usando las siguientes reglas:

  1. El controlador solo convierte a formato de intercambio y deshace la conversión de campos exportados.

  2. El driver genera una clave BSON utilizando el campo de estructura correspondiente en minúsculas.

  3. El driver ordena los campos de la estructura embebida como subdocumentos. Cada clave es la versión en minúsculas del tipo de campo.

  4. El controlador agrupa un campo de puntero como el tipo subyacente si el puntero no es nulo. Si el puntero es nulo, el controlador lo serializa como un valor nulo de BSON.

  5. Al deserializar, el controlador de Go sigue estos mapeos de tipos D/M para campos de tipo interface{}. El controlador deserializa documentos BSON deserializados en un campo interface{} como un tipo D.

El siguiente ejemplo demuestra cómo el controlador de Go serializa una estructura con varias etiquetas de estructura:

type Address struct {
Street string
City string
State string
}
type Student struct {
FirstName string `bson:"first_name,omitempty"`
LastName string `bson:"last_name,omitempty"`
Address Address `bson:"inline"`
Age int
}
coll := client.Database("db").Collection("students")
address1 := Address{ "1 Lakewood Way", "Elwood City", "PA" }
student1 := Student{ FirstName : "Arthur", Address : address1, Age : 8}
_, err = coll.InsertOne(context.TODO(), student1)

La representación BSON correspondiente se ve así:

{
"_id" : ObjectId("..."),
"first_name" : "Arthur",
"street" : "1 Lakewood Way",
"city" : "Elwood City",
"state" : "PA",
"age" : 8
}

En este ejemplo, las etiquetas de estructuras hacen que el controlador:

  • Define nombres de campo BSON personalizados como first_name

  • Omitir el campo vacío LastName

  • Aplana la estructura anidada y lleva todos los campos al nivel superior

En el siguiente ejemplo se demuestra cómo el driver Go codifica una estructura sin ninguna etiqueta de estructura:

type Address struct {
Street string
City string
State string
}
type Student struct {
FirstName string
LastName string
Address Address
Age int
}
coll := client.Database("db").Collection("students")
address1 := Address{ "1 Lakewood Way", "Elwood City", "PA" }
student1 := Student{ FirstName : "Arthur", Address : address1, Age : 8}
_, err = coll.InsertOne(context.TODO(), student1)

La representación BSON correspondiente se ve así:

{
"_id" : ObjectId("..."),
"firstname" : "Arthur",
"lastname" : "",
"address": {
"street" : "1 Lakewood Way",
"city" : "Elwood City",
"state" : "PA"
},
"age" : 8
}

Sin etiquetas estructurales, el controlador:

  • Configura las letras minúsculas de los campos de la estructura como nombres de campo BSON

  • Incluye un campo lastname vacío

  • Almacena el campo Address como un valor anidado

Se pueden especificar opciones BSON para ajustar el comportamiento de marshalling y unmarshalling de la instancia de Client. Para configurar opciones BSON en Client, crear y configurar una instancia de BSONOptions.

Este ejemplo realiza las siguientes acciones:

  • Crea una instancia de BSONOptions configurando los siguientes ajustes:

    • Establece el campo UseJSONStructTags en true, lo que indica al controlador que use la etiqueta de struct "json" si no se especifica una etiqueta de struct "bson"

    • Establece el campo NilSliceAsEmpty en true, lo que instruye al controlador a agrupar nil slices de Go como arreglos de BSON vacíos

  • Pasa la instancia BSONOptions al método asistente SetBSONOptions() para especificar una instancia ClientOptions

  • Crea un Client para aplicar el comportamiento especificado de empaquetado y desempaquetado BSON

bsonOpts := &options.BSONOptions {
UseJSONStructTags: true,
NilSliceAsEmpty: true,
}
clientOpts := options.Client().
ApplyURI("<connection string>").
SetBSONOptions(bsonOpts)
client, err := mongo.Connect(context.TODO(), clientOpts)

Tip

Para obtener más información sobre el tipo BSONOptions, consulte la documentación de la API BSONOptions. Para un ejemplo que especifique una instancia BSONOptions y cree un cliente con estas opciones, consulte el Ejemplo de opciones BSON para Connect().

Puedes deserializar documentos BSON utilizando el método Decode() en el resultado del método FindOne o en cualquier instancia *mongo.Cursor.

El método Decode() devuelve un tipo error que contiene uno de los siguientes valores:

  • nil si un documento coincidía con tu query y no hubo errores al recuperar y deserializar el documento.

  • Si el controlador recuperó su documento pero no pudo deserializar su resultado, el método Decode() devuelve el error de deserialización.

  • Si hubo un error al recuperar tu documento durante la ejecución del método FindOne(), el error se propaga al método Decode() y el método Decode() devuelve el error.

Cuando se usa en el tipo SingleResult devuelto por el método FindOne(), Decode() también puede devolver el error ErrNoDocuments si ningún documento coincide con el filtro de query.

El siguiente ejemplo demuestra cómo puedes utilizar el método Decode() para desmarcar y leer el resultado de una operación sencilla de FindOne():

coll := client.Database("db").Collection("students")
filter := bson.D{{"age", 8}}
var result bson.D
err := coll.FindOne(context.TODO(), filter).Decode(&result)
fmt.Println(result)
[{_id ObjectID("...")} {first_name Arthur} {street 1 Fern Way} {city Elwood City} {state PA} {age 8}]

El tipo Cursor también utiliza el método All(), que deserializa todos los documentos almacenados en el cursor en un arreglo al mismo tiempo.

El paquete bson incluye una familia de métodos Marshal() y Unmarshal() que trabajan con datos codificados en BSON de tipo []byte.

El siguiente código muestra cómo puedes desensamblar BSON de nuevo en una estructura definida por el usuario usando métodos del paquete bson:

type Item struct {
Category string
Quantity int32
}
doc, err := bson.Marshal(bson.D{{"category", "plate"}, {"quantity", 6}})
var test Item
err = bson.Unmarshal(doc, &test)
fmt.Printf("Unmarshalled Struct:\n%+v\n", test)
Unmarshalled Struct:
{Category:plate Quantity:6}

Nota

Puede utilizar el tipo Raw para recuperar elementos de un segmento de bytes de un documento BSON sin deserializarlo en un tipo de Go. Con este tipo, puedes buscar elementos individuales sin tener que desempaquetar todo el documento BSON.

Para aprender más información sobre los métodos de marshalling y unmarshalling utilizados con el tipo Cursor, consulta la documentación de la API de Cursor

Para obtener más información sobre los métodos de marshalling y unmarshalling en el paquete bson, consulta la documentación de la API de BSON

Volver

autenticación de empresa

En esta página