Cloud Firestore Case Insensitive Sorting Using Query
我尝试使用orderby从云FireStore读取排序数据。FireStore返回数据的顺序如下:
AAA<BR/>BBB
AAA<BR/>血脑屏障
现在,我想要的是如下:
AAA<BR/>AAA<BR/>BBB
血脑屏障
我只希望使用orderby而不是手动排序的结果。
在消防商店有没有办法这样分类?请给我一个解决办法。
事先谢谢。
云FireStore中的排序区分大小写。没有使排序忽略案例的标志。
实现用例的唯一方法是将字段存储两次。
假设您存储"aaa"的字段称为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | DocA: -> myData = 'AAA' -> myData_insensitive = 'AAA' DocB: -> myData = 'aaa' -> myData_insensitive = 'AAA' DocC: -> myData = 'BBB' -> myData_insensitive = 'BBB' DocD: -> myData = 'bbb' -> myData_insensitive = 'BBB' |
现在可以按
这个地区有两个有趣的地方:
不为每个排序规则创建单独的索引来解决(2),处理(1)的一种实现方法是通过案例折叠。如果您只想支持现代浏览器版本,那么下面给出一个javascript示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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); }); |
这将在CloudFireStore中为您提供一个包含以下字段的文档:
1 2 3 4 5 6 7 8 9 10 11 | { "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" } |
要处理较旧的浏览器,您可以看到一个解决方案,即如何使tolowercase()和touppercase()在浏览器之间保持一致
您也可以在获得结果后手动执行此操作:
1 2 3 4 5 6 7 8 9 | docArray.sort((a, b) => { if (a.myData.toLowerCase() < b.myData.toLowerCase()) { return -1; } if (a.myData.toLowerCase() > b.myData.toLowerCase()) { return 1; } return 0; }); |