如何不使用子字段、不修改存储数据实现Firebase Firestore搜索不区分大小写
解决方案
由于你要求不能修改Firestore已存储数据、也不能新增额外辅助字段,我们可以利用Firestore字符串按Unicode码点排序的特性,通过构造查询范围的上下界,覆盖所有大小写组合的匹配结果,实现不区分大小写的前缀查询。
实现逻辑
- 拿到用户输入的搜索词后先做去空格处理
- 构造查询下界:将搜索词转为全大写形式,所有大小写组合的目标字符串排序都会大于等于这个值
- 构造查询上界:将搜索词转为全小写形式后拼接特殊字符
\uf8ff,该字符是Unicode专用区的起始字符,排序优先级高于所有常规拉丁字母,所有大小写组合的目标字符串排序都会小于这个值 - 用上下界替换原来的单个
isGreaterThanOrEqualTo条件,增加isLessThan条件限定范围
修改后的代码
getResults(){ String rawQuery = _searchQueryController.text.trim(); // 构造查询上下界 String lowerBound = rawQuery.toUpperCase(); String upperBound = rawQuery.toLowerCase() + '\uf8ff'; FirebaseFirestore.instance.collection('items') .where("itemModel", isGreaterThanOrEqualTo: lowerBound) .where("itemModel", isLessThan: upperBound) .where("status", isEqualTo: "approved") .get() .then((results){ setState(() { items = results; }); }); }
注意事项
- 该方案仅适用于当前的前缀匹配场景(即搜索词匹配目标字段的开头部分),如果需要全词匹配或任意位置包含匹配,该方案不适用
- 如果你的搜索场景存在大量非拉丁字符(如中文、日文等),需要调整上下界的构造逻辑适配对应字符集的排序规则
内容的提问来源于stack exchange,提问作者Keshav Agarwal
相关产品推荐
相关产品推荐

