【问题标题】:Remove indexes that are in nested field when deleting an object删除对象时删除嵌套字段中的索引
【发布时间】:2016-10-04 10:37:21
【问题描述】:

我还在 Firebase 上,这次我有一个关于删除对象的问题。

我的结构如下:

users: {
    UsErId1:{
        name: "Jack",
        email: "m@i.l"
    },
    UsErId2: { + },
    UsErId3: { + }
},
user_contacts: {
    UsErId1:{
        UsErId2: true,
        UsErId3: true
    },
    UsErId2: {
        UsErId1: true
    }
}

所以如果我想删除一个用户,我必须:

  1. 删除用户对象
  2. 删除user_contacts分支下的用户对象
  3. 从 user_contacts 中删除所有指向该用户的索引

我的性能问题来自第 3 点,因为我需要迭代所有 user_contacts 条目以查看它是否存在于子项中的用户。

代码示例如下:

private void deleteUser(String userId) {

    firebaseDatabase.getReference("users").child(userId).removeValue();
    firebaseDatabase.getReference("users_contacts").child(userId).removeValue();
    firebaseDatabase.getReference("users_contacts").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot usersSnapshot : dataSnapshot.getChildren()) {
                for( DataSnapshot contactSnapshot : usersSnapshot.getChildren() ){
                    String contactId = contactSnapshot.getValue(String.class);
                    if( contactId.equals(userId) ){
                        contactSnapshot.getRef().removeValue();
                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

我想到了两种可能的解决方案:

  • 解决方案 1:不要从 user_contacts 中删除索引,当我必须加载用户联系人时,我必须调用每个用户以查看是否用户为空(已被删除),在这种情况下,不要显示它。顺便说一句,这会导致数据库变脏。

  • 解决方案 2:创建一个反向索引 contacts_users,在其中存储引用了我尝试删除的用户的用户。如下:

    contacts_user: {
        UsErId1: {
            UsErId2: true
        },
        UsErId2: {
            UsErId1: true  
        },
        UsErId3: {
            UsErId1: true
        }
    }
    

所以,当我必须删除一个用户时,我会在contacts_users 中查看它的子节点,并了解在其联系人中拥有它的每个用户,然后继续删除它(现在我可以知道整个路径)。在我看来,这似乎是一种更像 NoSql 的方法。

你怎么看?还有其他方法吗?

【问题讨论】:

    标签: android firebase firebase-realtime-database nosql


    【解决方案1】:

    您的第二个解决方案是我建议的方式,无需搜索。您可以按每个用户存储该信息,但如果它变得太大,将它放在其他地方会更好。

    同样在另一个方向上删除也变得更容易了。

    【讨论】:

    • 这里也一样:每当您发现自己需要循环+过滤时,最好创建一个反向索引。
    猜你喜欢
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多