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 obligatorio es localey que el servidor interpreta como un ID de localización del formato ICU. Por ejemplo, establece locale en en_US para representar el inglés estadounidense o fr_CA para representar el francés canadiense.
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 enumeran algunos ejemplos.
find() y sort()
Las consultas individuales pueden especificar una intercalación para usar al hacer coincidir y ordenar los resultados. La siguiente query y operación de intercalació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.
Considera la misma operación find_one_and_update pero con la intercalación especificada. La localización se establece 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()
Configure el parámetro de intercalación numericOrdering en true para comparar las cadenas numéricas por su valor numérico.
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" }
Configurar el parámetro strength del documento de intercalación a 1 o 2 hace que el servidor ignore la mayúscula y minúscula en el filtro de query. El siguiente ejemplo utiliza un filtro de query insensible a mayúsculas y minúsculas para borrar todos los registros en los que el campo cuisine coincida 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