MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Денормализация с Mongoose:Как да синхронизирате промените

Добре, докато чакам по-добър отговор от моя собствен, ще се опитам да публикувам какво съм правил досега.

Мидълуер преди/след

Първото нещо, което опитах, беше да използвам пре/пост мидълуер за синхронизиране на документи, които се препращат един към друг. (Например, ако имате Author и Quote , а Author има масив от типа:quotes: [{type: Schema.Types.ObjectId, ref:'Quotes'}] , тогава всеки път, когато дадена оферта бъде изтрита, ще трябва да премахнете нейния _id от масива. Или ако авторът е премахнат, може да искате всичките му цитати да бъдат премахнати).

Този подход има важнопредимство :ако дефинирате всяка схема в свой собствен файл, можете да дефинирате междинния софтуер там и всичко да е изрядно организирано . Всеки път, когато погледнете схемата, точно отдолу можете да видите какво прави, как нейните промени засягат други обекти и т.н.:

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.
    )
})

Основният недостатък обаче е, че тези кукички не се изпълняват, когато извиквате актуализация или други статични функции за актуализиране/премахване на Модел . По-скоро трябва да извлечете документа и след това да извикате save() или remove() върху тях.

Друг по-малък недостатък е, че Quote вече трябва да знае за всеки, който го препраща, така че да може да ги актуализира всеки път, когато Quote бъде актуализиран или премахнат. Да кажем, че Period има списък с цитати и Author има и списък с цитати, Quote ще трябва да знае за тези два, за да ги актуализира.

Причината за това е, че тези функции изпращат атомарни заявки към базата данни директно. Въпреки че това е хубаво, мразя несъответствието между използването на save() и Model.Update(...) . Може би някой друг или вие в бъдеще случайно използвате функциите за статична актуализация и вашият междинен софтуер не се задейства, което ви създава главоболия, от които се мъчите да се отървете.

Механизми за събития NodeJS

Това, което правя в момента, не е наистина оптимално, но ми предлага достатъчно предимства, за да надхвърли недостатъците (или поне така вярвам, ако някой иска да ми даде някаква обратна връзка, ще бъде страхотно). Създадох услуга, която обхваща модел, да речем AuthorService който разширява events.EventEmitter и е конструкторска функция, която ще изглежда приблизително така:

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()

Предимствата:

  • Всяка заинтересована функция може да се регистрира в събитията на услугата и да бъде уведомена. По този начин, например, когато Quote е актуализиран, AuthorService може да го слуша и да актуализира Authors съответно. (Бележка 1)
  • Не е необходимо Quote да е наясно с всички документи, които го споменават, Услугата просто задейства QuoteUpdated събитие и всички документи, които трябва да извършат операции, когато това се случи, ще го направят.

Бележка 1:Докато тази услуга се използва винаги, когато някой трябва да взаимодейства с mongoose.

Недостатъците:

  • Добавен шаблонен код, използващ услуга вместо директно mongoose.
  • Сега не е съвсем очевидно какви функции се извикват, когато задействате събитието.
  • Вие отделяте производител и потребител с цената на четливостта (тъй като просто emit('EventName', args) , не е веднага очевидно кои услуги слушат това събитие)

Друг недостатък е, че някой може да извлече модел от услугата и да извика save() , в който събитията няма да се задействат въпреки че съм сигурен, че това може да се реши с някакъв вид хибрид между тези две решения.

Много съм отворен за предложения в тази област (поради което публикувах този въпрос на първо място).



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Създаване на многополеви индекси в Mongoose / MongoDB

  2. TypeError:обектът не е функция при използване на MongoDB с Node.js

  3. MongoDb :Намерете общ елемент от два масива в рамките на заявка

  4. Външното поле на $lookup може да бъде полето на вложен документ?

  5. Защо набор от реплики на mongodb изисква нечетен брой възли за гласуване?