В модель MongoDB добавлен только первый вложенный документ

У меня есть модель Mongoose, которая выглядит так:

var ProjectSchema = new Schema({
    name: String,
    slug: String,
    dateCreated: { type: Date, default: new Date() },
    dateUpdated: { type: Date, default: new Date() },
    createdByUserId: Schema.Types.ObjectId,
    screens: [Schema.Types.Mixed]
});

У меня есть метод класса, который выглядит так:

ProjectSchema.statics.saveElementProperties = function(slugName, screenIndex, elementId, props, callback) {
    var Project = mongoose.model('Project');

    var updateProject = function(project) {
        // Init empty objects if missing
        project.screens[screenIndex] = project.screens[screenIndex] || {};
        project.screens[screenIndex].elements = project.screens[screenIndex].elements || {};
        project.screens[screenIndex].elements[elementId] = project.screens[screenIndex].elements[elementId] || {};
        // Apply properties
        project.screens[screenIndex].elements[elementId] = "Dummy Project Data";
        console.log('elements before save:', project.screens[screenIndex].elements);
        project.save(callback);
    };

    Project.findOne({ slug: slugName }, function(err, project) {
        if (!project) {
            project = new Project({ name: slugName, slug: slugName });
        }
        updateProject(project);
    });
};

Это происходит, когда я вызываю метод saveElementProperties:

  1. Когда я запускаю этот метод в первый раз, он работает так, как должен; новый объект добавляется в project.screens[screenIndex].elements как во время выполнения (оператор журнала 'elements before save:'), так и при проверке базы данных MongoDB с помощью клиента mongo.
  2. Во второй раз второй объект добавляется к project.screens[screenIndex].elements во время выполнения, но этот объект никогда не сохраняется в MongoDB.
  3. В третий раз объекты 1 и 3 видны в project.screens[screenIndex].elements во время выполнения, но третий объект никогда не сохраняется в MongoDB.

Что вызывает такое поведение?

БОЛЬШОЕ ОБНОВЛЕНИЕ: я переписал весь механизм сохраняемости, чтобы он запускался реже, и вместо этого заменил весь объект project.screens[screenIndex].elements обновленной структурой:

ProjectSchema.statics.saveScreenProperties = function(slugName, screenIndex, elements, callback) {
    console.log('saveScreenProperties:', slugName, screenIndex);
    var Project = mongoose.model('Project');

    var updateProject = function(project) {
        // Init empty objects if missing
        project.screens[screenIndex] = project.screens[screenIndex] || {};
        project.screens[screenIndex].elements = elements;
        // Mark as modified and save
        project.markModified('screens.' + screenIndex);
        project.save(callback);
    };

    Project.findOne({ slug: slugName }, function(err, project) {
        if (!project) {
            project = new Project({ name: slugName, slug: slugName });
            console.log('  creating new project');
        }
        updateProject(project);
    });
};

Однако он по-прежнему показывает то же поведение — он сохраняет начальный объект elements, но не изменяет его позже.


person Tom Söderlund    schedule 01.02.2014    source источник
comment
Вы видели markModified в документах? mongoosejs.com/docs/api.html#document_Document-markModified Изменения победили не настаивайте, если Мангуст не знал, что они произошли.   -  person WiredPrairie    schedule 02.02.2014
comment
@WiredPrairie Спасибо, я пытался добавить project.markModified('screens.0'); и даже project.markModified('screens');, но без изменений.   -  person Tom Söderlund    schedule 02.02.2014
comment
@WiredPrairie: см. обновление вопроса, включая мое использование markModified.   -  person Tom Söderlund    schedule 02.02.2014
comment
Я беру это назад - приведенный выше код действительно работает. Спасибо!   -  person Tom Söderlund    schedule 02.02.2014


Ответы (1)


Проблема в том, что вы манипулируете объектами так же, как и в стандартном коде, но мангуст не является «механизмом сохранения», это ODM. Таким образом, вам необходимо использовать предоставленные методы для обновления хранилища данных.

Вам нужно будет использовать операторы обновления для $push в массив. Аналогичные методы есть и у Mongoose. Наиболее поясняющие документы находятся на сайте MongoDB.

http://docs.mongodb.org/manual/reference/operator/update-array/

http://docs.mongodb.org/manual/reference/operator/update/

http://docs.mongodb.org/manual/reference/method/db.collection.update/#db.collection.update

person Neil Lunn    schedule 01.02.2014
comment
Спасибо! Я переписал механизм сохранения (см. обновленный вопрос выше), и теперь мне нужно сохранить измененный объект elements, но он не сохраняется. Любые подсказки? - person Tom Söderlund; 02.02.2014
comment
Вам нужно нажать, как я сказал в ответе. У мангуста тоже есть метод. Также посмотрите заполнение в документации. - person Neil Lunn; 02.02.2014
comment
Не мангуст, но вот эти два упоминания совсем недавно. 21502654 21502620 - person Neil Lunn; 02.02.2014