Trabalhe com BSON
Visão geral
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.
Tipos de dados
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 BSONE
: Um único elemento dentro de um tipo D
O exemplo abaixo mostra como criar um filtro de consulta 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.
Marcações de estrutura
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:
O driver apenas ordena e desordena os campos exportados.
O driver gera uma chave BSON utilizando a letra minúscula do campo de estrutura correspondente.
O driver ordena campos de estrutura integrados como subdocumentos. Cada chave é a letra minúscula do tipo de campo.
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.
Ao desordenar, o driver Go segue esses mapeamentos tipo D/M para campos do tipo
interface{}
. O driver desordena documentos BSON desordenados em um campointerface{}
como um tipoD
.
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
vazioNivelar 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
vazioArmazena o campo
Address
como um valor aninhado
Opções de JSON
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
comotrue
, que instrui o driver a usar a marcação"json"
de estrutura se uma marcação"bson"
de estrutura não for especificadaDefine o campo
NilSliceAsEmpty
comotrue
, que instrui o driver a ordenar fatiasnil
Go como arrays BSON vazias
Passa a instância
BSONOptions
para o método auxiliarSetBSONOptions()
para especificar uma instânciaClientOptions
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.
Desordenação
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étodoDecode()
e o métodoDecode()
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