Количество баз Firebase

Поддерживает ли Firebase групповой подсчет?
Я хотел бы получить счет для конкретного ключа, сгруппированного по значению.

Пример моей структуры данных:

"playbackPosition" : {
    "-JZ2c7v-imQXaEx2c4Cs" : {
        "data" : "0"
    },
    "-JZ2cDta73UGAgwIOejL" : {
        "data" : "25"
    },
    "-JZ2cJutDZu-7quLpLI2" : {
        "data" : "50"
    },
    "-JZ2cO-Me0nGK5XLTwd-" : {
        "data" : "75"
    },
    "-JZ2cSh-XnstYxbE_Zad" : {
        "data" : "100"
    },
    "-JZ2cWxya0-kmTPCze4u" : {
        "data" : "0"
    },
    "-JZ2c_wX-ODv43TKXkNG" : {
        "data" : "25"
    }
}

Требуемые результаты на основе data ключ:

0 => 2  
25 => 2  
50 => 1  
75 => 1  
100 => 1

И конечно надо учитывать, что на нем будут тысячи детей, а не только 7...

Спасибо вперед!

РЕДАКТИРОВАТЬ
Более глубокое объяснение приложения и проблемы, которую мы хотим решить.

У нас есть видео-скрипты, которые запускаются на разных веб-сайтах, каждый видео сеанс (сеанс пользователя) отправляет события и данные, вы можете увидеть пример здесь, перейдите на вкладку Сеть - https://secure.bwebi.co/videostir/regular.html

Наша цель - собрать эти данные и создать аналитическую панель в реальном времени с несколькими диаграммами и графиками.

Вы можете увидеть нашу текущую структуру данных здесь

Пример для графиков нам нужен:
Степень завершенности
Общее - Гистограмма, показывающая общее количество просмотров за длительность клипа предварительно определенных периодов.
Фильтры - дата (начало / конец), уникальные / все, все URL / конкретные URL (встроенные), все конфигурации / конкретные конфигурации / игнорировать без вывода сообщений.
Ось X - группы 0-25, 25-50,50-75,75-99, 100
Ось Y - количество просмотров

Количество просмотров в день (с коэффициентом завершения)
Общее - Многострочный график, показывающий количество просмотров в день за периоды продолжительности.
Фильтры - дата (начало / конец), уникальные / все, все URL / конкретные URL (встроенные), все конфигурации / конкретные конфигурации / игнорировать без вывода сообщений.
Ось X - время в днях
Ось Y - Количество просмотров
Линии для:
Всего просмотров за день
Ежедневные просмотры со 100% продолжительностью
Ежедневные просмотры с продолжительностью 75-99%
Ежедневные просмотры с продолжительностью 50-75%
Ежедневные просмотры с продолжительностью 25-50%
Ежедневные просмотры с продолжительностью 0-25%

Надеюсь, теперь все понятно!

2 ответа

Решение

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

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

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

Сохраните итоги

Это самое масштабируемое решение. Сохраните ваши данные следующим образом:

/playbacks/$id/<playback data>
/group_totals/$group/<count>

При записи на воспроизведение также обновите счет для соответствующей группы:

var fb = new Firebase(URL);
function addPlayback(rec) {
   var ref = fb.child('playbacks').push(rec, function(err) {
      if( err )  throw err;
      incrementCount(rec.data);
   });
}

function incrementCount(count) {
   fb.child('group_totals/' + count).transaction(function(currentVal) {
     return (currentVal||0)+1;
   });
}

Теперь, когда вы хотите получить общее значение для группы, вы можете просто посмотреть значение в group_totals/$group. Точно так же вы можете хранить идентификаторы для записей, которые принадлежат каждой группе, и использовать этот индекс для захвата только записей для данной группы.

Используйте приоритеты для извлечения и группировки

Более простой подход - дать каждой записи приоритет на основе значения группы / данных.

var fb = new Firebase(URL);
function addPlayback(rec) {
   rec['.priority'] = rec.data;
   var ref = fb.child('playbacks').push(rec, function(err) {
      if( err )  throw err;
   });
}

Теперь, чтобы получить набор записей для данной группы:

var fb = new Firebase(URL);
function getGroup(groupValue, callback) {
   fb.child('playbackPosition').startAt(groupValue).endAt(groupValue).once('value', callback);
}

function logGroupCount(groupValue, callback) {
   getGroup(groupValue, function(snap) {
       console.log('there are ' + snap.numChildren() + ' items in group ' +groupValue);
   });
}

Я не профессиональный программист, я только учусь. Вот фрагмент кода, который я придумал, когда хотел сгруппировать результаты своего запроса:

       btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                progressBar.setVisibility(View.VISIBLE);
                tv_info.setText("Please wait ... ");

                Query query = collectionRef.orderBy("timestamp", Query.Direction.DESCENDING);

                query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        String dataInfo = "";
                        int arrayLength = 1;
                        List <String> UsedNames = new ArrayList<String>();
                        String someName = "...";

                        String oneRow = "";
                        int orderNumber = -1;
                        int count = 0;

                        for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                            OneRecord oneRecord = documentSnapshot.toObject(OneRecord.class);
                            someName = oneRecord.getSomeName();

                            if (UsedNames.contains(someName)) {
//                                Log.i("test" , "Array Contains ");
                            } else {
                                orderNumber += 1;
                                UsedNames.add(someName);

                            }

                   }

                        List list = queryDocumentSnapshots.toObjects(OneRecord.class);


                        for (String someString : UsedNames) {

                            int counter = 0;
                            for (int i = 0; i < list.size(); i++) {
                                OneRecord oneRecord = (OneRecord) list.get(i);
                                String name = oneRecord.getName();

                                if (someString.equals(name)) {
                                    counter += 1;
                                }
                            }
                            Log.i("test" , "Array: " + someString + " : " + counter);
                            count = count +1;
                            dataInfo = dataInfo + someString + " : " + counter + "\n";

                        }



                        Log.i("test" , "Used length: " + UsedNames.size());


                        progressBar.setVisibility(View.GONE);
                        tv_info.setText(dataInfo);


                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        progressBar.setVisibility(View.GONE);
                        tv_info.setText("Could not query last records: " + e.getMessage());
                    }
                });


            }
        });

К сожалению, я не понял, как их отсортировать по убыванию или по возрастанию.

Другие вопросы по тегам