【问题标题】:How to search text in Flutter using Firestore如何使用 Firestore 在 Flutter 中搜索文本
【发布时间】: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/… 以获取演示。

标签: firebase flutter dart google-cloud-firestore


【解决方案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();
      

      我还会将结果限制为实际数量的元素。

      【讨论】:

        猜你喜欢
        • 2018-10-01
        • 1970-01-01
        • 2021-04-22
        • 2021-05-08
        • 2021-06-05
        • 2022-08-18
        • 2018-04-03
        • 1970-01-01
        • 2019-09-07
        相关资源
        最近更新 更多