Как установить внешние ключи в Firestore?

В качестве примера представьте приложение для электронной коммерции, в которое пользователь может загружать столько же элементов, что и у этих элементов есть категории и подкатегории.

Как установить user_id в качестве внешнего ключа в каждом опубликованном элементе, а также item_id в коллекции пользователей, чтобы запрашивать все элементы, отправленные определенным пользователем.

Как мы можем использовать ссылочный тип данных в Firestore для установки внешних ключей?

Есть ли другие способы установки внешних ключей?

Структура базы данных:

Users/doc_id/name..

Categories/fashion/clothing/auto_doc_id/type:denims
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
10
0
12 591
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Допустим, у вас есть товар в магазине / {shop_id} в виде документа, в котором есть поле ссылки, указывающее на пользователя / {user_id}. Чтобы установить эту ссылку программно:

FirebaseFirestore firestore = FirebaseFirestore.getInstance();
DocumentReference userRef = firestore.collection("user").document({user_id});
Map<String, Object> map = new HashMap<>();
map.put("user", userRef);
firestore.collection("shop").document({shop_id}).update(map);

Чтобы получить этого пользователя, вы можете:

firestore.collection("shop").document({shop_id}).addSnapshotListener(this, (shopItemSnapshot, e) -> {
    // Get the shopItem here
    // ShopItem shopItem = shopItemSnapshot.toObject(ShopItem.class);
    ((DocumentReference) shopItemSnapshot.get("user")).addSnapshotListener((userSnapshot, e1) -> 
        // Get the user from the shopItem document
        User user = userSnapshot.toObject(User.class);
    });
});

Чем это лучше, чем хранить идентификатор документа в качестве ссылки?

Shahood ul Hassan 29.09.2019 14:33

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

Это из моего проекта, у меня есть, например, узел, который нравится, каждый лайк - это кнопка нажатия, и внутри этой кнопки у меня есть идентификатор пользователя каждого пользователя, которому понравился пост, сообщение представлено с помощью pushKey

Теперь у меня есть еще один узел, который называется users, и внутри вы можете увидеть мой идентификатор пользователя.

Как видите, у меня есть тот же идентификатор пользователя в моем узле users, что и в моем узле Like.

Так что я бы сделал это

  • Я храню все данные в пользователях (с идентификатором пользователя в качестве основного узла pk)
  • Когда мне нравится сообщение, я запрашиваю идентификатор пользователя, которому понравился, подтягиваю его и сохраняю в моем узле «Нравится».

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

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

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

Привет, Гастон. Отличное объяснение того, как это сделать в базе данных Firebase Realtime. Но OP спрашивает о Cloud Firestore (более новая база данных от Firebase), которая имеет определенный тип данных для ссылки на другие документы (что, к сожалению, у меня еще не было возможности попробовать).

Frank van Puffelen 03.06.2018 01:38

@ GastónSaillén Спасибо за ваше объяснение. Но я использую firestore. У меня появилась идея, как настроить внешние ключи, но я хочу опробовать ссылочный тип данных firestore для установки внешних ключей. .

jhashane 03.06.2018 05:50
Ответ принят как подходящий

in order to query all the items posted by a specific user.

Для этого нет необходимости устанавливать user_id в качестве внешнего ключа в каждом опубликованном элементе, а также item_id в коллекции пользователей. Вы можете только добавить новое свойство к объекту элемента с именем postedBy, которое будет содержать в качестве значения идентификатор пользователя. Чтобы отобразить только элементы определенного пользователя, вам нужно запросить базу данных, используя следующий код:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference itemsRef = rootRef.collection("items");
Query query = itemsRef.whereEqualTo("postedBy", user_id);

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

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

Firestore-root
     |
     --- users (collecton)
          |
          --- userId (document)
                 |
                 --- userItems (collecton)
                        |
                        --- itemId (document)

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

Да, уже используется тот же первый метод, который включает в себя установку user_id в новом поле вместе с добавляемыми элементами. Большое спасибо за ваше ясное объяснение. Но знаете ли вы, как использовать ссылочный тип данных? Я просто из любопытства.

jhashane 05.06.2018 14:35

Пожалуйста! Как и в официальный документ, вы можете использовать ссылку в этой строке: projects/[PROJECT_ID]/databases/[DATABASE_ID]/documents/[DOC‌​UMENT_PATH].

Alex Mamo 05.06.2018 14:37

Если вы считаете, что мой ответ вам помог, примите его. Спасибо!

Alex Mamo 05.06.2018 14:37

Спасибо @Alex. Я думал, есть ли другой метод использования ссылочного типа данных для установки и запроса. В любом случае, спасибо

jhashane 05.06.2018 14:40

Другие вопросы по теме