【问题标题】:Swift - Firebase search in databaseSwift - 数据库中的 Firebase 搜索
【发布时间】:2016-07-08 20:03:48
【问题描述】:

我在打字时搜索用户。但是最后它会返回每个用户。 我不知道为什么会发生这种情况。好像没问题

 class func findUsers(text: String)->[User]{
    let user = User()
    var users = [User]()
    ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).observeEventType(.Value, withBlock: { snapshot in
        for u in snapshot.children{
            user.name = u.value!["name"] as? String
            user.surname = u.value!["surname"] as? String
            user.email = u.value!["email"] as? String
            user.score = u.value!["score"] as? Int
            user.status = u.value!["status"] as? Int
            user.id = u.value!["id"] as? String
            user.pin = u.value!["pin"] as? String
            users.append(user)
            print(user.name)
        }
    })
    print("users:", users)
    return users
}

【问题讨论】:

  • 您能否显示您的 JSON 的最小且具有代表性的 sn-p(作为文本,您可以通过从 Firebase 数据库控制台导出它来获得)和 text 在它给出的那一刻的值错误的结果?

标签: swift firebase firebase-realtime-database


【解决方案1】:

您正在使用queryStartingAtValue。来自documentation

FIRDatabaseQuery 实例返回 queryStartingAtValue:childKey 将响应节点上的事件 值大于 startValue,或等于 startValue 并带有键 大于或等于 childKey。

因此请记住,如果您搜索用户的name,它将给出所有用户名称的字母顺序大于给定用户。您需要设置一个queryEndingAtValue 来限制查询范围。

ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"\u{f8ff}")

Firebase legacy documentation 是了解 Firebase 如何处理查询的好资源。在那里你会发现:

上面查询中使用的 f8ff 字符是一个很高的代码点 在 Unicode 范围内。因为它在大多数常规字符之后 Unicode,查询匹配所有以 b 开头的值。

您可能还会对Elasticsearch 感兴趣。 Flashlight是一个集elasticsearch和firebase于一体的node服务。


更新:

正如 cmets 中所指出的,如果您要搜索的字符串包含大写字符,则此方法将不起作用。在这种情况下,解决方案是在对象中添加一个附加字段,其中包含您要搜索的所有信息均以小写形式显示。因此,如果您将Satoshi Nakamoto 设置为name,您将使用satoshi nakamoto 保存一个额外的nameSearch 属性。

最后确保您的搜索字符串也是小写的。


您的代码还有一些其他问题。

  • 您正在设置观察者。它会在您的数据更改时触发回调,因此您应该在回调中重置 users 数组,这样您就不会有重复和脏数据。

  • 由于 firebase 调用是异步的,因此您的函数不会向用户返回数据。当您调用 return users 时,您不会填充 users 数组。我建议您使用 self.users = users 而不是在函数中返回它。否则,如果你想继续当前的方法并返回它,你应该设置一个completion handler


class func findUsers(text: String)->Void{
    ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"\u{f8ff}").observeEventType(.Value, withBlock: { snapshot in
        var user = User()
        var users = [User]()
        for u in snapshot.children{
            user.name = u.value!["name"] as? String
            ...
            users.append(user)
        }
        self.users = users
    })
}

【讨论】:

  • 非常感谢!你刚刚救了我的命
  • 我会说这是一个正确的解决方案,但它不是 100% 有效的,例如它不区分大小写。如果我搜索“Jim”,我会得到结果,但搜索“jim”什么也没给我。有解决办法吗?
  • 嘿@Wink,感谢您的评论,抱歉回复晚了。我添加了一个应该有帮助的更新。
  • 我也被困在这里。 firebase 中对象模型上的小写搜索字符串为我解决了这个问题。在一个完美的世界中,我们会使用弹性搜索,但这可以完成工作。谢谢!
  • 这仍然区分大小写。我怎样才能做到,如果我搜索 JIM,我会得到“jim”和“jimmy”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多