Как лучше всего это сделать?
Я знаю, что все ищут решение best , но в мире баз данных NoSQL существует no лучшее решение. Есть много способов, которыми вы можете смоделировать базу данных для приложения, подобного вашему, и иметь тот же результат, и я объясню вам почему. Перед этим, пожалуйста, посмотрите на мой ответ из этого поста , чтобы лучше понять концепцию «идеального», «лучшего» или «правильного» решения в случай базы данных NoSQL.
Лучшее решение - шутить :). Рекомендованный способ получения списка избранных функций, который вы ищете, - использовать arrays
. Ваша схема базы данных может выглядеть так:
Firestore-root
|
--- users (Collection)
| |
| --- uid (document)
| |
| --- favoriteLocations: ["favoriteLocationId", "favoriteLocationId"]
|
--- locations (Collection)
|
--- locationId (document)
|
--- //Location details
Как видите, массив favoriteLocations
содержит только идентификаторы местоположения. Таким образом, чтобы получить информацию о местоположении, вы должны получить эти идентификаторы и сделать дополнительную базу данных get()
вызов.
Другой подход - вместо хранения массива идентификаторов местоположения хранить массив карт или массив объектов местоположения. Эта опция отлично работает, если у вас есть разумное количество избранных мест, скажем, 5, 10 или даже 50, но не 500. Если вам нужно сохранить 500 местоположений, по какой причине вы будете хранить место как любимое?
В этом случае следует помнить, что документы имеют ограничения . Таким образом, существуют некоторые ограничения в отношении объема данных, которые можно поместить в документ. Согласно официальной документации относительно использования и ограничений :
Максимальный размер документа: 1 МБ (1 048 576 байт)
Как вы можете видеть, вы ограничены суммой в 1 МБ данных в одном документе. Когда мы говорим о хранении текста, вы можете хранить его в значительной степени, но по мере увеличения массива будьте осторожны с этим ограничением.
Если вы хотите хранить больше данных, чем позволяет хранить один документ, вам следует использовать коллекции. Таким образом, вы можете создать вложенную коллекцию под каждым пользовательским объектом, который будет содержать в качестве документов объекты местоположения. Структура вашей базы данных должна выглядеть примерно так:
Firestore-root
|
--- users (Collection)
| |
| --- uid (document)
| |
| --- favoriteLocations (Collection)
| |
| --- favoriteLocationId (document)
| |
| --- //Location details
|
--- locations (Collection)
|
--- locationId (document)
|
--- //Location details
Чтобы запросить базу данных, которая выглядит следующим образом, используйте следующие строки кода:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("users").document(uid).collection(favoriteLocations);
favoriteLocationsRef.get(/* ... */);
Другой подход заключается в деномализации ваших данных и создании вашей подколлекции favoriteLocations
в виде коллекции верхнего уровня, подобной этой:
Firestore-root
|
--- users (Collection)
| |
| --- uid (document)
| |
| --- //User details
|
--- locations (Collection)
| |
| --- locationId (document)
| |
| --- //Location details
|
--- favoriteLocations (Collection)
|
--- uid (document)
|
--- userFavoriteLocations (collection)
|
--- favoriteLocationId (document)
|
--- //Location details
Соответствующий запрос должен выглядеть следующим образом:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("favoriteLocations").document(uid).collection(userFavoriteLocations);
favoriteLocationsRef.get(/* ... */);
Или еще более простой способ:
Firestore-root
|
--- users (Collection)
| |
| --- uid (document)
| |
| --- //User details
|
--- locations (Collection)
| |
| --- locationId (document)
| |
| --- //Location details
|
--- favoriteLocations (Collection)
|
--- locationId (document)
|
--- uid: "uid"
|
--- //Other location details
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("favoriteLocations").whereEqualTo("uid", uid);
favoriteLocationsRef.get(/* ... */);
Как видите, я добавил uid пользователя в качестве свойства объекта местоположения, чтобы вы могли просто получить все избранные местоположения, которые есть у конкретного пользователя.
Вам решать, какое решение будет "лучшим" для вашего варианта использования приложения:)
PS Пожалуйста, также посмотрите на мой ответ из этого поста , где я объяснил больше о collections
, maps
и arrays
в Firestore.