Cloud Firestore - Как получить реляционные данные из двух коллекций? - PullRequest
0 голосов
/ 08 октября 2018

Я хочу определить эти две коллекции в Cloud Firestore.Некоторые примеры данных показаны ниже:

Списки воспроизведения:

  • name: "playlist1"
  • songCount: // Для расчета в реальном времени

Песни:

  • title: "song1"
  • playlistId: "playlist1"

  • title: "song2 "

  • playlistId:" playlist1 "

  • title:" song3 "

  • playlistId:" playlist1 "

Далее, в моем приложении для Android я хочу показать отдельные списки всех плейлистов и всех песен.Однако при отображении списка всех плейлистов я хочу показать название каждого плейлиста вместе с количеством песен, содержащихся в каждом, на основе значения в "songCount".

Пожалуйста, посоветуйте, какой запрос яНужно сделать в Cloud Firestore для достижения этой цели.Доступна ли функция Join, или мне нужно поместить коллекцию Songs в цикл и считать те, которые имеют playlistId как «playlist1», а затем повторить ее для всех плейлистов, которые должны быть представлены в списке плейлистов?Я хочу иметь более разумное решение, но не могу найти его в Интернете.

Любая помощь будет очень полезна.Спасибо за ваше время.

1 Ответ

0 голосов
/ 08 октября 2018

Доступна ли функция соединения?

К сожалению, в Firestore нет запроса на присоединение.Запросы в Firestore мелкие: они получают только элементы из коллекции, с которой выполняется запрос.Невозможно получить документы из коллекции верхнего уровня и других коллекций или вложенных коллекций в одном запросе.Firestore не поддерживает запросы к различным коллекциям за один раз.Один запрос может использовать свойства документов только в одной коллекции.Поэтому самое простое решение, которое я могу придумать, - это использовать структуру базы данных, которая выглядит примерно так:

Firestore-root
   |
   --- playlists (collection)
   |     |
   |     --- playListId (document) //The unique id of the play list
   |           |
   |           --- name: "playlist1"
   |
   --- songs (collection)
        |
        --- playListId (document) //The same as the above playListId
               |
               --- playListSongs
                     |
                     --- songId
                          |
                          --- title: "song1"

Чтобы отобразить все списки воспроизведения, просто присоедините прослушиватель к ссылке playlists иполучить все playlist объектов.Если вы хотите получить все песни, которые соответствуют определенному списку воспроизведения, просто подключите слушателя на songs\playListId\playListSongs и получите все song объекты.

Что касается количества всех сог, которые соответствуют списку воспроизведения,Я рекомендую вам посмотреть мой ответ из этого поста , где я объяснил, что вы можете достичь этого.Итак, согласно последней части моего ответа, ваша база данных Firebase в реальном времени должна выглядеть следующим образом:

Firebase-realtime-database-root
    |
    --- playlists
          |
          --- playListIdOne: numberOfSongs
          |
          --- playListIdTwo: numberOfSongs

Редактировать:

Я не могускажем, я полностью это понял, особенно потому, что первый ответ касается FireStore, а второй - Firebase realtime db.

Я дал вам это решение, потому что если вы хотите использовать Cloud Firestore для подсчета и обновления элементов каждый раз, когдапесня добавлена ​​или удалена, Firestore будет взимать плату за каждую операцию записи / удаления.База данных Firebase в реальном времени имеет еще один тарифный план , так что вы не будете платить за это.См. Цены на Firestore Пожалуйста, прочитайте еще раз до конца, мой ответ из этой записи .

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

Вот как вы можете получить номер песни из Firestore и записать ее в базу данных Firebase в реальном времени:

rootRef.collection("songs").document(playListId).collection("playListSongs")
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            Log.d("TAG", task.getResult().size() + "");
            DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
            DatabaseReference playListIdRef = rootRef.child("playlists").child(playListId);
            playListIdRef.setValue(task.getResult().size());

        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});

И этокак вы можете читать:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playListIdRef = rootRef.child("playlists").child(playListId);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
            long playListIdOne = dataSnapshot.getValue(String.Long);
            Log.d(TAG, "playListIdOne: " + playListIdOne);
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage());
    }
};
playListIdRef.addListenerForSingleValueEvent(valueEventListener);

Во-вторых, согласно предложенной вами структуре, как я могу получить список всех песен во всех плейлистах?

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

Firestore-root
   |
   --- allSongs
         |
         --- songId
              |
              --- //song details

Эта практика называется denormalization и является обычной практикой, когда дело доходит до Firebase.Для лучшего понимания я рекомендую вам посмотреть это видео, Денормализация нормальна для базы данных Firebase .Это для базы данных реального времени Firebase, но те же правила применяются к Cloud Firestore.

Кроме того, когда вы дублируете данные, есть одна вещь, которую нужно иметь в виду.Точно так же, как вы добавляете данные, вы должны поддерживать их.Другими словами, если вы хотите обновить / обнаружить элемент, вы должны делать это в каждом месте, где он существует.

Помня о том, что одна и та же песня может быть найдена в нескольких списках воспроизведения..

Это не имеет значения, потому что каждый зонд имеет свой идентификатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...