如何使用 Firestore 在 Flutter 中搜索文本
Posted
技术标签:
【中文标题】如何使用 Firestore 在 Flutter 中搜索文本【英文标题】:How to search text in Flutter using Firestore 【发布时间】:2021-09-14 08:28:33 【问题描述】:我想通过查询使用 Cloud Firestore 实现搜索功能,但没有获取任何与获取数据相关的查询。我在谷歌上搜索了很多东西,但唯一的建议是首先从云 Firestore 获取所有数据,然后在本地搜索。我检查了查询中的 where 条件,但没有找到任何条件,例如“开始于”等。
我想按名称参数搜索。
【问题讨论】:
您是要搜索name
字段与搜索词完全匹配的文档,还是要进行全文搜索(firebase.google.com/docs/firestore/solutions/search)?
感谢您的回复假设我有很多记录,所以如果我搜索了“al”,那么所有文本都会显示谁以“al”文本开头并匹配。
好的,这是一个全文搜索。请访问我的第一条评论中的链接,看看它是如何实现的。您将需要像 Algolia 这样的第三方搜索服务。
我已经按照您的建议检查了 URL,但是如果您有任何与此相关的演示,则无法理解,因此请与我分享。我还搜索了 (pub.dev/packages/firestore_search) 插件,请您建议是否使用完整。
查看dev.to/samarthagarwal/… 以获取演示。
【参考方案1】:
Firestore 没有内置的全文搜索功能。我通常用于搜索文本字段的仅有两个查询运算符是:
使用isEqualTo:
查找字段与值完全匹配的文档。
使用isGreaterThanOrEqualTo:
和isLessThanOrEqualTo:
搜索字段以特定值开头的文档。
例如,要搜索name
以al
开头的所有文档,
你会使用collectionRef.where("name", isGreaterThanOrEqualTo: "al").where("name", isLessThanOrEqualTo: "al\uf7ff")
。这里的\uf7ff
只是最后一个已知的Unicode 字符,因此查询在处理完每个al
后停止返回结果。
如果您需要任何其他文本搜索操作,则需要为此使用其他解决方案 - 例如记录在 here 的 Algolia。
【讨论】:
【参考方案2】:这段代码对于使用火石颤振搜索文本非常有帮助
StreamBuilder(
stream: ( searchtxt!= "" && searchtxt!= null)?FirebaseFirestore.instance.collection("addjop").where("specilization",isNotEqualTo:searchtxt).orderBy("specilization").startAt([searchtxt,])
.endAt([searchtxt+'\uf8ff',])
.snapshots()
:FirebaseFirestore.instance.collection("addjop").snapshots(),
builder:(BuildContext context,snapshot)
if (snapshot.connectionState == ConnectionState.waiting &&
snapshot.hasData != true)
return Center(
child:CircularProgressIndicator(),
);
else
retun widget();
)
【讨论】:
【参考方案3】:有一种方法可以处理名称等短字符串。我们经常在我们的应用程序中使用它。您可以将名称拆分为小部分并将它们添加到数组中。要使用全文搜索来搜索名称,请等待至少 3 个字母,然后使用 array-contains-any
查询检查字母组合是否是数组的一部分。
拆分为数组代码:
const MAPPING_TABLE =
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
å: 'a',
æ: 'ae',
ç: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ý: 'y',
ÿ: 'y',
function splitStringToArray(stringToSplit)
const listCharacters = stringToSplit.split('')
var output = []
//replace special Characters
for (var i = 0; i < listCharacters.length; i++)
if (MAPPING_TABLE[listCharacters[i]] != null)
listCharacters[i] = MAPPING_TABLE[listCharacters[i]]
for (var i = 0; i < listCharacters.length; i++)
var temp = [listCharacters[i]]
for (var j = i + 1; j < listCharacters.length; j++)
temp.push(listCharacters[j])
const joinedString = temp.join('').toLowerCase()
if (joinedString.length > 2)
output.push(joinedString)
return output
export default splitStringToArray
这是一个用于搜索名称的查询:
ref = ref.where("search", "array-contains-any", [value.toLowerCase()]);
const snap = await ref.limitToLast(20).get();
我还会将结果限制为实际数量的元素。
【讨论】:
以上是关于如何使用 Firestore 在 Flutter 中搜索文本的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Flutter 在 Firestore 中删除集合中的所有文档
如何在 Flutter Web 上使用 StreamBuilder 和 Firestore?
如何在 Firebase + Firestore + Flutter 中使用 StreamBuilder 将所有子集合数据获取到 Widget
如何在flutter的firestore中使用uid更新用户数据