Menu Docs
Página inicial do Docs
/ / /
Go
/

Trabalhe com BSON

Nesta página

  • Visão geral
  • Tipos de dados
  • Marcações de estrutura
  • Opções de JSON
  • Desordenação

Neste guia, você aprenderá como o driver Go lida com conversões entre os tipos BSON e Go. O processo de conversão de um tipo Go para BSON é chamado de ordenação, enquanto o processo inverso é chamado de desordenação.

As seções a seguir explicam como o driver Go representa os dados BSON e como você pode ajustar os comportamentos padrão de ordenação e desordenação.

O MongoDB armazena documentos em uma representação binária denominada BSON que permite o processamento de dados fácil e flexível.

O driver Go oferece quatro tipos principais de trabalho com dados BSON:

  • D: Uma representação ordenada de um documento BSON (fatia)

  • M: Uma representação não ordenada de um documento BSON (mapa)

  • A: Uma representação ordenada de uma array BSON

  • E: Um único elemento dentro de um tipo D

O exemplo abaixo mostra como criar um filtro de queries utilizando o tipo bson.D para corresponder documentos em que o valor do campo quantity é maior que 100:

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

Para saber mais sobre como o driver Go lida com os dados BSON, consulte a documentação da API do pacote bson.

No Go, uma estrutura é uma collection de campos de dados com tipos de dados declarados. Você pode modificar o comportamento padrão de transferência e remoção de transferência de um campo de estrutura usando marcações de estrutura, que são partes opcionais de metadados anexadas aos campos de estrutura. O uso mais comum de marcações de estrutura é especificar o nome do campo no documento BSON que corresponde ao campo estruturado. A tabela a seguir descreve as marcações de estrutura adicionais que você pode usar no driver Go:

Marcação de estrutura
Descrição
omitempty
O campo não será ordenado se estiver definido para o valor zero correspondente ao tipo de campo.
minsize
Se o campo for do tipo int64, uint, uint32 ou uint64 e o valor do campo puder caber em um int32 assinado, o campo será serializado como um BSON int32 em vez de um BSON int64. Se o valor não couber em um int32 registrado, essa marcação será ignorada.
truncate
Se o tipo de campo for um tipo numérico não flutuante, o que BSON dobrar sem ordenação nesse campo será truncado no ponto decimal.
inline
Se o tipo de campo for um campo de estrutura ou mapa, o campo será achatado ao ser ordenado e não será achatado ao ser desordenado.

Se você não especificar marcações de estrutura, o driver Go organizará as estruturas usando as seguintes regras:

  1. O driver apenas ordena e desordena os campos exportados.

  2. O driver gera uma chave BSON utilizando a letra minúscula do campo de estrutura correspondente.

  3. O driver ordena campos de estrutura integrados como subdocumentos. Cada chave é a letra minúscula do tipo de campo.

  4. O driver ordena um campo de ponteiro como o tipo subjacente se o ponteiro for diferente de nulo. Se o ponteiro for nulo, o driver o ordenará como um valor nulo BSON.

  5. Ao desordenar, o driver Go segue esses mapeamentos tipo D/M para campos do tipo interface{}. O driver desordena documentos BSON desordenados em um campo interface{} como um tipo D.

O exemplo a seguir demonstra como o driver Go transforma uma estrutura em uma struct com várias tags de estrutura:

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)

A representação BSON correspondente tem a seguinte aparência:

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

Neste exemplo, as tags estruturadas fazem o driver:

  • Defina nomes de campos BSON personalizados, como first_name

  • Omitir o campo LastName vazio

  • Nivelar a estrutura aninhada e levar todos os campos até o nível superior

O exemplo a seguir demonstra como o driver Go transforma uma estrutura sem nenhuma tag de estrutura:

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)

A representação BSON correspondente tem a seguinte aparência:

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

Sem marcações estruturadas, o driver:

  • Define as letras minúsculas dos campos estruturados como os nomes do campo BSON

  • Inclui um campo lastname vazio

  • Armazena o campo Address como um valor aninhado

Você pode especificar opções BSON para ajustar o comportamento de ordenação e desordenação de sua instância Client. Para definir opções de BSON no seu Client, crie e configure uma instância do BSONOptions.

Este exemplo executa as seguintes ações:

  • Cria uma instância BSONOptions definindo as seguintes configurações:

    • Define o campo UseJSONStructTags como true, que instrui o driver a usar a marcação "json" de estrutura se uma marcação "bson" de estrutura não for especificada

    • Define o campo NilSliceAsEmpty como true, que instrui o driver a ordenar fatias nil Go como arrays BSON vazias

  • Passa a instância BSONOptions para o método auxiliar SetBSONOptions() para especificar uma instância ClientOptions

  • Cria um Client para aplicar o comportamento de ordenação e desordenação de BSON especificado

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

Dica

Para saber mais sobre o tipo BSONOptions, consulte a documentação da API de BSONOptions. Para um exemplo que especifica uma instância BSONOptions e cria um cliente com estas opções, consulte o exemplo Connect() BSONOptions.

Você pode desordenar documentos BSON utilizando o método Decode() no resultado do método FindOne ou qualquer instância *mongo.Cursor.

O método Decode() retorna um tipo de error que contém um dos seguintes valores:

  • nil se um documento corresponder à sua query e não houver erros ao recuperar e desordenar o documento.

  • Se o driver recuperou o documento, mas não pôde desordenar o resultado, o método Decode() retorna o erro de desordenação.

  • Se houver um erro ao recuperar seu documento durante a execução do método FindOne(), o erro se propagará para o método Decode() e o método Decode() retornará o erro.

Quando utilizado no tipo SingleResult retornado pelo método FindOne(), o Decode() também pode retornar o erro ErrNoDocuments se nenhum documento corresponder ao filtro de query.

O exemplo seguinte demonstra como você pode utilizar o método Decode() para desordenar e ler o resultado de uma operação simples do 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)

O tipo Cursor também utiliza o método All(), que une todos os documentos armazenados no cursor em uma array ao mesmo tempo.

O pacote bson inclui uma família de métodos Marshal() e Unmarshal() que funcionam com dados codificados por BSONs do tipo []byte.

O código a seguir demonstra como você pode desordenar o BSON de volta para uma estrutura definida pelo usuário usando métodos do pacote 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)

Observação

Você pode usar o tipo Raw para recuperar elementos de uma fatia de bytes de documento BSON sem desordená-lo para um tipo Go. Isso pode ser útil se você precisar procurar elementos individuais sem desordenar todo o documento BSON.

Para saber mais sobre os métodos de ordenação e desordenação usados com o tipo Cursor, consulte a documentação da API do cursor

Para saber mais sobre os métodos de ordenação e desordenação no pacote bson, consulte a documentação da API do bson

Voltar

Mecanismos de autenticação empresarial