Структурированный Firestore Android для выборки на нескольких чеках - PullRequest
0 голосов
/ 03 сентября 2018

Я хочу прочитать коллекцию на основе нескольких элементов массива.

db.collection("questionCollection")
                .orderBy("questionID", Query.Direction.DESCENDING)
                .whereArrayContains("tags","EveryDayScience")
                //.whereArrayContains("tags","generalKnowledge")//this cannot be possible
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        if (queryDocumentSnapshots.isEmpty()) {
                            Log.d(TAG, "onSuccess: LIST EMPTY");
                            return;
                        } else {
                            // Convert the whole Query Snapshot to a list
                            // of objects directly! No need to fetch each
                            // document.
                            questionList = queryDocumentSnapshots.toObjects(QuestionBO.class);
                        }
                    }
                }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                e.printStackTrace();
                Toast.makeText(mContext,"Failed",Toast.LENGTH_LONG).show();
            }
        });

Мне нужно прочитать все вопросы, которые относятся к everyDayScience и generalKnowledge или нескольким тегам, таким как физика, химия и т. Д.

Архитектура моего приложения приведена ниже. Как я мог структурировать свою БД для чтения коллекции по нескольким тегам?

enter image description here

Редактировать Я требую разбивки на страницы, например, любимых и комментирующих вопросов. и вы порекомендовали меня Эта структура

В MongoDb это достигается следующим образом

1 Ответ

0 голосов
/ 03 сентября 2018

Если вы попытаетесь объединить несколько методов whereArrayContains(), вы, скорее всего, получите следующую ошибку:

Причина: java.lang.IllegalArgumentException: недопустимый запрос. Запросы поддерживают только наличие одного фильтра, содержащего массив.

Так что, к сожалению, Firestore может разрешить только один вызов whereArrayContains() метода. В этом случае вам следует рассмотреть возможность дополнения структуры базы данных, чтобы разрешить обратный поиск, добавив под каждым объектом тега (документом) из tagCollection новую коллекцию с именем tagQuestion, в которую необходимо добавить все вопросы, помеченные конкретный тег. Структура вашей базы данных должна выглядеть следующим образом:

Firestore-root
  |
  --- tagCollection (collection)
         |
         --- EveryDayScience (document)
         |    |
         |    --- tagQuestions (collection)
         |          |
         |          --- tagQuestionId
         |                 |
         |                 --- //question details
         |
         --- generalKnowledge (document)
              |
              --- tagQuestions (collection)
                    |
                    --- tagQuestionId
                           |
                           --- //question details

Чтобы получить все вопросы из двух конкретных тегов, используйте следующие строки кода:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query firstQuery = rootRef.collection("tagCollection").document("EveryDayScience").collection("tagQuestions");
Query firstQuery = rootRef.collection("tagCollection").document("generalKnowledge").collection("tagQuestions");

Task firstTask = firstQuery.get();
Task secondTask = secondQuery.get();

Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
         //Do what you need to do with the list of questions from within two tags
    }
});

Но вы будете думать, зачем это делать? Зачем дублировать данные? Что ж, нет проблем с дублированием данных, когда речь идет о Firebase. Это довольно распространенная практика, которая называется denormalization, и для этого я рекомендую вам посмотреть это видео, Денормализация нормальна для базы данных Firebase . Это для базы данных реального времени, но те же принципы применимы к облачному хранилищу пожаров.

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

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