Agrupamentos
Nesta página
Agrupamentos estão disponíveis no MongoDB 3.4 e posterior.
Visão geral
Este guia mostra como usar agrupamentos, um conjunto de regras de classificação, para executar operações usando ordenação de strings para idiomas e localidades específicos (uma comunidade ou região que compartilha expressões idiomáticas de idioma comum).
O MongoDB classifica strings utilizando agrupamento binário por padrão. Esse método de agrupamento usa o padrão ASCII valores de caracteres para comparar e ordenar strings. Idiomas e locais têm convenções específicas de ordenação de caracteres que diferem do padrão ASCII.
Por exemplo, no francês canadense, o caractere mais acentuado à direita determina a ordem das strings quando os outros caracteres são os mesmos. Considere as seguintes palavras francesas: cote, coté, côte e côté.
O MongoDB os classifica na seguinte ordem usando o agrupamento binário padrão:
cote coté côte côté
O MongoDB os classifica na seguinte ordem usando o agrupamento francês canadense:
cote côte coté côté
Uso
Você pode especificar um agrupamento ao criar uma nova coleção ou novo índice. Você também pode especificar um agrupamento para operações e agregações CRUD .
Ao criar uma nova coleção com um agrupamento, você define o agrupamento padrão para qualquer uma das operações que suportam o agrupamento chamado nessa coleção. Você pode substituir o agrupamento de uma operação especificando uma diferente.
Observação
No momento, você não pode criar uma collection em uma collection existente. Para usar agrupamentos com uma collection existente, crie um índice com o agrupamento e especifique o mesmo agrupamento em suas operações nele.
Ao criar um índice com um agrupamento, você especifica a ordem de classificação para operações que usam esse índice. Para usar o agrupamento no índice, você deve fornecer um agrupamento correspondente na operação, e a operação deve usar o índice. Embora a maioria dos tipos de índice ofereça suporte ao agrupamento, os seguintes tipos oferecem suporte somente à comparação binária:
Parâmetros de agrupamento
O objeto de agrupamento contém os seguintes parâmetros:
collation: { locale: <string>, caseLevel: <bool>, caseFirst: <string>, strength: <int>, numericOrdering: <bool>, alternate: <string>, maxVariable: <string>, backwards: <bool> }
Você deve especificar o campo locale
no agrupamento; todos os outros campos são opcionais. Para obter uma lista completa dos locais suportados e dos valores padrão dos campos locale
, consulte Idiomas e locais suportados. Para obter descrições de cada campo, consulte a entrada de manual do Documento de agrupamento MongoDB.
Exemplos de agrupamento
Definir um agrupamento padrão em uma coleção
No exemplo a seguir, criamos uma nova coleção chamada souvenirs
e atribuímos um agrupamento padrão com a localidade "fr_CA"
. O agrupamento se aplica a todas as operações que suportam o agrupamento realizado nessa coleção.
db.createCollection("souvenirs", { collation: { locale: "fr_CA" }, });
Qualquer uma das operações que suportam agrupamentos aplicam automaticamente o agrupamento definido na coleção. A consulta abaixo pesquisa a coleção souvenirs
e aplica o agrupamento da localidade "fr_CA"
:
myColl.find({type: "photograph"});
Você pode especificar um agrupamento diferente como parâmetro em uma operação que oferece suporte a agrupamentos. A consulta a seguir especifica a localidade da Islândia "is"
e o parâmetro opcional caseFirst
com o valor "upper"
:
myColl.find({type: "photograph"}, { collation: { locale: "is", caseFirst: "upper" } } );
Atribuir um agrupamento a um Índice
No exemplo a seguir, criamos um novo índice no campo title
de uma coleção com um agrupamento definido para a localidade "en_US"
.
myColl.createIndex( { 'title' : 1 }, { 'collation' : { 'locale' : 'en_US' } });
A seguinte consulta usa o índice que criamos:
myColl.find({"year": 1980}, {"collation" : {"locale" : "en_US" }}) .sort({"title": -1});
As queries a seguir não usam o índice que criamos. A primeira query não inclui um agrupamento e a segunda contém um valor de força diferente do agrupamento no índice.
myColl.find({"year": 1980}, {"collation" : {"locale" : "en_US", "strength": 2 }}) .sort({"title": -1});
myColl.find({"year": 1980}) .sort({"title": -1});
Exemplos de query de agrupamento
As operações que leem, atualizam e excluem documentos de uma coleção podem usar agrupamentos. Esta seção inclui exemplos de uma seleção deles. Consulte o manual do MongoDB para obter uma lista completa das operações que suportam agrupamento.
Exemplo de find() e sort()
O exemplo seguinte chama find()
e sort()
em uma coleção que utiliza o agrupamento binário padrão. Usamos o agrupamento alemão definindo o valor do parâmetro locale
como "de"
.
myColl.find({ city: "New York" }, { collation: { locale: "de" } }) .sort({ name: 1 });
Exemplo de findOneAndUpdate ()
O exemplo seguinte chama a operação findOneAndUpdate()
em uma coleção que utiliza o agrupamento binário padrão. A coleção 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" }
Considere a seguinte operação do findOneAndUpdate()
nesta coleção que não especifica um agrupamento:
myColl.findOneAndUpdate( { first_name : { $lt: "Gunter" } }, { $set: { verified: true } } );
Como "Gunter" é o primeiro resultado classificado ao usar um agrupamento binário, nenhum dos documentos vem lexicalmente antes e corresponde ao operador de comparação $lt
no documento de consulta. Como resultado, a operação não atualiza nenhum documento.
Considere a mesma operação com um agrupamento especificado com a localidade configurada para de@collation=phonebook
. Essa localidade especifica a opção collation=phonebook
que contém regras para priorizar nomes próprios, identificados pela capitalização da primeira letra. A localidade e a opção de@collation=phonebook
classificam os caracteres com umlauts antes dos mesmos caracteres sem umlauts.
myColl.findOneAndUpdate( { first_name: { $lt: "Gunter" } }, { $set: { verified: true } }, { collation: { locale: "de@collation=phonebook" } }, );
Como "Günter" vem lexicalmente antes de "Gunter" usando o agrupamento de@collation=phonebook
especificado em findOneAndUpdate()
, a operação retorna o seguinte documento atualizado:
{ lastErrorObject: { updatedExisting: true, n: 1 }, value: { _id: 3, first_name: 'Günter' }, ok: 1 }
Exemplo de findOneAndDelete()
O exemplo a seguir chama a operação findOneAndDelete()
em uma coleção que usa o agrupamento binário padrão e contém os seguintes documentos:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
Neste exemplo, definimos o parâmetro de agrupamento numericOrdering
como true
para classificar strings com base em sua ordem numérica em vez de sua ordem lexical.
myColl.findOneAndDelete( { a: { $gt: "100" } }, { collation: { locale: "en", numericOrdering: true } }, );
Após executar a operação acima, a coleção contém os seguintes documentos:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" }
Ao executar a mesma operação em uma coleção original de três documentos sem agrupamento, a correspondência será feita de acordo com o valor lexicográfico das strings ("16"
, "84"
e "179"
) e excluirá o primeiro documento encontrado que corresponda aos critérios de consulta.
await myColl.findOneAndDelete({ a: { $gt: "100" } });
Como todos os documentos contêm valores lexicais no campo a
que correspondem aos critérios (maior que o valor lexical de "100"
), a operação remove o primeiro resultado. Após executar a operação acima, a coleção contém os seguintes documentos:
{ "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
Exemplo de agregação
Para usar o agrupamento com a operação agregada, passe o documento de agrupamento no campo de opções, após a array de estágios do pipeline.
O exemplo a seguir mostra um pipeline de agregação em uma coleção que usa o agrupamento binário padrão. A agregação agrupa o campo first_name
, conta o número total de resultados em cada grupo e classifica os resultados pela ordem da Agenda telefônica alemã ("de@collation=phonebook"
localidade).
Observação
Você pode especificar apenas um agrupamento em uma agregação.
myColl.aggregate( [ { $group: { "_id": "$first_name", "nameCount": { "$sum": 1 } } }, { $sort: { "_id": 1 } }, ], { collation: { locale: "de@collation=phonebook" } }, );