javascript firebase google-cloud-firestore

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:

  1. Con Unicode, eliminar el caso es más complejo que solo ''toLowerCase''
  2. 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; });