Visão geral
Neste guia, você pode aprender como usar o driver Go para configurar as operações de leitura e escrita.
Configurações de leitura e escrita
Você pode controlar como o driver direciona as operações de leitura definindo uma preferência de leitura. Você também pode controlar como o driver lida com a consistência e a durabilidade dos dados definindo uma preocupação de leitura ou preocupação de gravação. As write concerns especificam o nível de durabilidade necessário para os dados ao realizar operações de leitura, e as write concerns especificam como o driver aguarda a confirmação das operações de gravação em um conjunto de réplicas.
É possível definir as opções de preocupação de gravação, preocupação de leitura e preferência de leitura nos seguintes níveis:
Nível do cliente, que define o padrão para todas as execuções de operações, a menos que sejam substituídas
Nível da sessão
Nível de transação
Nível do banco de dados
Nível de collection
A lista anterior também indica a ordem crescente de precedência das configurações de opção. Por exemplo, se você definir uma preocupação de leitura para uma transação, ela substituirá uma preocupação de leitura definida para o cliente.
Escreva preocupação
Uma preocupação de gravação descreve o número de membros portadores de dados em um conjunto de réplicas que devem confirmar uma operação de escrita, como uma inserção ou atualização, antes que a operação retorne como bem-sucedida. Por padrão, a operação de gravação é bem-sucedida se somente o membro primário do conjunto de réplicas reconhecê-la.
Opções
O MongoDB Go Driver fornece o pacote writeconcern
, que permite especificar a preocupação de gravação para um conjunto de réplicas. Defina a preocupação de gravação passando uma instância do tipo WriteConcern
para o método SetWriteConcern()
. O tipo WriteConcern
fornece os seguintes métodos para selecionar especificações comuns de preocupação de gravação :
Método | Descrição |
---|---|
| The client requests acknowledgement that write operations propagate to
tagged members of a mongod instance. For more
information, see the Write Concern specification.Parameter: tag (string) |
| The client requests acknowledgement that the replica set has
written the changes to the on-disk journal. For more information, see the
Write Concern specification. Parameter: none |
| The client requests acknowledgement that write operations propagate to the
majority of data-bearing voting members. For more information, see the
Write Concern specification. Parameter: none |
| The client requests requests no acknowledgment of write
operations. For more information, see the
Write Concern specification for w: 0. Parameter: none |
| The client requests acknowledgement that the replica set has
written the changes to memory on one node, such as the standalone mongod or
the primary in a replica set. For more
information, see the Write Concern specification for w: 1. Parameter: none |
Dica
Tempo limite de write concern
Você não pode definir um tempo limite em uma instância WriteConcern
. Em vez disso, defina o tempo limite no nível de operação usando o método WithTimeout()
ao criar um contexto. Para saber mais, consulte Limitar o tempo de execução do servidor no guia Opções de conexão.
Se você precisar de uma preocupação de gravação mais especializada, você pode definir um literal de estrutura WriteConcern
personalizado. Você pode definir os seguintes campos em uma estrutura WriteConcern
:
Campo | Descrição |
---|---|
| Specifies the number of mongod instances or tagged members
that write operations must propagate to for acknowledgement. Common values include
1 , 0 , and "majority" .Type: string or int |
| Specifies whether the replica set must write the changes to the on-disk
journal for acknowledgement. Type: bool |
Dica
Como alternativa, você pode especificar uma preocupação de gravação em sua string de conexão. Consulte a entrada manual do servidor sobre Opções de preocupação de gravação para obter mais informações.
Exemplo
O código a seguir mostra como você pode especificar diferentes write concerns no nível do cliente e da coleção. A preocupação de gravação no nível do cliente solicita confirmação de dois membros do conjunto de réplicas e define o registro no diário como false
. A preocupação de gravação no nível da collection solicita confirmação da maioria dos nós do conjunto de réplicas.
uri := "mongodb://<hostname>:<port>" journal := false cliWC := &writeconcern.WriteConcern{ W: 2, Journal: &journal, } clOpts := options.Client().ApplyURI(uri).SetWriteConcern(cliWC) client, err := mongo.Connect(clOpts) ... collWC := writeconcern.Majority() collOpts := options.Collection().SetWriteConcern(collWC) coll := client.Database("db").Collection("myColl", collOpts)
Preocupação de leitura
A opção de preocupação de leitura possibilita que você determine quais dados o cliente retorna de uma query. O nível de preocupação de leitura padrão é "local", o que significa que o cliente retorna os dados mais recentes da instância, sem garantia de que os dados tenham sido gravados na maioria dos membros do conjunto de réplicas.
Opções
O MongoDB Go Driver fornece o pacote readconcern
, que permite especificar a preocupação de leitura para um conjunto de réplicas. Defina a preocupação de leitura passando uma instância de um tipo ReadConcern
para o método SetReadConcern()
. O tipo ReadConcern
tem os seguintes métodos para especificar a preocupação de leitura:
Método | Descrição |
---|---|
| A query retorna dados da instância sem garantia de que os dados tenham sido gravados na maioria dos membros do conjunto de réplicas. Para obter mais informações, consulte a especificação Read Concern. |
| A query retorna dados que refletem todas as escritas bem-sucedidas emitidas com uma preocupação de gravação de |
| A query retorna os dados mais recentes da instância. Para obter mais informações, consulte a especificação Read Concern. |
| A query retorna os dados mais recentes da instância reconhecidos como tendo sido gravados para a maioria dos membros no conjunto de réplicas. Para obter mais informações, consulte a especificação Read Concern. |
| A query retorna uma cópia completa dos dados em uma instância do |
Exemplo
O código a seguir mostra como você pode especificar uma read concern de "maioria". O código então seleciona um Collection
com esta opção.
rc := readconcern.Majority() opts := options.Collection().SetReadConcern(rc) database := client.Database("db") coll := database.Collection("myCollection", opts)
readPreference
A opção de preferência de leitura especifica como o cliente MongoDB roteia as operações de leitura para os membros de um conjunto de réplica. Por padrão, um aplicativo direciona suas operações de leitura para o membro primário em um conjunto de réplicas.
A read preference consiste no modo de read preference e, opcionalmente, em uma lista de conjunto de tags, na opção maxStalenessSeconds e na opção de leituras distribuídas.
Opções
O MongoDB Go Driver fornece o pacote readpref
, que permite especificar a preferência de leitura para um conjunto de réplicas. Defina a preferência de leitura passando uma instância do tipo ReadPref
para o método SetReadPreference()
. O tipo ReadPref
tem os seguintes métodos para especificar a preferência de leitura:
Método | Descrição |
---|---|
| O cliente lê a partir de um nó aleatório qualificado do conjunto de réplicas, com base em um limite de latência especificado. Para obter mais informações, consulte a entrada manual do servidor de preferência de leitura. |
| O cliente lê a partir do nó primário do conjunto de réplicas atual. Para obter mais informações, consulte a entrada manual do servidor MongoDB de preferência de leitura. |
| O cliente lê a partir do nó primário se estiver disponível. Se o primário não estiver disponível, as operações serão lidas dos nós secundários. Para obter mais informações, consulte a entrada manual do servidor de preferência de leitura. |
| O cliente lê a partir dos nós secundários do conjunto de réplicas. Para obter mais informações, consulte a entrada manual do servidor MongoDB de preferência de leitura. |
| O cliente lê a partir dos nós secundários se um ou mais estiverem disponíveis. Se os secundários não estiverem disponíveis, as operações serão lidas do nó primário. Para obter mais informações, consulte a entrada manual do servidor de preferência de leitura. |
Dica
Como alternativa, você pode especificar uma preferência de leitura em sua string de conexão. Consulte a entrada manual do servidor em Opções de preferência de leitura para obter mais informações.
Exemplo
O código a seguir mostra como você pode especificar uma preferência de leitura para ler dos nós secundários. O código então seleciona um Database
com essa opção.
rp := readpref.Secondary() opts := options.Database().SetReadPreference(rp) database := client.Database("db", opts)
Leituras e gravações retráteis
O driver Go tenta automaticamente determinadas operações de leitura e gravação uma única vez se elas falharem devido a um erro de rede ou servidor .
Você pode desabilitar explicitamente as leituras ou gravações repetíveis definindo a opção RetryReads
ou RetryWrites
como False
ao criar um novo cliente usando a estrutura options.Client
.
O exemplo a seguir desabilita leituras e gravações repetíveis para um cliente usando as funções de setter ClientOptions
:
// Defines the client options clientOps := options.Client(). ApplyURI(uri). SetRetryWrites(false). SetRetryReads(false) // Creates a new client using the specified options client, err := mongo.Connect(clientOps) if err != nil { panic(err) }
Para saber mais sobre as operações de leitura repetível com suporte, consulte Leituras repetíveis no manual do MongoDB Server . Para saber mais sobre as operações de gravações repetíveis com suporte, consulte Retryable writes no manual do MongoDB Server .
Agrupamentos
Você pode especificar um agrupamento para modificar o comportamento das operações de leitura e gravação. Um agrupamento é um conjunto de regras específicas do idioma para comparação de cadeias de caracteres, como para letras maiúsculas e minúsculas e acentos.
Por padrão, o MongoDB classifica strings utilizando agrupamento binário. Esse agrupamento padrão usa o padrão ASCII de valores de caracteres para comparar e ordenar strings. Idiomas e locais possuem convenções específicas de ordenação de caracteres que diferem do padrão ASCII, e você pode optar por aplicar um conjunto diferente de regras de agrupamento à sua operação.
Você pode especificar um agrupamento nos seguintes níveis:
Collection: define o agrupamento padrão para operações na collection. Você não pode definir uma coleta para uma coleta existente.
Índice: define o agrupamento para operações que usam o índice.
Operação: define o agrupamento da operação e substitui quaisquer agrupamentos herdados.
Especificar um agrupamento
Para especificar um agrupamento, crie um objeto Collation
. Você deve definir o campo Locale
do objeto Collation
, mas todos os outros campos são opcionais. Por exemplo, o seguinte exemplo de código especifica um objeto Collation
com o agrupamento de locale "en_US"
:
myCollation := &options.Collation{Locale: "en_US"}
Para ver uma lista completa dos Collation
campos de objeto, acesse a documentação da API de agrupamento. Para ver todas as localidades suportadas e os valores padrão para os campos Locale
, visite Idiomas e localidades compatíveis.
Definir um agrupamento em uma collection ou visualização
Você pode aplicar um agrupamento ao criar uma nova coleção ou visualização. Isso define o agrupamento padrão para quaisquer operações chamadas nessa coleção ou visualização. Defina um agrupamento por meio de um objeto CreateCollectionOptions
ou CreateViewOptions
. Em seguida, chame o método CreateCollection()
ou CreateView()
com seu objeto de opções como argumento.
Criar um Exemplo de Coleção
O exemplo a seguir cria uma nova coleção chamada books
e especifica um agrupamento padrão com a localidade "fr"
. O campo de agrupamento Strength
tem um valor de 1
para ignorar diferenças nos acentos das letras.
myCollation := &options.Collation{Locale: "fr", Strength: 1} opts := options.CreateCollection().SetCollation(myCollation) err := db.CreateCollection(context.TODO(), "books", opts) if err != nil { panic(err) }
Usar o exemplo de agrupamento padrão
Se você chamar uma operação que usa um agrupamento na collection books
, a operação usará o agrupamento padrão especificado no Exemplo de criar uma coleção.
Suponha que a coleção books
contenha os seguintes documentos:
{"name" : "Emma", "length" : "474"} {"name" : "Les Misérables", "length": "1462"} {"name" : "Infinite Jest", "length" : "1104"} {"name" : "Cryptonomicon", "length" : "918"} {"name" : "Ça", "length" : "1138"}
Observação
Para saber como inserir documentos, consulte Inserir documentos.
O exemplo a seguir usa o método Find()
para retornar todos os documentos com um valor name
que precede alfabeticamente "Infinite Jest"
:
filter := bson.D{{"name", bson.D{{"$lt", "Infinite Jest"}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"name":"Emma","length":"474"} {"name":"Cryptonomicon","length":"918"} {"name":"Ça","length":"1138"}
Se o código não especificar um agrupamento books
padrão, o método Find()
seguirá as regras de agrupamento binário padrão para determinar os valores name
que precedem "Infinite Jest"
. Essas regras colocam as palavras que começam com "ç" após aquelas que começam com "I". O resultado se assemelha ao seguinte:
{"name":"Emma","length":"474"} {"name":"Cryptonomicon","length":"918"}
Para saber mais sobre o método Find()
, consulte Localizar documentos.
Definir um agrupamento em um índice
Você pode aplicar um agrupamento ao criar um novo índice em uma coleção. O índice armazena uma representação ordenada dos documentos na coleção, para que sua instância do MongoDB não execute a ordem para operações de classificação na memória.
Para usar o índice em uma operação, sua operação deve usar o mesmo agrupamento que o especificado no índice. Além disso, certifique-se de que a operação esteja coberta pelo índice que contém o agrupamento. Defina um agrupamento por meio de um objeto IndexOptions
e passe esse objeto como argumento para o método CreateOne()
.
Exemplo
Depois de criar a coleção books
e aplicar um agrupamento padrão, como mostrado na seção Criar um Exemplo de Coleção , você não poderá alterar o agrupamento padrão da coleção. No entanto, você pode criar um índice para a coleção com um agrupamento diferente.
O exemplo a seguir usa o método CreateOne()
para criar um índice ascendente no campo name
e especifica um novo agrupamento com um locale "en_US"
:
myCollation := &options.Collation{Locale: "en_US"} opts := options.Index().SetCollation(myCollation) indexModel := mongo.IndexModel{ Keys: bson.D{{"name", 1}}, Options: opts, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Name of Index Created: name_1
Definir um agrupamento em uma operação
As operações que leem, atualizam e excluem documentos de uma coleção podem usar agrupamentos. A aplicação de um agrupamento a uma operação substitui qualquer agrupamento padrão definido anteriormente para uma coleção.
Se você aplicar um novo agrupamento a uma operação que difere do agrupamento de um índice, não poderá usar esse índice. Como resultado, a operação pode não ter um desempenho tão bom quanto uma operação coberta por um índice. Para obter mais informações sobre as desvantagens das operações de classificação não cobertas por um índice, consulte Usando índices para classificar resultados de queries. Consulte o manual do MongoDB para obter uma lista de operações que suportam agrupamento.
Exemplo
Você pode usar as operações que suportam agrupamento para atualizar e consultar documentos na collection books
.
O exemplo a seguir usa o método Find()
para retornar documentos nos quais o valor length
é maior que "1000"
. O campo de agrupamento NumericOrdering
tem um valor de true
para garantir que os valores sejam classificados em ordem numérica em vez de alfabética:
filter := bson.D{{"length", bson.D{{"$gt", "1000"}}}} myCollation := &options.Collation{Locale: "en_US", NumericOrdering: true} opts := options.Find().SetCollation(myCollation) cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"name":"Les Misérables","length":"1462"} {"name":"Infinite Jest","length":"1104"} {"name":"Ça","length":"1138"}
Se o código não especificar um agrupamento com um campo NumericOrdering
definido como true
, a mesma operação Find()
comparará os valores length
como strings. Nesse caso, a saída se assemelha ao seguinte:
{"name":"Emma","length":"474"} {"name":"Les Misérables","length":"1462"} {""name":"Infinite Jest","length":"1104"} {"name":"Cryptonomicon","length":"918"} {"name":"Ça","length":"1138"}
Informações adicionais
Para saber mais sobre o método Find()
, consulte o guia Localizar documentos .
Para saber mais sobre os conceitos discutidos neste guia, visite as seguintes páginas do manual:
Documentação da API
Para saber mais sobre os métodos discutidos neste guia, consulte a seguinte documentação da API: