Sé que este es un viejo hilo, pero creo que sería útil para responder de todos modos.
Definitivamente no desea hacer la clasificación en su aplicación, porque eso significa que tiene que obtener todos los documentos de la colección en la memoria para ordenarlos y devolver la ventana que desee. Si tu colección es enorme, entonces esto es extremadamente ineficiente. La base de datos debería hacer la clasificación y devolverle la ventana.
Pero, MongoDB no admite la ordenación sensible a la configuración regional, usted dice. ¿Cómo resuelves el problema? La magia es el concepto de "claves de clasificación".
Básicamente, digamos que tiene el alfabeto inglés/latino regular de "a" a "z". Lo que haría sería crear una asignación de clave de clasificación de "a" a "01" y de "b" a "02", etc., a "z" a "26". Es decir, asigna cada letra a un número en el orden de clasificación para ese idioma y luego codifica ese número como una cadena. Luego, asigna la cadena que deseas ordenar a este tipo de clave de orden. Por ejemplo, "abc" se convertiría en "010203". A continuación, añadir una propiedad a su documento con la clave de ordenación para una propiedad, y añadir el nombre de la propiedad con el nombre de la la configuración regional:
{
name: "abc",
name_en: "010203"
}
Ahora se puede ordenar en el lenguaje "es" simplemente por la indexación en la propiedad "name_en" y utilice la ordenación simple MongoDB basada en inglés para selectores y rangos en lugar de la propiedad "nombre".
Ahora, digamos que tiene otra lengua loca "xx" donde el orden del alfabeto es "acb" en lugar de "abc".(Sí, hay lenguas que meterse con el orden del alfabeto latino de esa manera!) La clave de ordenación sería así:
{
name: "abc",
name_en: "010203",
name_xx: "010302"
}
Ahora, todo lo que tiene que hacer es crear índices en Suite Sencilla y name_xx y utilice la clasificación MongoDB regular para ordenar correctamente en esas configuraciones regionales. Básicamente, las propiedades adicionales son proxies para clasificar en diferentes lugares.
Entonces, ¿dónde obtienes estas asignaciones, preguntas? Después de todo, no eres un experto en globalización, ¿verdad?
Bueno, si usa Java, C o C++, existen clases ya preparadas que hacen esta asignación por usted. En Java, use la clase Collator estándar o use la clase icu4j Collator. Si está utilizando C/C++, use la versión C/C++ de la función/clase Collator de la ICU. Para otros idiomas, estás fuera de suerte a menos que puedas encontrar una biblioteca que ya lo haga.
Éstos son algunos enlaces para ayudarle a encontrarlos:
El estándar Compaginadora biblioteca de Java: http://docs.oracle.com/javase/7/docs/api/java/text/Collator.html#getCollationKey(java.lang.String)
La clase C++ Compaginadora: http://icu-project.org/apiref/icu4c/classicu_1_1Collator.html#ae0bc68d37c4a88d1cb731adaa5a85e95
También puede hacer diferentes criterios de ordenación que le permiten ordene las mayúsculas y minúsculas según la configuración regional (sí, la asignación de mayúsculas y minúsculas es sensible a la configuración regional) y la insensibilidad a los acentos, y la variante Unicode insensible, o cualquier combinación de las anteriores. El único problema es que ahora tiene muchas propiedades que son paralelas a cada propiedad ordenable, y debe mantenerlas sincronizadas cuando actualice la propiedad de "nombre" base. Es un dolor en el que usted sabe qué, pero aún así, es mejor que hacer la clasificación en la aplicación o la capa de lógica de negocios.
También tenga cuidado con los cursores con rangos. En inglés, por ejemplo, simplemente ignoramos acentos en los personajes. Entonces, un "Ö" se ordena de la misma manera que "O" y aparecerá en el rango "M" a "Z". Pero, en sueco, los caracteres acentuados se ordenan después de "Z". Entonces, si haces un rango "M" - "Z", incluirás un montón de registros que comienzan con "Ö" que deberían estar allí en inglés, pero no en sueco.
Esto también tiene implicaciones en la fragmentación si divide en una propiedad de texto de un documento. Tenga cuidado con los rangos dentro de qué fragmento. Sería mejor fragmentar cosas que no son sensibles a la configuración regional, como los hashes.
Entonces, con este ejemplo, ¿se detendría después de 5 o 6 caracteres y 0-fill en palabras más cortas? – Stephane
No, una cadena más corta siempre "gana" la comparación. "abc" ordena antes de "abcdef" aunque tengan el mismo prefijo, por lo que "010203" debe ordenar antes de "010203040506". Las propiedades de la clave de clasificación se deben comparar como cadenas, no como números. –
Ah, y las claves de clasificación que los collaters Java y C++ devuelven parecen muy diferentes a los ejemplos que di aquí. Acabo de usar "01", "02", etc. porque eran fáciles de entender. En Java, por ejemplo, el método getCollationKey() devuelve una matriz de enteros que contiene los elementos de intercalación de bits. Sugiero transformar esta matriz en una cadena de dígitos hexadecimales para que MongoDB pueda compararlos como cadenas con las reglas de comparación en inglés predeterminadas que funcionan bien en hexadecimal. –