Firebase Realtime DB: упорядочить результаты запроса по количеству значений для ключа - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть база данных Firebase Web Realtime с пользователями, у каждого из которых есть атрибут jobs, значение которого является объектом:

{
  userid1:
    jobs:
      guid1: {},
      guid2: {},
  userid2:
    jobs:
      guid1: {},
      guid2: {},
}

Я хочу запросить, чтобы n пользователей получили наибольшее количество рабочих мест. , Есть ли трюк упорядочения, который я могу использовать, чтобы упорядочить пользователей по количеству значений, которые данный пользователь имеет в их атрибуте jobs?

Я специально не хочу хранить целое число количества заданий у каждого пользователя есть, потому что мне нужно обновить атрибут jobs пользователей как часть обновлений atomi c, которые обновляют другие атрибуты пользователей одновременно и атомарно, и я не верю, что транзакции (например, увеличивающие / уменьшающие счетчики) могут быть частью из этих транзакций атома c.

Вот пример обновления атома c, которое я делаю. Примечание. У меня нет пользователя, которого я изменяю в памяти, когда запускаю следующее обновление:

firebase.database().ref('/').update({
  [`/users/${user.guid}/pizza`]: true,
  [`/users/${user.guid}/jobs/${job.guid}/scheduled`]: true,
})

Любые предложения по шаблонам, которые будут работать с этими данными, будут чрезвычайно полезны!

1 Ответ

2 голосов
/ 04 февраля 2020

Транзакции базы данных реального времени выполняются на одном узле в дереве JSON, поэтому было бы довольно сложно интегрировать обновление узла jobCounter в ваше обновление атома c для нескольких узлов (т. Е. До /users/${user.guid}/pizza). и /users/${user.guid}/jobs/${job.guid}/scheduled). Нам нужно обновить на уровне /users/${user.guid} и вычислить значение счетчика и т. Д. c ...

Более простой подход - использовать облачную функцию для обновления пользовательского узла jobCounter каждый раз, когда есть изменение одного из jobs узлов, что подразумевает изменение в счетчике. Другими словами, если новый узел задания добавляется или удаляется, счетчик обновляется. Если существующий узел только изменен, счетчик не обновляется, поскольку количество заданий не изменилось.

exports.updateJobsCounter = functions.database.ref('/users/{userId}/jobs')
    .onWrite((change, context) => {

        if (!change.after.exists()) {

            //This is the case when no more jobs exist for this user

            const userJobsCounterRef = change.before.ref.parent.child('jobsCounter');
            return userJobsCounterRef.transaction(() => {
                return 0;
            });

        } else {

            if (!change.before.val()) {

                //This is the case when the first job is created

                const userJobsCounterRef = change.before.ref.parent.child('jobsCounter');
                return userJobsCounterRef.transaction(() => {
                    return 1;
                });

            } else {

                const valObjBefore = change.before.val();
                const valObjAfter = change.after.val();

                const nbrJobsBefore = Object.keys(valObjBefore).length;
                const nbrJobsAfter = Object.keys(valObjAfter).length;

                if (nbrJobsBefore !== nbrJobsAfter) {
                    //We update the jobsCounter node
                    const userJobsCounterRef = change.after.ref.parent.child('jobsCounter');
                    return userJobsCounterRef.transaction(() => {
                        return nbrJobsAfter;
                    });
                } else {
                    //No need to update the jobsCounter node
                    return null;
                }

            }

        }

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