美文网首页
mongoose.js 基础使用—— Documents

mongoose.js 基础使用—— Documents

作者: 没名字的某某人 | 来源:发表于2022-10-22 16:36 被阅读0次

文档(Documents)

Mongoose document 代表着MongoDB 文档的一对一映射。每个 document都是他的Model的实例。

检索

MongoDB 有很多检索数据的方法。我们在这章暂不提及,详情请看查询(queries)

更新

Document 更新的方法同样有很多,我们先看看一个传统的实现,使用 findById

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);

  tank.size = 'large';
  tank.save(function (err, updatedTank) {
    if (err) return handleError(err);
    res.send(updatedTank);
  });
});

你也可以用 .set() 修改 document。在底层, tank.size = 'large';tank.set({ size: 'large' })实现。

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);

  tank.set({ size: 'large' });
  tank.save(function (err, updatedTank) {
    if (err) return handleError(err);
    res.send(updatedTank);
  });
});

这个方法先检索数据,接着更新(使用了 save)。 如果我们仅仅需要更新而不需要获取该数据, Model#update 就很适合我们:

Tank.update({ _id: id }, { $set: { size: 'large' }}, callback);

如果我们确实需要返回文档,这个方法更适合:

Tank.findByIdAndUpdate(id, { $set: { size: 'large' }}, { new: true }, function (err, tank) {
  if (err) return handleError(err);
  res.send(tank);
});

验证

Document 会在被保存之前验证。阅读 验证(validation)章节了解更多。

覆盖

你可以用 .set() 覆盖整个文档。如果你要修改 在中间件中被保存的文档,这样就很方便。

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);
  // Now `otherTank` is a copy of `tank`
  otherTank.set(tank);
});

子文档(Subdocument)

子文档是指嵌套在另一个文档中的文档。 在 Mongoose 中,这意味着你可以在里嵌套另一个 schema。 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
});

子文档与普通 document 类似。嵌套 schema 可以有自己的 中间件、自定义检验逻辑、 虚拟值以及其他顶层 schemas 可用的特性。两者主要的不同点是 子文档不能单独保存,他们会在他们的顶级文档保存时保存。

var Parent = mongoose.model('Parent', parentSchema);
var parent = new Parent({ children: [{ name: 'Matt' }, { name: 'Sarah' }] })
parent.children[0].name = 'Matthew';

// `parent.children[0].save()` 无操作,虽然他触发了中间件
// 但是没有保存文档。你需要 save 他的父文档
parent.save(callback);

子文档跟普通 document 一样有 savevalidate 中间件。 调用父文档的 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') 中间件执行于 顶层 document 的 pre('save') 之前, 顶层 document 的 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();
});

查找子文档

每个子文档都有一个默认的 _id 。Mongoose document 数组有一个特别的 id 方法, 这个方法只要传入 _id 就能返回文档数组中特定文档。

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

添加子文档到数组

Mongoose 数组有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!');
});

删除子文档

每个子文档都有 remove方法。 另外,对于子文档数组,有一个等效方法 .pull()。 对于单个嵌套子文档,remove() 与把这个文档的值设为 null 等效。

// 等效于 `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');
});

代替声明语法的写法
如果你用对象的数组创建 schema ,mongoose 会自动 为你把对象转换成 schema:

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

相关文章

网友评论

      本文标题:mongoose.js 基础使用—— Documents

      本文链接:https://www.haomeiwen.com/subject/eqqbzrtx.html