zoukankan      html  css  js  c++  java
  • mongoose 文档(三) Documents

    Documents

    mongoose 的 document 与MongoDB 的 document 一一对应。每个document都是它的model的实例。

    1、检索

     在MongoDB中有很多方法检索document。我们不会在这一节中涉及。详细请看 querying 节。

    2、更新

     有很多种方法修改 document。我们首先看传统方法findById。

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

    这种方法包括先从Mongo检索document,然后发出修改命令(通过调用保存触发)。可是,如果我们不需要在应用程序中返回document而是只不过想直接修改数据库中的属性,Model#update 适合我们。

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

    如果我们想要应用程序中返回document,有一个更好的选项

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

     静态方法findAndUpdate/Remove 最多只改变一个document,并只通过一个调用返回到数据库。在 findAndModifu 主题 变化。阅读API文档查看更多细节。注意findAndUpdate/Remove在修改数据库前不执行任何钩子或验证。如果你想要钩子和验证,先检索 document 然后保存它。

    3、验证

     document在保存前进行验证。详情阅读API文档或validation节。

    子文档

    sub-document是各自有着schema的document,是一个父元素数组的元素。

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

    sub-document享有所有与普通document相同的特征。唯一不同的是它们不单独保存,当它们的顶层父document保存时它们才被保存。

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

    如果在子文档中间件发生错误,它冒泡到父的save()回调,因此错误处理是小事一桩。

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

    1、查找子文档

    每一个document都有_id,.DocumentArrays有特殊的 id 方法来通过_id来查找document。

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

    2、增加子文档

    mongoose数组方法如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!');
    });

     子文档的创建不需通过使用创建方法MongooseArrays添加到数组。

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

    3、删除文档

    每个子文档都有自己的删除方法:

    var doc = parent.children.id(id).remove();
    parent.save(function (err) {
      if (err) return handleError(err);
      console.log('the sub-doc was removed')
    });

    交替声明语法

    如果你不需要访问的子文档schena的实例,你也可以通过简单传递一个对象字面量声明子文档。

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

    简单嵌入子文档

    New in 4.2.0

    你还可以在不使用数组的方式下嵌入schema。

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

    一个嵌入式子文档的行为类似于一个嵌入式数组。当它的父文档保存时它才保存、它的前/后document中间件被执行。

    childSchema.pre('save', function(next) {
      console.log(this.name); // prints 'Leia'
    });
    var Parent = mongoose.model('Parent', parentSchema);
    var parent = new Parent({ child: { name: 'Luke' } })
    parent.child.name = 'Leia';
    parent.save(callback); // Triggers the pre middleware.

    defaults

     1、在schema中声明默认值

    你可以给schema的某些path定义默认值。如果你创建的新document没有设置那个path,默认值会取代。

        var schema = new Schema({
          name: String,
          role: {type: String, default: 'guitarist'}
        });
    
        var Person = db.model('Person', schema);
    
        var axl = new Person({name: 'Axl Rose', role: 'singer'});
        assert.equal(axl.role, 'singer');
    
        var slash = new Person({name: 'Slash'});
        assert.equal(slash.role, 'guitarist');

    2、默认函数

    你还可以将默认schema选项设置为一个函数。mongoose 将执行那个函数并使用它的返回值作为默认值。

     var schema = new Schema({
          title: String,
          date: {
            type: Date,
            // `Date.now()` returns the current unix timestamp as a number
            default: Date.now
          }
        });
    
        var BlogPost = db.model('BlogPost', schema);
    
        var post = new BlogPost({title: '5 Best Arnold Schwarzenegger Movies'});
    
        // The post has a default Date set to now
        assert.ok(post.date.getTime() >= Date.now() - 1000);
        assert.ok(post.date.getTime() <= Date.now());
      

    3、setDefaultsOnInsert 选项

     默认情况下,mongoose只在创建新document时应有默认值。如果你使用update() 和 findOneAndUpdate()它会设置默认值。可是 mongoose 4.x 让你选择性加入这个行为使用 setDefaultsOnInsert 选项。

    4、重要

     setDefaultsOnInsert  选项依赖MongoDB $setOnInsert 操作符。在 MongoDB 2.4中介绍了$setOnInsert操作符,如果你使用的MongoDB服务器<2.4.0,不要使用setDefaultsOnInsert。

        var schema = new Schema({
          title: String,
          genre: {type: String, default: 'Action'}
        });
    
        var Movie = db.model('Movie', schema);
    
        var query = {};
        var update = {title: 'The Terminator'};
        var options = {
          // Return the document after updates are applied
          new: true,
          // Create a document if one isn't found. Required
          // for `setDefaultsOnInsert`
          upsert: true,
          setDefaultsOnInsert: true
        };
    
        Movie.
          findOneAndUpdate(query, update, options, function (error, doc) {
            assert.ifError(error);
            assert.equal(doc.title, 'The Terminator');
            assert.equal(doc.genre, 'Action');
          });
      
  • 相关阅读:
    一步一步学grails:7 MVC
    虚拟机安装CentOS7
    虚拟机安装windows sever2008
    微信console
    centOS7常用操作命令
    lr事务
    2.0通信之调用ADO.NET Data Services(数据服务)
    Silverlight应用程序中如何获取ASP.NET页面参数
    2.0网页之可脚本化, 与DOM的交互, 与JavaScript的交互
    2.0Tip/Trick之MessageBox, Popup, 循环的几种实现方法, 动态变换主题, 本地化(多语言), 响应鼠标双击事件
  • 原文地址:https://www.cnblogs.com/surahe/p/5180870.html
Copyright © 2011-2022 走看看