[英]Lodash : how to do a case insensitive sorting on a collection using orderBy?
[英]Cloud Firestore Case Insensitive Sorting Using Query
我嘗試使用OrderBy從 Cloud Firestore 讀取排序數據。 Firestore 按以下順序返回數據:
AAA級
BBB
啊啊
bbb
現在,我想要的是如下內容:
AAA級
啊啊
BBB
bbb
我希望這個結果只使用OrderBy而不是手動排序。
在 Firestore 中有沒有辦法像這樣排序?
請為此提供解決方案。
提前致謝。
Cloud Firestore中的排序區分大小寫。 沒有標志可以使排序忽略大小寫。
實現用例的唯一方法是將字段存儲兩次。
假設存儲'AAA'和'aaa'的字段稱為myData
。 在您的客戶端代碼中,您需要存儲名為myData_insensitive
的第二個字段,其中存儲不區分大小寫的數據副本。
DocA:
-> myData = 'AAA'
-> myData_insensitive = 'AAA'
DocB:
-> myData = 'aaa'
-> myData_insensitive = 'AAA'
DocC:
-> myData = 'BBB'
-> myData_insensitive = 'BBB'
DocD:
-> myData = 'bbb'
-> myData_insensitive = 'BBB'
現在您可以通過myData_insensitive
查詢和/或訂購,但顯示myData
。
關於這個領域的兩個有趣的事情是:
不為每個排序規則創建單獨的索引來解決(2),處理(1)的一種實現方法是通過大小寫折疊。 如果您只想支持現代瀏覽器版本,那么下面給出了一個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);
});
這將在Cloud Firestore中為您提供以下字段的文檔:
{
"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()之間找到一個解決方案
現在是 2022 年。Firebase太棒了。 Firestore很棒。 您無需因為此限制而停止使用 Firestore。 noSQL 世界上的一些東西是故意制造的,只是為了加快速度。
在這種情況下,您可以做的只是在文檔上創建另一個屬性,您可以在其中解析源值並將其小寫。 然后您可以使用解析的屬性對事物進行排序/排序。
例子:
interface ICompany {
dateAdded: Date
dateEdited: Date
description: string
id?: string
logo?: string
managers?: ICompanyManager
name: string
nameLowercase: string
website?: string
}
如果您想按name
對公司進行排序,請在此處。 你可以做什么:
query(
companiesCollection,
orderBy('nameLowercase', 'asc'),
)
添加/編輯時:
const company = await addDoc(companiesCollection, {
name: data.name,
nameLowercase: data.name.toLowerCase(),
description: data.description,
website: data.website,
dateAdded: new Date(),
dateEdited: new Date(),
} as ICompany)
瞧。
您可以在獲得結果后手動執行此操作:
docArray.sort((a, b) => {
if (a.myData.toLowerCase() < b.myData.toLowerCase()) {
return -1;
}
if (a.myData.toLowerCase() > b.myData.toLowerCase()) {
return 1;
}
return 0;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.