MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Denormalizacja za pomocą Mongoose:Jak zsynchronizować zmiany

Ok, czekając na lepszą odpowiedź niż moja, postaram się opublikować to, co robiłem do tej pory.

Oprogramowanie pośredniczące przed/po

Pierwszą rzeczą, którą spróbowałem, było użycie oprogramowania pośredniczącego przed i po do synchronizacji dokumentów, które odwołują się do siebie. (Na przykład, jeśli masz Author i Quote , a autor ma tablicę typu:quotes: [{type: Schema.Types.ObjectId, ref:'Quotes'}] , wtedy za każdym razem, gdy oferta zostanie usunięta, musisz usunąć jej _id z tablicy. Lub jeśli Autor zostanie usunięty, możesz chcieć usunąć wszystkie jego cytaty).

Takie podejście ma ważną zaletę :jeśli zdefiniujesz każdy schemat we własnym pliku, możesz tam zdefiniować oprogramowanie pośredniczące i mieć je porządnie zorganizowane . Za każdym razem, gdy spojrzysz na schemat, poniżej możesz zobaczyć, co robi, jak jego zmiany wpływają na inne jednostki itp.

var Quote = new Schema({
    //fields in schema
})
//its quite clear what happens when you remove an entity
Quote.pre('remove', function(next) {
    Author.update(
        //remove quote from Author quotes array.
    )
})

Główna wada jednak jest to, że te podpięcia nie są wykonywane, gdy wywołujesz update lub jakąkolwiek funkcję statycznego aktualizowania/usuwania modelu . Raczej musisz pobrać dokument, a następnie wywołać save() lub remove() na nich.

Inną mniejszą wadą jest to, że Quote musi teraz być świadomy każdego, kto się do niego odwołuje, aby mógł je aktualizować za każdym razem, gdy oferta zostanie zaktualizowana lub usunięta. Załóżmy więc, że Period ma listę cytatów i Author ma również listę cytatów, Cytat będzie musiał wiedzieć o tych dwóch, aby je zaktualizować.

Powodem tego jest to, że te funkcje wysyłają zapytania atomowe bezpośrednio do bazy danych. Chociaż jest to miłe, nienawidzę niespójności między używaniem save() i Model.Update(...) . Być może ktoś inny lub Ty w przyszłości przypadkowo użyjesz funkcji aktualizacji statycznej, a Twoje oprogramowanie pośredniczące nie zostanie uruchomione, co przysporzy Ci bólów głowy, których nie możesz się pozbyć.

Mechanizmy zdarzeń NodeJS

To, co obecnie robię, nie jest tak naprawdę optymalne, ale oferuje mi wystarczająco dużo korzyści, aby faktycznie przeważyć wady (przynajmniej tak mi się wydaje, jeśli ktoś chciałby przekazać mi jakieś uwagi, to byłoby świetnie). Stworzyłem usługę, która otacza model, powiedzmy AuthorService która rozszerza events.EventEmitter i jest funkcją konstruktora, która będzie wyglądać mniej więcej tak:

function AuthorService() {
    var self = this

    this.create = function() {...}
    this.update = function() {
        ...
        self.emit('AuthorUpdated, before, after)
        ...
    }
}

util.inherits(AuthorService, events.EventEmitter)
module.exports = new AuthorService()

Zalety:

  • Każda zainteresowana funkcja może zarejestrować się w wydarzeniach serwisowych i otrzymywać powiadomienia. W ten sposób, na przykład, gdy Quote jest zaktualizowany, AuthorService może go słuchać i aktualizować Authors odpowiednio. (Uwaga 1)
  • Cytat nie musi być świadomy wszystkich dokumentów, które się do niego odwołują, usługa po prostu uruchamia QuoteUpdated zdarzenie i wszystkie dokumenty, które muszą wykonać operacje, gdy to nastąpi, zrobią to.

Uwaga 1:tak długo, jak ta usługa jest używana, gdy ktoś potrzebuje interakcji z mangustą.

Wady:

  • Dodano standardowy kod, używając usługi zamiast bezpośrednio mangusty.
  • Teraz nie jest do końca jasne, jakie funkcje są wywoływane po uruchomieniu zdarzenia.
  • Rozdzielasz producenta i konsumenta kosztem czytelności (ponieważ po prostu emit('EventName', args) , nie jest od razu oczywiste, które usługi słuchają tego zdarzenia)

Inną wadą jest to, że ktoś może pobrać model z usługi i wywołać save() , w którym zdarzenia nie będą wywoływane chociaż jestem pewien, że można to rozwiązać za pomocą pewnego rodzaju hybrydy między tymi dwoma rozwiązaniami.

Jestem bardzo otwarty na sugestie w tej dziedzinie (dlatego właśnie zadałem to pytanie).



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Klaster mongodb z punktem końcowym ELB jako dns

  2. MongoDB C# Driver - Ignoruj ​​pola podczas wiązania

  3. Jak zatrzymać wstawianie zduplikowanych dokumentów do kolekcji mongodb

  4. Jak agregować MongoDB w Node.js

  5. zakres mapreduce mongodb - ReferenceError