Swift - 数据库中的Firebase搜索

Rob*_*Kim 7 firebase swift firebase-realtime-database

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

 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
}
Run Code Online (Sandbox Code Playgroud)

ado*_*srs 20

你正在使用queryStartingAtValue.从文档:

FIRDatabaseQuery返回的实例 queryStartingAtValue:childKey将响应节点上的事件,其值大于startValue,或等于startValue且密钥大于或等于childKey.

因此请记住,如果您搜索name用户,它将为所有用户提供字母顺序比给定名称更大的用户.您需要设置a queryEndingAtValue来限制查询范围.

ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"\u{f8ff}")
Run Code Online (Sandbox Code Playgroud)

Firebase遗留文档是了解firebase如何处理查询的良好资源.在那里你会发现:

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

您可能也对Elasticsearch感兴趣.Flashlight是一种集成了elasticsearch和firebase的节点服务.


更新:

正如评论中指出的那样,如果您要搜索的字符串具有大写字符,则无法使用.在这种情况下,解决方案是在对象中添加一个字段,其中您正在搜索的信息全部为小写.所以,如果你有Satoshi Nakamoto,name你将保存额外的nameSearch财产satoshi nakamoto.

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


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

  • 你正在设置一个观察者.它会在您的数据发生变化时触发回调,因此您应该users在回调中重置数组,这样您就不会有重复数据和脏数据.

  • 由于firebase调用是异步的,因此您的函数不会返回带有数据的用户.当您打电话时,return users您将不会填充用户数组.我建议您使用self.users = users而不是在函数中返回它.否则,如果要继续当前方法并返回它,则应设置完成处理程序.


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
    })
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你!你刚救了我的命 (4认同)
  • 我会说这是一个正确的解决方案,但它不是100%有效,例如它不区分大小写.如果我搜索"吉姆",我会得到结果,但搜索"吉姆"并没有给我什么.有解决方案吗? (3认同)