如何使用 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: 搜索字段以特定值开头的文档。

例如,要搜索nameal 开头的所有文档, 你会使用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更新用户数据

如何在flutter中获取firestore文档的documentid?

如何使用flutter cloud_firestore包传递firestore auth token