1. Sub Docs(子文档)

子文档是嵌入在其他文档中的文档。在 Mongoose 中,这意味着您可以在其他模式中嵌套模式。Mongoose 有两个不同的子文档概念:子文档数组和单个嵌套的子文档。

var childSchema = new Schema({ name: 'string' });

var parentSchema = new Schema({
  //子文档数组
  children: [childSchema],
  //单个嵌套的子文档。警告:单个嵌套的subdocs只能工作
  //在 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()` 是一个空操作, 它会触发中间件
// 但实际上**不会**保存子文档。
// 你需要保存父文档。
parent.save(callback);

子文档像顶级文档一样保存和验证中间件。在父文档上调用 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() 之前进行的验证实际上是一个内置的中间件。

// 下面的代码将按顺序输出 1-4
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();
});

1.1. 查找子文档

默认情况下,每个子文档都有一个 _id。 Mongoose 文档数组有一个特殊的 id 方法,用于搜索文档数组以找到具有给定 _id 的文档。

var doc = parent.children.id(_id);

1.2. 将子文档添加到数组

MongooseArray 方法,诸如 pushunshiftaddToSet 和其他透明地将参数转换为正确的类型:

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!');
});

也可以使用 MongooseArrays 的 create 方法将子文档添加到数组中,创建子文档。

var newdoc = parent.children.create({ name: 'Aaron' });

1.3. 删除子目录

每个子文档都有自己的 remove 方法。对于数组子文档,这相当于在子文档上调用 .pull()。对于单个嵌套的子文档,remove() 相当于将子文档设置为 null

//相当于parent.children.pull(_id) parent.children.id(_id)卸下摆臂(); //相当于parent.child = null parent.child.remove(); parent.save(function(err){ 如果(err)返回handleError(err); console.log('subdocs被删除'); });

// 相当于 `parent.children.pull(_id)`
parent.children.id(_id).remove();
// 相当于  `parent.child = null`
parent.child.remove();
parent.save(function (err) {
  if (err) return handleError(err);
  console.log('the subdocs were removed');
});

1.4. 数组的替代声明语法

如果使用对象数组创建模式,mongoose 会自动将对象转换为模式:

var parentSchema = new Schema({
  children: [{ name: 'string' }]
});
// 等价
var parentSchema = new Schema({
  children: [new Schema({ name: 'string' })]
});

1.5. 接下来

现在我们已经介绍了Sub-documents,让我们看看 querying

Copyright © tuzhu008 2017 all right reserved,powered by Gitbook该文件修订时间: 2017-12-24 13:19:52

results matching ""

    No results matching ""