Поддокументы
Поддокументы — это документы, вложенные в другие документы. В Mongoose это означает, что вы можете вкладывать схемы в другие схемы. Mongoose имеет два различных понятия поддокументов: массивы поддокументов и одиночные вложенные поддокументы.
var childSchema = new Schema({ name: 'string' }); var parentSchema = new Schema({ // Array of subdocuments children: [childSchema], // Single nested subdocuments. Caveat: single nested subdocs only work // in mongoose >= 4.2.0 child: childSchema });
Поддокументы похожи на обычные документы. Вложенные схемы могут иметь средства промежуточного программного обеспечения, собственную логику валидации, виртуальные поля и любые другие возможности, которые могут использовать схемы верхнего уровня. Основное отличие заключается в том, что поддокументы не сохраняются индивидуально, они сохраняются всякий раз, когда сохраняется их родительский документ верхнего уровня.
var Parent = mongoose.model('Parent', parentSchema); var parent = new Parent({ children: [{ name: 'Matt' }, { name: 'Sarah' }] }) parent.children[0].name = 'Matthew'; // `parent.children[0].save()` is a no-op, it triggers middleware but // does **not** actually save the subdocument. You need to save the parent // doc. parent.save(callback);
Поддокументы имеют save и validate средства промежуточного программного обеспечения, как и документы верхнего уровня. Вызов save() родительского документа запускает save() средства промежуточного программного обеспечения для всех его поддокументов, и то же самое для validate() средств промежуточного программного обеспечения.
childSchema.pre('save', function (next) { if ('invalid' == this.name) { return next(new Error('#sadpanda')); } next(); }); var parent = new Parent({ children: [{ name: 'invalid' }] }); parent.save(function (err) { console.log(err.message) // #sadpanda });
Средства промежуточного программного обеспечения поддокументов pre('save') и pre('validate') выполняются перед средствами промежуточного программного обеспечения документа верхнего уровня pre('save'), но после средств промежуточного программного обеспечения документа верхнего уровня pre('validate'). Это связано с тем, что валидация перед save() на самом деле является частью встроенных средств промежуточного программного обеспечения.
// Below code will print out 1-4 in order var childSchema = new mongoose.Schema({ name: 'string' }); childSchema.pre('validate', function(next) { console.log('2'); next(); }); childSchema.pre('save', function(next) { console.log('3'); next(); }); var parentSchema = new mongoose.Schema({ child: childSchema, }); parentSchema.pre('validate', function(next) { console.log('1'); next(); }); parentSchema.pre('save', function(next) { console.log('4'); next(); });
Поиск поддокумента
Каждый поддокумент имеет _id по умолчанию. Массивы документов Mongoose имеют специальный метод id для поиска в массиве документов документа с заданным _id.
var doc = parent.children.id(_id);
Добавление поддокументов в массивы
Методы MongooseArray, такие как push, unshift, addToSet и другие, прозрачно преобразуют аргументы в их соответствующие типы:
var Parent = mongoose.model('Parent'); var parent = new Parent; // create a comment parent.children.push({ name: 'Liesl' }); var subdoc = parent.children[0]; console.log(subdoc) // { _id: '501d86090d371bab2c0341c5', name: 'Liesl' } subdoc.isNew; // true parent.save(function (err) { if (err) return handleError(err) console.log('Success!'); });
Поддокументы также можно создать, не добавляя их в массив, используя метод create MongooseArrays.
var newdoc = parent.children.create({ name: 'Aaron' });
Удаление поддокументов
Каждый поддокумент имеет свой собственный метод remove. Для поддокумента в массиве это эквивалентно вызову .pull() для поддокумента. Для одиночного вложенного поддокумента remove() эквивалентно установлению поддокумента в null.
// Equivalent to `parent.children.pull(_id)` parent.children.id(_id).remove(); // Equivalent to `parent.child = null` parent.child.remove(); parent.save(function (err) { if (err) return handleError(err); console.log('the subdocs were removed'); });
Альтернативный синтаксис объявления для массивов
Если вы создаете схему с массивом объектов, mongoose автоматически преобразует объект в схему для вас:
var parentSchema = new Schema({ children: [{ name: 'string' }] }); // Equivalent var parentSchema = new Schema({ children: [new Schema({ name: 'string' })] });
Далее
Теперь, когда мы рассмотрели Sub-documents, давайте посмотрим на запросы.
© 2010 LearnBoost
Licensed under the MIT License.
https://mongoosejs.com/docs/4.x/docs/subdocs.html