Firestore: моделирование данных для приложения отслеживания объектов - PullRequest
0 голосов
/ 11 октября 2018

Это мой первый проект Firestore и NoSQL, и я пытаюсь смоделировать свои данные.

У меня есть несколько объектов (порядка от 500 до 1000), которые физически перемещаются вокругземной шар.Они периодически (примерно раз в день) регистрируются для отправки своего геолокации вместе с некоторыми дополнительными данными.

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

Как мнелучше структурировать мои данные для оптимизации по следующему запросу?Для каждого из тысячи объектов дайте мне последние N мест отслеживания, отсортированных от самых новых до самых старых.Я предполагаю, что N составляет от 100 до 300.

РЕДАКТИРОВАТЬ: Чтобы уточнить, это вернуло бы около 1000 х (от 100 до 300) мест отслеживания.Можно ли это сделать без 1000 запросов (т.е. по одному для каждого из объектов)?

1 Ответ

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

Следующая структура базы данных должна работать для вашего варианта использования.

Firestore-root
   |
   --- drivers (collection)
   |     |
   |     --- driverId (document)
   |     |
   |     --- //other driver details
   |
   --- data (collection)
   |     |
   |     --- driverId (document)
   |           |
   |           --- driverData (collection)
   |                 |
   |                 --- driverDataId (document) //Same object as below
   |                       |
   |                       --- geoPoint: [[48.858376° N, 2.294537° E]]
   |                       |
   |                       --- date: Oct 11, 2018 at 6:16:58 PM UTC+3
   |                       |
   |                       --- driverId: "DriverUserId"
   |                       |
   |                       --- //other extra data
   |
   --- allData (collection)
         |
         --- driverDataId (document) //Same object as above
                |
                --- geoPoint: [[48.858376° N, 2.294537° E]]
                |
                --- date: Oct 11, 2018 at 6:16:58 PM UTC+3
                |
                --- driverId: "DriverUserId"
                |
                --- //other extra data

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

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

data (collection) -> driverId (document) -> driverData (collection) -> driverDataId (document)

и

allData (collection) -> driverDataId (document)

Для всех объектов дайте мне последние N мест отслеживания, отсортированных от самых новых к самым старым.

Чтобы получитьДля всех этих объектов требуется запрос, подобный следующему:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference allDataRef = rootRef.collection("allData");
Query query = allDataRef.orderBy("date", Query.Direction.ASCENDING).limit(n);

Если вы хотите получить также сведения о драйвере, вам нужно сделать дополнительный вызов get(), чтобы вы могли получить его данные.Вы можете добиться этого, используя driverId, существующее как свойство в объекте данных драйвера.

Если вы хотите получить все эти объекты из одного драйвера, вам следует использовать следующий запрос:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference allDataRef = rootRef.collection("data").document(driverId).collecton("driverData");
Query query = allDataRef.orderBy("date", Query.Direction.ASCENDING).limit(n);

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

Кроме того, когда вы дублируете данные, есть одна вещь, которую нужно иметь в виду.Точно так же, как вы добавляете данные, вы должны поддерживать их.Другими словами, если вы хотите обновить / обнаружить элемент, вы должны сделать это в каждом месте, где он существует.

Редактировать:

Согласно вашему комментариюТеперь я понимаю, что вы имеете в виду.В этом случае вы можете рассмотреть allData collection фид, в который вы должны добавить, как видите, объекты данных драйвера.Допустим, что n = 100.Это означает, что каждый раз, когда вы добавляете новый объект после сотого объекта, вам необходимо удалить самый старый.Так что это подразумевает дополнительную операцию удаления.Таким образом, вы будете хранить в этом фиде только 100 объектов определенного пользователя.И да, если у вас 1000 пользователей и у каждого пользователя есть 100 объектов данных, вам нужно будет запросить коллекцию, содержащую 100 тыс. Документов.Поэтому, если вы хотите получить все эти данные одновременно, будет выполнено 100 тыс. Чтений.

Edit2:

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

Firestore-root
   |
   --- drivers (collection)
         |
         --- driverId (document)
         |
         --- //other driver details
         |
         --- driverData (map)
               |
               --- driverDataId (document) //Same object as below
                     |
                     --- geoPoint: [[48.858376° N, 2.294537° E]]
                     |
                     --- date: Oct 11, 2018 at 6:16:58 PM UTC+3
                     |
                     --- driverId: "DriverUserId"
                     |
                     --- //other extra data

Как видите, я изменил коллекцию driverData на map в объекте драйвера.В этом случае вы также должны поддерживать эти 100 объектов на этой карте.В этом случае требуется только 1000 запросов, которые могут вернуть объект данных драйвера 100 КБ.Но обратите внимание, проблема в том, что документы имеют пределы.Таким образом, существуют некоторые ограничения в отношении объема данных, которые вы можете поместить в документ.В соответствии с официальной документацией относительно использования и ограничений :

Максимальный размер документа: 1 МБ (1 048 576 байт)

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

...