Overview
Las intercalaciones son conjuntos de reglas para comparar cadenas de texto, generalmente en un lenguaje natural particular.
Por ejemplo, en el francés canadiense, el último acento en una palabra dada determina el orden de ordenación.
Considera las siguientes palabras en francés:
cote < coté < côte < côté
El orden de clasificación usando la intercalación Francés Canadiense resultaría en lo siguiente:
cote < côte < coté < côté
Si no se especifica una intercalación, MongoDB utiliza la comparación binaria simple para las cadenas. Así, el orden de clasificación de las palabras sería:
cote < coté < côte < côté
Uso
Puedes especificar una intercalación por defecto para colecciones e índices cuando se crean, o especificar una intercalación para operaciones CRUD y agregaciones. Para las operaciones que admiten la intercalación, MongoDB utiliza la intercalación por defecto de la colección, a menos que la operación especifique una intercalación diferente.
Parámetros de intercalación
'collation' => { 'locale' => <string>, 'caseLevel' => <bool>, 'caseFirst' => <string>, 'strength' => <int>, 'numericOrdering' => <bool>, 'alternate' => <string>, 'maxVariable' => <string>, 'normalization' => <bool>, 'backwards' => <bool> }
El único parámetro requerido es locale, que el servidor analiza como un ID de configuración regional del formato ICUPor ejemplo, configure locale en en_US para representar inglés fr_CA de EE. UU. o para representar francés de Canadá.
Para obtener una descripción completa de los parámetros disponibles, consulta la entrada en el manual de MongoDB.
Asignar una intercalación por defecto a una colección
El siguiente ejemplo crea una nueva colección llamada contacts en la base de datos test y asigna una intercalación por defecto con la localización fr_CA. Especificar una intercalación al crear la colección garantiza que todas las operaciones que involucren una consulta ejecutada en la colección contacts utilicen la intercalación fr_CA, a menos que la consulta especifique otra intercalación. Cualquier índices de la nueva colección también heredará la intercalación por defecto, a menos que el comando de creación especifique otra intercalación.
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") client[:contacts, { "collation" => { "locale" => "fr_CA" } } ].create
Asignar una intercalación a un índice
Para especificar una intercalación para un índice, utiliza la opción collation al crear el índice.
El siguiente ejemplo crea un índice en el campo name de la colección address_book, con el parámetro unique activado y una intercalación por defecto con locale configurado en 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 este índice, asegúrese también de que sus consultas especifiquen la misma intercalación. La siguiente query utiliza el índice anterior:
client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US" })
Las siguientes consultas NO usan el índice. La primera query no utiliza ninguna intercalación, y la segunda utiliza una intercalación con un valor strength diferente al de la intercalación del índice.
client[:address_book].find({"first_name" : "Adam" }) client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US", "strength" => 2 })
Operaciones que admiten intercalación
Todos los métodos de lectura, actualización y eliminación admiten la intercalación. A continuación se muestran algunos ejemplos.
find() y sort()
Las consultas individuales pueden especificar una intercalación para comparar y ordenar los resultados. La siguiente operación de consulta y ordenación utiliza una intercalación alemana con el parámetro locale establecido en 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()
Una colección llamada names contiene los siguientes documentos:
{ "_id" : 1, "first_name" : "Hans" } { "_id" : 2, "first_name" : "Gunter" } { "_id" : 3, "first_name" : "Günter" } { "_id" : 4, "first_name" : "Jürgen" }
La siguiente operación find_one_and_update en la colección no especifica una intercalación.
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 } })
Debido a que Gunter es léxicamente el primero en la colección, la operación anterior no devuelve resultados ni actualiza ningún documento.
Considere la misma operación find_one_and_update, pero con la intercalación especificada. La configuración regional está establecida en de@collation=phonebook.
Nota
Algunas localizaciones tienen una opción collation=phonebook disponible para su uso con idiomas que ordenan los nombres propios de manera diferente a otras palabras. De acuerdo con la de@collation=phonebook intercalación, los caracteres con diéresis aparecen antes que los mismos caracteres sin diéresis.
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 } )
La operación devuelve el siguiente documento actualizado:
{ "_id" => 3, "first_name" => "Günter", "verified" => true }
find_one_and_delete()
Establezca el parámetro de intercalación numericOrdering en true para comparar cadenas numéricas por sus valores numéricos.
La colección numbers contiene los siguientes documentos:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
El siguiente ejemplo coincide con el primer documento en el que el campo a tiene un valor numérico superior a 100 y lo borra.
docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } }, { "collation" => { "locale" => "en", "numericOrdering" => true } })
Después de la operación anterior, los siguientes documentos permanecen en la colección:
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" }
Si realizas la misma operación sin intercalación, el servidor elimina el primer documento que encuentra en el que el valor léxico de a es mayor que "100".
numbers = client[:numbers] docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } })
Después de la operación anterior, se ha eliminado el documento en el que a era igual a "16", y los siguientes documentos permanecen en la colección:
{ "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
delete_many()
Se pueden utilizar colaciones con todas las diversas operaciones masivas que existen en el driver Ruby.
La colección recipes contiene los siguientes documentos:
{ "_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" }
Al establecer el parámetro strength del documento de intercalación en 1 o 2, el servidor ignora las mayúsculas y minúsculas en el filtro de consulta. El siguiente ejemplo utiliza un filtro de consulta que no distingue entre mayúsculas y minúsculas para eliminar todos los registros en los que el campo cuisine coincide con 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 })
Después de ejecutar la operación anterior, los documentos con valores de _id de 2 y 4 se eliminan de la colección.
Agregación
Para utilizar la intercalación con una operación de agregación, especifica una intercalación en las opciones de agregación.
El siguiente ejemplo de agregación utiliza una colección llamada names y agrupa juntos el campo first_name, cuenta el número total de resultados en cada grupo y ordena los resultados según el orden telefónico alemán.
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