Отменить повтор для огромного объекта - PullRequest
0 голосов
/ 10 октября 2019

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

В настоящее время у меня есть огромный Объект, который происходит из одной коллекции Монго.

Псевдоструктура:

{
  cart:{
    products:[
      {
        name: "Watch",
        quantity: 1,
        shippingDate: 123456782,
        text: "lorem ipsum....",
        prices:[
          {
            currency: "USD",
            price: 300
          },
          {
            currency: "GBP",
            price: 220
          }
        ]
      }
    ],
    ...someMoreKeyValuePair
  }
}

Теперь обновление может происходить на любом узле, например: добавление / изменение / удаление товара, добавление / изменение / удаление данных уровня корзины.

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

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

Обновление:

необходимо отменить повторное выполнение в БД. И язык, который я использую, это Javascript-NodeJS

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Вы должны будете вести журнал изменений. Таким образом, клиентский запрос, с которым работает ваше серверное приложение (nodejs), должен быть преобразован в действия db, которые оба регистрируют изменение (как отмена журнала) и выполняют его в одной транзакции.

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

Запись в таком журнале отмены будет содержать от 3 до 4 элементов:

  1. действие: «обновить», «вставить» или «удалить». Последние два в основном предназначены для представления манипуляций с массивами.
  2. путь, чтобы определить, где в объекте должно применяться изменение. Этот путь будет массивом свойств, которые, например, могут быть закодированы как строка, разделенная точками.
  3. старое значение в этом месте (в случае «обновления» или «удаления»), закодировано в JSON.
  4. новое значение в этом месте (в случае «обновления» или «вставки»"), Закодировано в JSON.

Примеры таких записей:

  • ("update", "cart.products.0.name", '"Watch"', '"Watching"')
  • ("delete", "cart.products.prices.1", '{"currency":"GBP","price":220}', null): это представляет действие, в котором старое значениеудаляется из индекса 1 массива prices. Пробел заполняется смещением значений массива, подобно операции splice(index, 1) в JavaScript.
  • ("insert", "cart.products.prices.0", null, '{"currency":"EUR","price":270}'): это представляет действие, в котором новое значение вставляется в индекс 0 в массиве prices. Если этот индекс уже имеет значение, он смещается вправо, как операция splice(index, 0, newvalue) в JavaScript.

Значения null просто указывают, что этот параметр не имеет отношения к данному конкретному действию.

В приведенном выше примере журнала будут собраны следующие данные, начиная с приведенных вами примеров:

{
  cart:{
    products:[
      {
        name: "Watching",
        quantity: 1,
        shippingDate: 123456782,
        text: "lorem ipsum....",
        prices:[
          {
            currency: "EUR",
            price: 270
          },
          {
            currency: "USD",
            price: 300
          }
        ]
      }
    ]
  }
}

Такой журнал, как все для отмены действия: если данные былиуничтожен («обновить», «удалить»), вы можете восстановить уничтоженные данные из третьего параметра.

0 голосов
/ 10 октября 2019

Например, вы можете использовать deep-diff .

deep-diff - это модуль javascript / node.js, предоставляющий вспомогательные функции для определения структурных различий между объектами ивключает некоторые утилиты для применения различий между объектами.

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

const change = diff(oldValue, newValue);

Чтобы применить разность:

applyChange(target, source, change);

jsondiffpatch - еще один вариант. Если вы используете Mongoose, вы можете реализовать плагин для управления изменениями или использовать существующий: mongoose-diff-history

...