Sposoby implementacji wersjonowania danych w MongoDB

Czy możesz podzielić się swoimi przemyśleniami, jak zaimplementowałbyś wersjonowanie danych w MongoDB? (Zadałem podobne pytanie dotyczące Cassandry . Jeśli masz jakieś przemyślenia, które db jest lepsze do tego, podziel się)

Załóżmy, że potrzebuję wersji rekordów w prostej książce adresowej. (Rekordy Książki adresowej są przechowywane jako płaskie obiekty json). Oczekuję, że historia:

  • będzie używany rzadko
  • zostaną użyte jednocześnie, aby zaprezentować je w " wehikule czasu" Moda
  • Nie będzie więcej wersji niż kilkaset na jednej płycie. historia nie wygaśnie.

Rozważam następujące podejścia:

  • Utwórz nową kolekcję obiektów do przechowywania historii rekordów lub zmian w rekordach. Przechowywałby jeden obiekt na wersję z odniesieniem do wpisu książki adresowej. Takie zapisy wyglądałyby następująco:

    {
     '_id': 'new id',
     'user': user_id,
     'timestamp': timestamp,
     'address_book_id': 'id of the address book record' 
     'old_record': {'first_name': 'Jon', 'last_name':'Doe' ...}
    }
    

    To podejście można zmodyfikować, aby przechowywać tablicę wersji dla każdego dokumentu. Ale to wydaje się być wolniejsze podejście bez żadnych zalet.

  • Przechowuje wersje jako obiekt serialized (JSON) dołączony do wpisów książki adresowej. Nie jestem pewien, jak dołączyć takie obiekty do dokumentów MongoDB. Być może jako tablica ciągów. (wzorowane na prostej wersji dokumentu z CouchDB)

Author: Community, 2010-11-15

9 answers

Pierwszym dużym pytaniem przy tym nurkowaniu jest "jak chcesz przechowywać zestawy zmian"?

  1. Diffs?
  2. Całe kopie płyt?

Moim osobistym podejściem byłoby przechowywanie różnic. Ponieważ wyświetlanie tych diffów jest naprawdę specjalnym działaniem, umieściłbym diffy w innej kolekcji "historii".

Użyłbym innej kolekcji, aby zaoszczędzić miejsce w pamięci. Zazwyczaj nie chcesz pełnej historii dla prostego zapytania. Tak więc zachowując historia poza obiektem można również zachować ją poza powszechnie dostępną pamięcią, gdy dane są odpytywane.

Aby ułatwić sobie życie, chciałbym zrobić dokument historii zawierający słownik znaczników czasu diffs. Coś takiego:

{
    _id : "id of address book record",
    changes : { 
                1234567 : { "city" : "Omaha", "state" : "Nebraska" },
                1234568 : { "city" : "Kansas City", "state" : "Missouri" }
               }
}

Aby moje życie było naprawdę łatwe, zrobiłbym tę część moich obiektów DataObjects (EntityWrapper, cokolwiek), których używam, aby uzyskać dostęp do moich danych. Ogólnie rzecz biorąc, obiekty te mają pewną formę historii, dzięki czemu można łatwo nadpisać metodę save(), aby to zrobić zmiana w tym samym czasie.

Aktualizacja: 2015-10

Wygląda na to, że istnieje teraz spec do obsługi diffów JSON. Wydaje się to bardziej solidnym sposobem przechowywania różnic / zmian.

 133
Author: Gates VP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-27 18:16:27

Istnieje schemat wersjonowania zwany "Vermongo", który odnosi się do niektórych aspektów, które nie zostały omówione w innych odpowiedziach.

Jednym z tych problemów jest jednoczesna aktualizacja, innym jest usuwanie dokumentów.

Vermongo przechowuje kompletne kopie dokumentów w kolekcji cieni. W niektórych przypadkach może to spowodować zbyt duże koszty, ale myślę, że upraszcza to również wiele rzeczy.

Https://github.com/thiloplanz/v7files/wiki/Vermongo

 27
Author: Marian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-16 12:27:23

Oto inne rozwiązanie wykorzystujące jeden dokument dla bieżącej wersji i wszystkich starych wersji:

{
    _id: ObjectId("..."),
    data: [
        { vid: 1, content: "foo" },
        { vid: 2, content: "bar" }
    ]
}

data zawiera wszystkie wersje. Tablica data jest uporządkowana , nowe wersje otrzymają tylko $pushed na koniec tablicy. {[9] } jest identyfikatorem wersji, który jest liczbą zwiększającą.

Pobierz najnowszą wersję:

find(
    { "_id":ObjectId("...") },
    { "data":{ $slice:-1 } }
)

Pobierz konkretną wersję przez vid:

find(
    { "_id":ObjectId("...") },
    { "data":{ $elemMatch:{ "vid":1 } } }
)

Return only specified pola:

find(
    { "_id":ObjectId("...") },
    { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
)

Wstawianie nowej wersji: (i zapobieganie równoczesnemu wstawianiu/aktualizowaniu)

update(
    {
        "_id":ObjectId("..."),
        $and:[
            { "data.vid":{ $not:{ $gt:2 } } },
            { "data.vid":2 }
        ]
    },
    { $push:{ "data":{ "vid":3, "content":"baz" } } }
)

2 jest vid aktualnej najnowszej wersji i {[13] } jest wstawiana nowa wersja. Ponieważ potrzebujesz najnowszej wersji vid, łatwo jest uzyskać następną wersję vid: nextVID = oldVID + 1.

Warunek $and zapewni, że 2 jest ostatnim vid.

W ten sposób nie ma potrzeby posiadania unikalnego indeksu, ale aplikacja logika musi dbać o zwiększenie vid na insert.

Usuń konkretną wersję:

update(
    { "_id":ObjectId("...") },
    { $pull:{ "data":{ "vid":2 } } }
)
To jest to!

(zapamiętaj limit 16MB na dokument)

 14
Author: Benjamin M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-14 17:53:04

Jeśli szukasz gotowego rozwiązania -

Mongoid ma wbudowane proste wersjonowanie

Http://mongoid.org/en/mongoid/docs/extras.html#versioning

Mongoid-history to wtyczka Ruby, która zapewnia znacznie bardziej skomplikowane rozwiązanie z audytowaniem, cofaniem i powtarzaniem

Https://github.com/aq1018/mongoid-history

 11
Author: s01ipsist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-13 09:03:11

Pracowałem nad tym rozwiązaniem, które uwzględnia opublikowaną, szkicową i historyczną wersję danych:

{
  published: {},
  draft: {},
  history: {
    "1" : {
      metadata: <value>,
      document: {}
    },
    ...
  }
}

Model wyjaśniam dalej tutaj: http://software.danielwatrous.com/representing-revision-data-in-mongodb/

Dla tych, którzy mogą zaimplementować coś takiego w Java , Oto przykład:

Http://software.danielwatrous.com/using-java-to-work-with-versioned-data/

Łącznie z całym kodem, który możesz rozwidlić, jeśli lubisz

Https://github.com/dwatrous/mongodb-revision-objects

 7
Author: Daniel Watrous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-09 15:42:06

Jeśli używasz mongoose, znalazłem następujący plugin jako przydatną implementację formatu JSON Patch

Mangusta-patch-Historia

 2
Author: bmw15,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-10 16:10:51

Inną opcją jest użycie wtyczki mongoose-history .

let mongoose = require('mongoose');
let mongooseHistory = require('mongoose-history');
let Schema = mongoose.Schema;

let MySchema = Post = new Schema({
    title: String,
    status: Boolean
});

MySchema.plugin(mongooseHistory);
// The plugin will automatically create a new collection with the schema name + "_history".
// In this case, collection with name "my_schema_history" will be created.
 0
Author: Muhammad Reda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 17:42:32

Użyłem poniższego pakietu dla projektu meteor / MongoDB i działa dobrze, główną zaletą jest to, że przechowuje historię/wersje w tablicy w tym samym dokumencie, stąd nie ma potrzeby dodatkowych publikacji lub oprogramowania pośredniczącego, aby uzyskać dostęp do historii zmian. Może obsługiwać ograniczoną liczbę poprzednich wersji (np. ostatnie dziesięć wersji), obsługuje również konkatenację zmian (więc wszystkie zmiany zaszły w określonym okresie będą objęte jednym revision).

Nicklozon / meteor-collection-revisions

Inną opcją dźwiękową jest użycie Meteor Vermongo (TUTAJ )

 0
Author: helcode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-25 07:28:31

Spróbuj użyć Javerów. Dobra biblioteka.

 -2
Author: Demel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 08:20:01