Создайте новый корневой узел с 10 лучшими пользователями - PullRequest
0 голосов
/ 25 октября 2018

У меня есть следующая функция, которая ранжирует пользователей в моей таблице mobile_user по eanred_points и присваивает им ранг.Это делается каждый раз, когда я вызываю триггер http-запроса.

Я хотел бы создать еще один корневой узел, называемый таблицей лидеров, который помещает в него только 10 лучших пользователей.

Моя текущая функция выглядит следующим образом:

    exports.leaderboardUpdate2 = functions.https.onRequest((req, res) =>{
  var ref = admin.database().ref("/mobile_user");
    ref.orderByChild("earned_points").once("value", function(dataSnapshot) {
        var i = 0;
        dataSnapshot.forEach(function(childSnapshot) {
          var childRef = childSnapshot.ref;
          var r = (dataSnapshot.numChildren() - i);
          childRef.update({rank: r},function(error) {
              if (error != null)
                console.log("update error: " + error);
          });
          i++;
        });
    });
    res.status(200).send("Updated mobile users ranks");
});

Как мне пойти и сделать это?Приветствуется любая помощь или совет.

Редактировать: моя структура таблицы mobile_user выглядит следующим образом: enter image description here

1 Ответ

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

Я бы, вероятно, сделал что-то вроде этого:

const LEADERBOARD_CUTOFF = 10;

exports.leaderboardUpdate2 = functions.https.onRequest((req, res) =>{
  const updates = [];
  const leaderboard = {};

  const ref = admin.database().ref("/mobile_user");
  const leaderboardRef = admin.database().ref("/leaderboard");

  return ref.orderByChild("earned_points").once("value")
    .then(dataSnapshot => {
      let i = 0;
      dataSnapshot.forEach(function(childSnapshot) {
        const r = dataSnapshot.numChildren() - i;
        updates.push(childSnapshot.ref.update({rank: r}));
        if (r < LEADERBOARD_CUTOFF) {
          leaderboard[childSnapshot.key] = Object.assign(childSnapshot.val(), {rank: r});
        }
        i++;
      });

      updates.push(leaderboardRef.set(leaderboard)));
      return Promise.all(updates);
    }).then(() => {
      res.status(200).send("Updated mobile users ranks");
    }).catch((err) => {
      console.error(err);
      res.status(500).send("Error updating ranks.");
    });
});

Отличия от исходного сценария:

  1. Обновления объединяются в массив, и ответ удерживается до тех пор, пока они не будутполный.На самом деле, вы, скорее всего, в конечном итоге будете иметь ошибки, так как функция будет блокировать ЦП / сеть при отправке HTTP-ответа, и некоторые ваши обновления не пройдут.
  2. A leaderboard objectсоздается и заполняется соответствующим образом по мере выполнения итерации.Это set() для соответствующей ссылки в качестве окончательного обновления функции.
  3. Обещания используются повсеместно (о них гораздо проще рассуждать).
...