Как получить случайных детей из Firebase

Предположим, мы хотим получить 15 случайных дочерних элементов из узла questions со структурой этой базы данных, как показано ниже:

введите здесь описание изображения

1. Первый (интуитивный и обсуждаемый) способ извлечения случайных дочерних элементов из Firebase — получить весь требуемый родительский узел (questions как dataSnapshot), а затем выбрать несколько случайных дочерних элементов на стороне клиента. Этот метод упоминался во многих сообщениях, например, в здесь . Очевидно, что у этого метода есть свои недостатки; например, при запросе через родительский узел большого размера (например, более 10 000 дочерних узлов) получение такой суммы каждый раз приведет к огромному использованию полосы пропускания, а также к нагрузке на стороне клиента (когда нам на самом деле требуется лишь небольшое количество детей)

2. Двигаемся дальше: другой подход, как описано здесь, который использует итератор, каким-то образом обходит весь нагрузка на стороне клиента, однако огромное использование полосы пропускания все еще может иметь место, поскольку мы каждый раз загружаем весь родительский узел.

3. Интересный подход описан в ответе Тома на странице это обсуждение в Firebase, в котором предлагается:

Хакерский способ сделать это - сгенерировать случайный ключ и выполнить запрос с помощью startAt().limit(1). У меня есть ощущение, что это может повредить производительности вашей базы огня, поэтому вы не должны выполнять эту операцию часто. У нас нет настоящей функции случайной выборки.

Это решение на самом деле звучит довольно хорошо, но я не уверен, как оно действительно повлияет на мою Firebase.

4. Другим глупым решением может быть ручное присвоение идентификаторам вопросов, так сказать, от 0 до N, поэтому обработка случайной группы идентификаторов на стороне клиента и выборка вопросов на месте, зная фактическое имя узлов.

<сильный>5. И, наконец, я придумал следующее решение, которое я спрашиваю, является ли оно более или менее жизнеспособным, чем те, что представлены выше: создание другого родителя, содержащего только идентификаторы вопросов, и при необходимости следует получить этот родитель, который намного легче, чем questions родитель. Оттуда у меня были бы конкретные случайные идентификаторы, и мне нужно было бы стрелять только по этим детям. Чтобы лучше понять, что я имею в виду, посмотрите на картинку ниже: введите здесь описание изображения

Теперь из-за этого метода возникает следующая проблема: является ли назначение (скажем) 15 eventListeners хорошей практикой? Может ли это на самом деле замедлить работу? (Примечание: это относится и к методам 3 и 4)

И, наконец, какой метод на самом деле является оптимальным при запросе из большой базы данных для некоторых случайных дочерних элементов?


person Catalin Ghita    schedule 15.02.2018    source источник
comment
Что вы имеете в виду, назначая 15 прослушивателей событий? Что вы хотите сделать с 15 прослушивателями событий?   -  person Hasan Bou Taam    schedule 15.02.2018
comment
@svi.data Поскольку я, возможно, не ясно выразился, я хотел бы получить несколько (скажем, 15) случайных детей от родителя. Как я уже сказал, знание точного идентификатора конкретных дочерних элементов (описанных в последнем методе) подразумевает назначение 15 слушателей. например databaseRef.child("questions").child("id_0001").addSingleValueEventListener(..) за каждый случайный идентификатор, который я получил.   -  person Catalin Ghita    schedule 15.02.2018
comment
так что вы пытаетесь получить детали под каждым случайным идентификатором (поэтому вам нужно использовать 15 прослушивателей событий)?   -  person Hasan Bou Taam    schedule 15.02.2018
comment
@svi.data Да. Мне нужно получить подробную информацию о каждом случайном идентификаторе.   -  person Catalin Ghita    schedule 15.02.2018
comment
Тогда, конечно, вы используете только одного слушателя, указывающего на ваш (question_ids) ref. Что лучше.   -  person Hasan Bou Taam    schedule 15.02.2018
comment
вместо 15 слушателей.   -  person Hasan Bou Taam    schedule 15.02.2018
comment
@svi.data Я должен сделать это, так как это источник случайных идентификаторов. Как сказано выше, я получаю весь список идентификаторов, а затем выбираю некоторые из них. Однако после этого я должен получить информацию для каждого идентификатора, подключив прослушиватель для каждого из них в узле questions.   -  person Catalin Ghita    schedule 15.02.2018
comment
вы перечисляете (question_ids) в режиме переработчика или в виде списка?   -  person Hasan Bou Taam    schedule 15.02.2018
comment
@svi.data Я не указываю идентификаторы. Мне нужно только получить их, чтобы я мог прикрепить к ним слушателей и, следовательно, получить больше информации по этим вопросам.   -  person Catalin Ghita    schedule 15.02.2018


Ответы (2)


Вы можете использовать классическое решение, как я объяснил в этом ответе но если вы боитесь получить огромное количество данных, используйте вместо этого 15 слушателей. Нет ничего плохого в использовании слушателей, если вы удаляете их в соответствии с жизненным циклом вашей деятельности. Так что, ИМХО, вперед с 15 слушателями.

person Alex Mamo    schedule 16.02.2018
comment
Итак, вы предлагаете 5-е решение, которое я представил? В этом случае, насколько я помню, слушатели Firebase автоматически удаляются в соответствии с определенным жизненным циклом, поэтому нет необходимости удалять (отсоединять) слушатели вручную. - person Catalin Ghita; 16.02.2018
comment
Да, 5-е решение. Нет, они не. Посмотрите здесь, чтобы узнать, где вам нужно удалить слушатель. - person Alex Mamo; 16.02.2018
comment
Я понимаю, и действительно, в этом случае я должен удалить слушателей. Следовательно, нет другого лучшего решения этого вопроса? Спасибо, и я приму ответ. - person Catalin Ghita; 16.02.2018
comment
Вы уже упомянули все способы, которыми можно решить эту проблему. Спасибо. Ваше здоровье! - person Alex Mamo; 16.02.2018

У нас есть 2 случая здесь

случай 1

Если вы хотите получить все детали случайных идентификаторов сразу, я предлагаю 1 прослушиватель для родительского узла (получите значение моментального снимка данных с помощью класса pojo).

случай 2

Если вы хотите получать детали самостоятельно по запросу, вам придется прикрепить прослушиватель к каждому (случайному идентификатору), который вы хотите.

Об эффективности

Попробуйте использовать только прослушиватель для событий с одним значением, поскольку они прослушиваются один раз, а затем останавливаются (лучше для производительности).

Не используйте прослушиватель событий Value (поскольку эти прослушиватели продолжают проверять изменения и, следовательно, снижают производительность по мере увеличения прослушивателей).

ИЗМЕНИТЬ

скажем, вы прослушали узел (questions_ids), теперь у вас есть доступ к случайным ключам идентификатора, сохраните их в переменной String, а затем внутри того же слушателя добавьте еще один слушатель (вопросы), указывающий на идентификатор, который вы хотите получить детали

      //first listen to question ids ref (the one with 15 ids)

       question_ids_ref.addListenerForSingleValueEvent(...{
       //grab the key of each (random id) and store in variable

        String random_01=......;

        //run another listener this time to questions ref

             questions_ref.child(random_01).addListenerForSingleValueEvent(..{

             //get details of random_01 and so on....

         });



       });
person Hasan Bou Taam    schedule 15.02.2018
comment
В случае 1 вы имеете в виду 1 слушателя, прикрепленного к questions? В данном случае это не решает мою проблему. Это попадет в первый представленный мной случай, в котором есть обе проблемы. - person Catalin Ghita; 15.02.2018
comment
случай 1 - это 1 слушатель узла (идентификаторы вопросов) ..... Если вы хотите получить все подробности сразу, если нет, то случай 2. - person Hasan Bou Taam; 15.02.2018
comment
Присоединение слушателя к question_id решает только половину проблемы. Мне все еще нужно получить детали для каждого случайного идентификатора. - person Catalin Ghita; 15.02.2018
comment
тогда используйте класс pojo. - person Hasan Bou Taam; 15.02.2018
comment
Вопросы — это POJO. Но содержание вопросов доступно только в узле questions. Присоединение прослушивателя относится к первой категории (первое решение представлено выше). - person Catalin Ghita; 15.02.2018
comment
В приведенном вами примере показано, как получить информацию об одном случайном идентификаторе. Но первый слушатель получает все случайные идентификаторы, и поэтому представленный вами вложенный слушатель должен получать информацию обо всех случайных ключах. Тем не менее, ваш пример работает только для 1 случайного ключа. Поправьте меня, если не так - person Catalin Ghita; 15.02.2018