javascript - Cloud Firestore Case Insensitive Sorting mediante la consulta
firebase google-cloud-firestore (2)
Intenté leer datos ordenados de Cloud Firestore usando OrderBy . Y Firestore devolvió datos como el siguiente orden:
AAA
BBB
aaa
bbb
Ahora, lo que quiero es algo como lo siguiente:
AAA
aaa
BBB
bbb
Quiero este resultado solo usando
OrderBy,
no mediante Clasificación manual.
¿Hay alguna forma de ordenar así en Firestore?
Por favor, dame una solución para esto.
Gracias por adelantado.
La ordenación en Cloud Firestore distingue entre mayúsculas y minúsculas. No hay bandera para hacer que la clasificación ignore el caso.
La única forma de lograr su caso de uso es almacenar el campo dos veces.
Digamos que su campo que almacena ''AAA'' y ''aaa'' se llama
myData
.
En su código de cliente, deberá almacenar un segundo campo llamado
myData_insensitive
donde almacenará una copia de los datos que no
myData_insensitive
entre mayúsculas y minúsculas.
DocA:
-> myData = ''AAA''
-> myData_insensitive = ''AAA''
DocB:
-> myData = ''aaa''
-> myData_insensitive = ''AAA''
DocC:
-> myData = ''BBB''
-> myData_insensitive = ''BBB''
DocD:
-> myData = ''bbb''
-> myData_insensitive = ''BBB''
Ahora puede consultar y / u ordenar por
myData_insensitive
, pero mostrar
myData
.
Dos cosas interesantes sobre esta área son:
- Con Unicode, eliminar el caso es más complejo que solo ''toLowerCase''
- Diferentes idiomas humanos ordenarán los mismos caracteres de manera diferente
Sin crear índices separados para cada colación para resolver (2), un enfoque de implementación para tratar con (1) es mediante el plegado de mayúsculas y minúsculas. Si solo desea admitir versiones modernas del navegador, lo siguiente le ofrece un ejemplo de JavaScript:
caseFoldNormalize = function (s){
return s.normalize(''NFKC'').toLowerCase().toUpperCase().toLowerCase()
};
caseFoldDoc = function(doc, field_options) {
// Case fold desired document fields
if (field_options != null) {
for (var field in field_options) {
if (field_options.hasOwnProperty(field)) {
switch(field_options[field]) {
case ''case_fold'':
if (doc.hasOwnProperty(field) && Object.prototype.toString.call(doc[field]) === "[object String]") {
doc[field.concat("_insensitive")] = caseFoldNormalize(doc[field])
}
break;
}
}
}
}
return doc;
}
var raw_document = {
name: "Los Angeles",
state: "CA",
country: "USA",
structure: ''Waſſerſchloß'',
message: ''quıt quit'' // Notice the different i''s
};
var field_options = {
name: ''case_fold'',
country: ''case_fold'',
structure: ''case_fold'',
message: ''case_fold''
}
var firestore_document = caseFoldDoc(raw_document, field_options);
db.collection("cities").doc("LA").set(firestore_document).then(function() {
console.log("Document successfully written!");
}).catch(function(error) {
console.error("Error writing document: ", error);
});
Esto le dará un documento en Cloud Firestore con los siguientes campos:
{
"name": "Los Angeles",
"state": "CA",
"country": "USA",
"structure": "Waſſerſchloß",
"message": "quıt quit",
"name_casefold": "los angeles",
"country_casefold": "usa",
"structure_casefold": "wasserschloss",
"message_casefold": "quit quit"
}
Para manejar un navegador más antiguo, puede ver una solución en Cómo hago que toLowerCase () y toUpperCase () sean consistentes en todos los navegadores
También puede hacerlo manualmente después de obtener sus resultados:
docArray.sort((a, b) => {
if (a.myData.toLowerCase() < b.myData.toLowerCase()) {
return -1;
}
if (a.myData.toLowerCase() > b.myData.toLowerCase()) {
return 1;
}
return 0;
});