Firestore: История версий документов - PullRequest
0 голосов
/ 23 ноября 2018

Я ищу правильный способ структурировать базу данных Firestore для обработки нескольких версий версий документов в одной коллекции.

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

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

collections: offers
 - documents: offer1, (offer2, offer3, ...)
     - fields populated with latest version of the offer content
     - nested collection named history
         - nested documents for each version (v1, v2, v3), which in turn have fields specifing state of each field in that version. 

Это кажется слишком сложным, поскольку у меня последнее состояние и вложенная коллекциядля истории.Может ли это быть как-то в плоской структуре, где последний элемент в массиве является последним состоянием, или что-то подобное.

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

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

Спасибо!

РЕДАКТИРОВАТЬ: Согласно ответу Алекса, вот мой другой взгляд на это.

Firestore-root
   |
   --- offers (collection)
        |
        --- offerID (document)
        |   (with fields populated )
        |        |
        |        --- history (collection) //last edited timestamp
        |            |
        |            --- historyId
        |            --- historyId
        |
         --- offerID (document)
            (with fields populated with latest changes)
                 |
                 --- history (collection) //last edited timestamp
                     |
                     --- historyId
                     --- historyId

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

Я не уверен в денормализации, так как кажется, что это решает мою проблему и позволяет избежать осложнений.

Еще раз, требования: - возможность получать все предложения с последним состоянием (работы) - возможность загружать определенное состояние истории (работы)

Просто каждый раз, когда я обновляю коллекцию истории сВ новом состоянии я перезаписываю поля непосредственно в коллекции offerID тем же самым последним состоянием.

Я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Я могу думать об этом так.Каждый предложение документ будет иметь offerHistoryID в качестве числа.

  • Вы можете иметь отдельную корневую коллекцию для версий документов предложений (скажем, offer_transactions ).
  • Теперь напишите облачную функцию триггера обновления для , которая предлагает документ, который будет иметь значения после и до документа.
  • Перед обновлением документа вы можете записать значения до в offer_transactions вместе с отметкой времени и последним historyID.
  • Увеличьте offerHistoryID на1 для этого предложения и обновите документ с новыми значениями.

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

Мысли?

0 голосов
/ 23 ноября 2018

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

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

Firestore-root
   |
   --- offerId (collection)
        |
        --- offerHistoryId (document)
        |        |
        |        --- //Offer details
        |
        --- offerHistoryId (document)
                 |
                 --- //Offer details

Если вы хотите отобразить все версии истории предложения, требуется один запрос.Так что вам просто нужно присоединить слушателя к коллекции offerId и получить все объекты предложения (документы) за один раз.

Однако, если вы хотите получить только последнюю версию предложения, вам следуетдобавьте под каждым объектом предложения свойство timestamp и запросите базу данных по убыванию.В конце просто позвоните limit(1) и все!

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

Согласно вашему комментарию:

Мне нужночтобы получить список всех предложений с их последними данными

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

Firestore-root
   |
   --- offers (collection)
        |
        --- offerHistoryId (document)
        |        |
        |        --- date: //last edited timestamp
        |        |
        |        --- //Offer details
        |
        --- offerHistoryId (document)
                 |
                 --- date: //last edited timestamp
                 |
                 --- //Offer details

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

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

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

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