J'ai essayé de lire les données triées de Cloud Firestore en utilisant OrderBy. Et Firestore a renvoyé les données comme ordre suivant:
AAA
BBB
aaa
bbb
Maintenant, ce que je veux, c'est quelque chose comme ceci:
AAA
aaa
BBB
bbb
Je veux ce résultat uniquement en utilisant OrderBy pas par tri manuel.
Existe-t-il un moyen de trier comme ça dans Firestore?
Veuillez me fournir une solution pour cela.
Merci d'avance.
Le tri dans Cloud Firestore est sensible à la casse. Il n'y a pas d'indicateur pour que le tri ignore le cas.
La seule façon de réaliser votre cas d'utilisation est de stocker le champ deux fois.
Disons que votre champ qui stocke 'AAA' et 'aaa' s'appelle myData
. Dans votre code client, vous devrez stocker un deuxième champ appelé myData_insensitive
où vous stockez une copie insensible à la casse des données.
DocA:
-> myData = 'AAA'
-> myData_insensitive = 'AAA'
DocB:
-> myData = 'aaa'
-> myData_insensitive = 'AAA'
DocC:
-> myData = 'BBB'
-> myData_insensitive = 'BBB'
DocD:
-> myData = 'bbb'
-> myData_insensitive = 'BBB'
Vous pouvez maintenant interroger et/ou commander par myData_insensitive
, mais affichez myData
.
Deux choses intéressantes à propos de ce domaine sont:
Sans créer d'index distincts pour chaque classement à résoudre (2), une approche d'implémentation à traiter (1) consiste à replier la casse. Si vous souhaitez uniquement prendre en charge les versions de navigateur modernes, voici ce qui vous donne un exemple 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);
});
Cela vous donnera un document dans Cloud Firestore avec les champs suivants:
{
"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"
}
Pour gérer un navigateur plus ancien, vous pouvez voir une solution dans Comment puis-je rendre toLowerCase () et toUpperCase () cohérents entre les navigateurs
Vous pouvez également le faire manuellement après avoir obtenu vos résultats:
docArray.sort((a, b) => {
if (a.myData.toLowerCase() < b.myData.toLowerCase()) {
return -1;
}
if (a.myData.toLowerCase() > b.myData.toLowerCase()) {
return 1;
}
return 0;
});