Удаление индексов, которые находятся во вложенном поле при удалении объекта

#android #firebase #firebase-realtime-database #nosql

#Android #firebase #firebase-realtime-база данных #nosql

Вопрос:

Я все еще на Firebase, и на этот раз у меня есть вопрос, связанный с удалением объектов.

У меня есть структура, подобная следующей:

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

Поэтому, если я хочу удалить пользователя, я должен:

  1. Удаление пользовательского объекта
  2. Удалите объект user в ветке 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 , и когда мне нужно загрузить пользовательские контакты, я должен позвонить каждому пользователю, чтобы узнать, является ли пользователь null (был удален), и в этом случае не показывайте его. Кстати, это приводит к загрязнению базы данных.

  • Решение 2. создайте обратный индекс contacts_users , в котором я сохраняю пользователей, на которых ссылается пользователь, которого я пытаюсь удалить. Как показано ниже:

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

Итак, когда мне нужно удалить пользователя, я посмотрю на его дочерние contacts_users элементы и узнаю всех пользователей, у которых он есть в контактах, и приступлю к его удалению (теперь, когда я могу знать весь путь). Мне кажется, это более похожий на NoSQL подход.

Что вы думаете? Есть ли другой способ сделать это?

Ответ №1:

Ваше второе решение — это то, как я бы предложил это сделать, не нужно искать. Вы можете хранить эту информацию для каждого пользователя, но если она становится слишком большой, лучше использовать ее в другом месте.

Аналогично, удаление в другом направлении также становится проще.

Комментарии:

1. То же самое здесь: всякий раз, когда вам нужно выполнить цикл filter, вам, вероятно, лучше создать обратный индекс.