То есть копирование одного узла под другой
Мы находимся в середине реализации хранилища событий на нашем бэкэнде Firebase (черпая вдохновение из commanded/eventstore Бена Смита и EventStore Грега Янга), и на этом этапе необходим механизм моментальных снимков.
(Позже я нашел суть, на которую стоит обратить внимание: https://gist.github.com/katowulf/6099042)
Добавление некоторых образцов данных
После настройки Firebase и запуска Node REPL на консоли:
> const path_ref = firebase_admin.database().ref("main"); > "the cake is a lie".split(" ").forEach( function(word) { path_ref.child("topics").child(word).set({ length: word.length }) });
и правильно написать:
"the cake is a lie".split(" ").forEach( function(word) { path_ref.child("topics").child(word).set({length: word.length}) });
Это создаст такую структуру:
Создать снимок (т. е. скопировать путь под другим)
> path_ref.once("value").then(function(dataSnapshot) { path_ref.child("snapshots").push(dataSnapshot.val())});
Приведение в порядок:
path_ref.once("value").then( function(dataSnapshot) { path_ref.child("snapshots").push(dataSnapshot.val()) });
Это приведет к следующему:
once("value")
берет все содержимое path_ref
(которое на данный момент /main
) и возвращает Promise
с DataSnapshot
. Мы добавили дочерний путь моментальные снимки и добавили значение моментальных снимков данных под уникальным идентификатором (с push()
).
Прелесть этого решения в том, что скопированный путь может быть сколь угодно глубоким и содержать вложенные объекты.
Предостережение
Вызов той же функции, что и выше, теперь потребует как topics
, так и snapshots
! ( val()
возвращает все, что находится под путем). Следующее решение работает каждый раз, когда можно было бы ожидать, и копирует только выбранные пути:
> path_ref.once("value").then(function(dataSnapshot) { dataSnapshot.forEach(function(child){ if (child.key === "topics") { path_ref.child("snapshots").push(child.val())}})});
or
path_ref.once("value").then( function(dataSnapshot) { dataSnapshot.forEach( function(child){ if (child.key === "topics") { path_ref.child("snapshots").push(child.val()) } }); });
Результат после вызова дважды подряд: