Firebase嵌套结构搜索

时间:2018-05-07 19:42:57

标签: java android firebase firebase-realtime-database

我正在Firebase中存储用户列表。结构如下所示:

enter image description here

在我的Android应用中,我希望让用户以灵活的方式搜索任何用户。因此,如果用户搜索以下内容, John Smith 应显示在结果中: Joh ...,Smit ...,jsmi ... 。此外,我希望搜索能够在用户输入时立即显示结果(如Instagram)。

目前,这是我的实施。我会在搜索活动打开时提取所有用户详细信息,并将所有详细信息存储在ArrayList中。然后当用户开始搜索时,我搜索ArrayList并返回匹配。

以下是一些示例代码:

ArrayList<User> listOfUsers = new ArrayList<>();

ref.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
      User user = userSnapshot.getValue(User.class);
      listOfUsers.add(user);
    }
  }

  @Override
  public void onCancelled(DatabaseError databaseError) { }
});

// Then I search for users like this
for (User user : listOfUsers) {
   if (user.getFullname.contains("Joh") || 
      user.getUsername.contains("Joh")){
      // show user in results
   }
}

它现在正常工作,因为我没有太多用户。但是我觉得如果我有100k用户,那么事先拉出他们所有的细节并解析100k项目的arrayList来寻找匹配可能会很昂贵。什么是更好的解决方案?

1 个答案:

答案 0 :(得分:1)

Firebase不支持本机索引或搜索数据库中的文本字段。此外,下载整个节点以搜索客户端字段是不切实际的,大部分时间都是因为它的大小。

不幸的是,Firebase也不允许您在多个媒体资源上创建搜索。所以不允许这样的查询。

usersRef
    .whereEqualTo("name", "John Smith")
    .whereEqualTo("username", "jsmith"); //Not allowed

但是,如果您想基于单个属性查询数据库,例如:Joh... Smit...,则需要执行以下查询:

usersRef
    .whereEqualTo("name", "Joh")
    .startAt(searchText).endAt(searchText + "\uf8ff");

如果您想使用较新版本的数据库,建议您尝试Cloud Firestore。要启用Cloud Firestore数据库的全文搜索,您可以使用名为Algolia的第三方搜索服务,这将帮助您实现所需的确切功能。为此,我建议您从 this post 中查看答案。有关详细信息,我还建议您看到 video