Firestore: как хранить данные на пользовательских и глобальных уровнях с расчетами? - PullRequest
0 голосов
/ 22 октября 2018

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

Например, допустим, вы создаете приложение для гоночного автомобиля, в котором среднее время прохождения трассы записывается для конкретного пользователя, но вы также хотите использовать среднее время этого пользователя для сравнения со средним глобальным значением этого пользователя.location.

Установка, о которой я думаю, выглядит следующим образом:

Глобальные данные Firestore

{
  Location: France,
  globalAverageTime: 6 minutes,
  numberOfParticipants: 2
}

Данные Firestore пользователя

[
 {
   username: "firstuser",
   location: France
   time: 8 minutes
 },
 {
  username: "seconduser",
  location: France
  time: 4 minutes
 }
]

Итак, каков наилучший способ размещения всех данных такого типа?Таким образом, каждый раз, когда пользователь обновляет свое личное среднее время на трассе, вычисляется новое глобальное среднее значение на основе местоположения этого пользователя и нового времени.Так, например, в приведенном выше примере во Франции есть два «числа участников»: один с 8 минутами, а другой с 4 минутами, поэтому среднее время составляет 6 минут на трассе для этого региона.

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

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

Ответы [ 2 ]

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

ИМХО, вы можете сохранить структуру базы данных как есть.И чтобы ответить на ваши вопросы:

Для запуска подобной системы лучше всего было бы использовать облачные функции, которые запускают вычисления после каждого обновления пользовательских данных, а затем обновляют глобальные данные?

Лучшее решение - использовать облачную функцию, потому что вы можете вычислить эти числа на стороне сервера.Таким образом, вы сможете автоматически запускать внутренний код в ответ на события, вызванные функциями Firebase и HTTPS-запросами.В вашем конкретном случае вы должны изменять свойство globalAverageTime, только если изменяется одно из свойств time в этих двух пользовательских объектах.

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

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

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

Интересный вопрос!Я думаю, что subcollections может быть ответом здесь.

Вы можете атаковать проблемы несколькими различными способами.Но первое, что приходит на ум, это:

Рассмотрим следующие коллекции верхнего уровня:

  • Пользователи
  • Треки

Коллекция 'users' содержит треки, управляемые пользователем следующим образом:

-- Users
   -- user_1
      -- tracks (object)
         -- track_1: true (could also be a float instead of boolean, representing the completion time for the user)
         -- track_2: true
         -- track_5: true

Затем в коллекции 'track' у вас есть следующее:

-- Tracks
   -- track_1
      -- location
      -- globalAverageTime
      -- numberOfParticipants

      -> 'users' (subcollection)
          -- user_1 (document)
             -- completionTime: 6.43

Таким образом, вы можетеВы должны запускать функцию каждый раз, когда в треки записывается новый документ -> пользовательская подколлекция и обновляется посредством транзакции.

РЕДАКТИРОВАТЬ Чтобы ответить на ваш вопрос о наличии большого количества пользователей в подколлекции треков:Если вы извлечете свою коллекцию / track / track_1, она будет , а не , чтобы получить коллекцию пользователей.Вы должны специально выбрать эту подколлекцию для извлечения этих данных, это означает, что вы можете легко извлечь дорожку или несколько дорожек, не выбирая также всех пользователей.

Вы можете прочитать о транзакциях здесь .

Из документов:

Используя клиентские библиотеки Cloud Firestore, вы можете сгруппировать несколько операций в одну транзакцию.Транзакции полезны, когда вы хотите обновить значение поля на основе его текущего значения или значения какого-либо другого поля.Вы можете увеличить счетчик, создав транзакцию, которая считывает текущее значение счетчика, увеличивает его и записывает новое значение в Cloud Firestore.

Таким образом, у вас может быть функция, наблюдающая /tracks/{track_id}/users/{user_id}, гдекаждый раз, когда пользователь завершает трек и устанавливает время, вы обновляете трек с новым средним значением

...