Agrupamentos
Nesta página
Visão geral
Novidade na versão 3.4.
Agrupamentos são conjuntos de regras sobre como comparar strings, normalmente em uma linguagem natural específica.
Por exemplo, no francês canadense, o último acento em uma determinada palavra determina a ordem de classificação.
Considere as seguintes palavras francesas:
cote < coté < côte < côté
A ordem de classificação usando o agrupamento francês canadense resultaria no seguinte:
cote < côte < coté < côté
Se o agrupamento não for especificado, o MongoDB usará a comparação binária simples para strings. Dessa forma, a ordem de classificação das palavras seria:
cote < coté < côte < côté
Uso
Você pode especificar um agrupamento padrão para collection e índices quando eles são criados ou especificar um agrupamento para operações e agregações CRUD. Para operações que suportam agrupamento, o MongoDB usa o agrupamento padrão da coleção, a menos que a operação especifique um agrupamento diferente.
Parâmetros de agrupamento
'collation' => { 'locale' => <string>, 'caseLevel' => <bool>, 'caseFirst' => <string>, 'strength' => <int>, 'numericOrdering' => <bool>, 'alternate' => <string>, 'maxVariable' => <string>, 'normalization' => <bool>, 'backwards' => <bool> }
O único parâmetro necessário é locale
, que o servidor analisa como um ID de localidade no formato ICU . Por exemplo, defina locale
como en_US
para representar o inglês dos EUA ou fr_CA
para representar o francês canadense.
Para obter uma descrição completa dos parâmetros disponíveis, consulte a entrada manual do MongoDB.
Atribuir um agrupamento padrão a uma collection
O exemplo a seguir cria uma nova coleção chamada contacts
no banco de dados test
e atribui um agrupamento padrão com a localidade fr_CA
. Especificar um agrupamento ao criar a collection garante que todas as operações envolvendo uma query executada na collection contacts
usem o agrupamento fr_CA
, a menos que a query especifique outro agrupamento. Todos os índices na nova collection também herdam o agrupamento padrão, a menos que o comando de criação especifique outro agrupamento.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") client[:contacts, { "collation" => { "locale" => "fr_CA" } } ].create
Atribuir um agrupamento a um Índice
Para especificar um agrupamento para um índice, utilize a opção collation
ao criar o índice.
O exemplo a seguir cria um índice no campo name
da collection address_book
, com o parâmetro unique
habilitado e um agrupamento padrão com locale
definido como en_US
.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") client[:address_book].indexes.create_one( { "first_name" => 1 }, "unique" => true, "collation" => { "locale" => "en_US" } )
Para usar esse índice, certifique-se de que sua query também especifique o mesmo agrupamento. A seguinte query utiliza o índice acima:
client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US" })
A query a seguir NÃO usa o índice. A primeira query não usa agrupamento e a segunda usa um agrupamento com um valor strength
diferente do agrupamento no índice.
client[:address_book].find({"first_name" : "Adam" }) client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US", "strength" => 2 })
Operações que suportam agrupamento
Todos os métodos de leitura, atualização e exclusão suportam agrupamento. Alguns exemplos estão listados abaixo.
find()
e a sort()
Query individuais podem especificar um agrupamento a ser usado ao combinar e classificar resultados. A seguinte operação de query e classificação utiliza um agrupamento alemão com o parâmetro locale
configurado para de
.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") docs = client[:contacts].find({ "city" => "New York" }, { "collation" => { "locale" => "de" } }).sort( "name" => 1 )
find_one_and_update()
Uma coleção chamada names
contém os seguintes documentos:
{ "_id" : 1, "first_name" : "Hans" } { "_id" : 2, "first_name" : "Gunter" } { "_id" : 3, "first_name" : "Günter" } { "_id" : 4, "first_name" : "Jürgen" }
A seguinte operação do find_one_and_update
na collection não especifica um agrupamento.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") doc = client[:names].find_one_and_update( {"first_name" => { "$lt" => "Gunter" }}, { "$set" => { "verified" => true } })
Como Gunter
é lexicalmente o primeiro na collection, a operação acima não retorna resultados e não atualiza documento.
Consider the same find_one_and_update
operation but with the collation specified. A localidade está definida para de@collation=phonebook
.
Observação
Algumas localidades têm uma opção collation=phonebook
disponível para uso com idiomas que classificam os nomes próprios de forma diferente de outras palavras. De acordo com o agrupamento de@collation=phonebook
, os caracteres com umlauts vêm antes dos mesmos caracteres sem umlauts.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") doc = client[:names].find_one_and_update( { "first_name" => { "$lt" => "Gunter" } }, { "$set" => { "verified" => true } }, { "collation" => { "locale" => "de@collation=phonebook" }, :return_document => :after } )
A operação retorna o seguinte documento atualizado:
{ "_id" => 3, "first_name" => "Günter", "verified" => true }
find_one_and_delete()
Defina o parâmetro de agrupamento numericOrdering
como true
para comparar a string numérica por seus valores numéricos.
A collection numbers
contém os seguintes documento:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
O exemplo a seguir corresponde ao primeiro documento no qual o campo a
tem um valor numérico maior que 100 e o exclui.
docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } }, { "collation" => { "locale" => "en", "numericOrdering" => true } })
Após a operação acima, os seguintes documento permanecem na collection:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" }
Se você executar a mesma operação sem agrupamento, o servidor excluirá o primeiro documento encontrado no qual o valor lexical de a
é maior que "100"
.
numbers = client[:numbers] docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } })
Após a operação acima, o documento no qual a
era igual a "16"
foi excluído e os seguintes documento permanecem na collection:
{ "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
delete_many()
Você pode usar agrupamentos com todas as várias operações em massa que existem no driver Ruby.
A collection recipes
contém os seguintes documento:
{ "_id" : 1, "dish" : "veggie empanadas", "cuisine" : "Spanish" } { "_id" : 2, "dish" : "beef bourgignon", "cuisine" : "French" } { "_id" : 3, "dish" : "chicken molé", "cuisine" : "Mexican" } { "_id" : 4, "dish" : "chicken paillard", "cuisine" : "french" } { "_id" : 5, "dish" : "pozole verde", "cuisine" : "Mexican" }
Definir o parâmetro strength
do documento de agrupamento para 1
ou 2
faz com que o servidor desconsidere maiúsculas e minúsculas no filtro de query. O exemplo a seguir usa um filtro de query que diferencia maiúsculas de minúsculas para excluir todos os registros em que o campo cuisine
corresponde a French
.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") recipes = client[:recipes] docs = recipes.delete_many({ "cuisine" => "French" }, "collation" => { "locale" => "en_US", "strength" => 1 })
Após a execução da operação acima, os documentos com valores _id
de 2
e 4
são excluídos da collection.
Agregação
Para usar o agrupamento com uma operação de agregação, especifique um agrupamento nas opções de agregação.
O exemplo de aggregation seguinte utiliza uma collection denominada names
e agrupa o campo first_name
, conta o número total de resultados em cada grupo e classifica os resultados por ordem da Agenda telefônica alemã.
aggregation = names.aggregate( [ { "$group" => { "_id" => "$first_name", "name_count" => { "$sum" => 1 } } }, { "$sort" => { "_id" => 1 } }, ], { "collation" => { "locale" => "de@collation=phonebook" } } ) aggregation.each do |doc| #=> Yields a BSON::Document. end