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 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.
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 |
|---|---|
| O campo não será organizado se estiver definido para o valor zero correspondente ao tipo de campo. Para evitar globalmente que o driver faça o marshaling de campos configurados com valor zero, você pode definir a opção BSON |
| Se o campo for do tipo |
| 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. |
| 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
any. O driver desordena documentos BSON desordenados em um campoanycomo um tipoD.
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
BSONOptionsdefinindo as seguintes configurações:Define o campo
UseJSONStructTagscomotrue, 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
NilSliceAsEmptycomotrue, que instrui o driver a ordenar fatiasnilGo como arrays BSON vaziasDefina o campo
OmitEmptycomotrue, que instrui o driver a omitir globalmente valores vazias do BSON empacotado, em vez de definir valores vazias comonull
Passa a instância
BSONOptionspara o método auxiliarSetBSONOptions()para especificar uma instânciaClientOptionsCria um
Clientpara aplicar o comportamento de ordenação e desordenação de BSON especificado
bsonOpts := &options.BSONOptions { UseJSONStructTags: true, NilSliceAsEmpty: true, OmitEmpty: true, } clientOpts := options.Client(). ApplyURI("<connection string>"). SetBSONOptions(bsonOpts) client, err := mongo.Connect(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:
nilse 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)
[{_id ObjectID("...")} {first_name Arthur} {street 1 Fern Way} {city Elwood City} {state PA} {age 8}]
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. Os métodos bson.Marshal() e bson.Unmarshal() exigem um parâmetro que pode ser codificado em um documento BSON, como um tipo bson.D. Um erro Write ocorrerá se você passar um tipo incorreto. Por exemplo, se você passar uma string para bson.Marshal(), ocorrerá um erro WriteString.
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)
Unmarshalled Struct: {Category:plate Quantity:6}
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. Esse tipo permite procurar elementos individuais sem desordenar todo o documento BSON . Para obter mais informações sobre como usar o tipo Raw, consulte a seção Trabalhar com dados brutos 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 BSON.
Use dados BSON brutos
O driver Go suporta trabalhar com documentos BSON brutos por meio do tipo Raw. O tipo Raw permite validar e recuperar elementos de uma fatia de bytes sem desordenar todo o documento BSON. Isso é útil nas seguintes situações:
Realizando pesquisas em campos específicos sem converter todo o documento
Reduzindo a sobrecarga de memória evitando a desordenação completa de documento
Trabalhando diretamente com dados BSON binários recebidos do banco de dados
O tipo Raw fornece métodos para validar o documento BSON e procurar elementos individuais por suas chaves. O exemplo a seguir demonstra como validar um documento BSON bruto e recuperar um campo específico dele:
collection := client.Database("sample_restaurants").Collection("restaurants") findOptions := options.FindOne() var raw bson.Raw err = collection.FindOne( context.TODO(), bson.D{{"name", "Mongo's Pizza"}}, findOptions, ).Decode(&raw) if err != nil { log.Fatalf("Failed to find document: %v", err) } // Print the document type fmt.Printf("Document type: %T\n", raw) // Access a field from the raw document name := raw.Lookup("name").StringValue() fmt.Println("Restaurant name:", name)
Document type: bson.Raw Restaurant name: Mongo's Pizza
Para saber mais sobre a família de tipos Raw, consulte a documentação da API de BSON bruto.