zoukankan      html  css  js  c++  java
  • mongoose

    Mongoose

    》Schema
    Mongoose 的一切始于 Schema。每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成。
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    var blogSchema = new Schema({
    title: String,
    author: String,
    body: String,
    comments: [{ body: String, date: Date }],
    date: { type: Date, default: Date.now },
    hidden: Boolean,
    meta: {
    votes: Number,
    favs: Number
    }
    });
    在这之后你还想添加 keys 的话, 请使用 Schema#add 方法。
    允许使用的 SchemaTypes 有:
    String
    Number
    Date
    Buffer
    Boolean
    Mixed
    ObjectId
    Array

    SchemaType
    指定字段约束,不同的SchemaType类型还有其他不同的属性配置
    var schema2 = new Schema({
    test: {
    type: String,
    lowercase: true // Always convert `test` to lowercase
    }
    });
    常用可配参数有:
    required: 必选验证器。
    default: 默认值。Any或function,如果该值是一个函数,则该函数的返回值将用作默认值。
    select: boolean值, 指定是否被投影
    validate: 验证器
    alias: 别名。
    其他类型特有属性官方API查找。

    since index creation can cause a significant performance impact. Disable the behavior by setting the autoIndex option of your schema to false, or globally on the connection by setting the option autoIndex to false.

    mongoose.connect('mongodb://user:pass@localhost:port/database', { autoIndex: false }); //真心推荐
    // or
    mongoose.createConnection('mongodb://user:pass@localhost:port/database', { autoIndex: false });
    // or
    animalSchema.set('autoIndex', false);
    // or
    new Schema({..}, { autoIndex: false });

    schema还可以添加一些Options:
    option: id
    Mongoose 会默认生成一个虚拟值 id,指向文档的 _id 字段。 如果你不需要 id 虚拟值,可以通过这个选项禁用此功能。
    option: _id
    Mongoose 默认给你的 Schema 赋值一个 _id。 这个值的类型是 ObjectId,这与MongoDB的默认表现一致。 如果你不需要 _id,可以通过这个选项禁用此功能。
    option: strict
    Strict 选项默认为 true,这意味着你不能 save schema 里没有声明的属性。
    还可以设置转字符串时的一些参数:
    schema.set('toJSON', { getters: true, virtuals: false });
    schema.set('toObject', { getters: true });

    》connction
    我们可以通过利用mongoose的connect()方法连接到MongoDB 。
    mongoose.connect('mongodb://localhost/myapp');
    这是在默认端口(27017)连接到在本地运行的myapp数据库的最低需要。

    我们也能根据你的环境指定URI中的几个参数,详细看MongoDB连接字符串格式。
    mongoose.connect('mongodb://username:password@host:port/database?options...');
    mongoose.connect('mongodb://test:1234@ip:port/test', {
    useNewUrlParser: true,
    useUnifiedTopology: true
    }).then(()=>{
    response.end("connected!");
    mongoose.connection.close();
    }).catch((e)=>{
    response.end("error!"+e);
    });

    要连接到副本集,你可以用逗号分隔,传入多个地址
    mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
    连接多个 mongos(MongoDB Shard)分片集群的实例。在 mongoose 5.x 中不需要传入任何特殊选项。
    // Connect to 2 mongos servers
    mongoose.connect('mongodb://mongosA:27501,mongosB:27501', cb);

    多个连接
    有时候我们需要多个连接,例如权限不同,或是连接到不同数据库。这个情况下我们可以使用 mongoose.createConnection(), 它接受之前提到的所有参数,给你返回一个新的连接。
    const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
    connection 对象后续用于创建和检索 models。 models 的范围总是局限于单个连接。

    调用 mongoose.connect() 时,Mongoose 会自动创建默认连接。 你可以使用 mongoose.connection 访问默认连接。

    Options
    connect方法还接收一个option对象,该对象将被传递给底层驱动程序,可以传一些Mongo底层驱动的参数或mongoose自己的参数。这里的所有选项优先于连接字符串传递的选项。
    mongoose.connect(uri, options);
    可设置的有:
    poolSize - MongoDB 保持的最大连接池的连接数。 poolSize 的默认值是 5。
    autoIndex - 默认情况下,mongoose 在连接时会自动建立 schema 的索引,这可能导致长时间阻塞,建议设置为false。
    user/pass - 用于认证的用户名和密码
    bufferCommands - Mongoose会缓存所有命令直到连接上数据库,这意味着你不必等待它连接MongoDB再定义 models,执行 queries 等。这个操作很方便,但也回引起一些疑惑, 因为如果你没连上 ,Mongoose 不会 抛错。要禁用缓存,请修改 bufferCommands 配置,也可以全局禁用 bufferCommands :
    mongoose.set('bufferCommands', false);
    bufferMaxEntries - MongoDB 驱动同样有自己的离线时缓存机制。如果你希望链接错误时终止数据库操作,请将此选项设为 0 以及把 bufferCommands 设为 false 。
    connectTimeoutMS - 连接超时时间
    keepAlive - 保活时间

    const options = {
    user: "test",
    pass: "1234"
    autoIndex: false, // Don't build indexes
    poolSize: 10, // Maintain up to 10 socket connections
    bufferCommands: false,
    bufferMaxEntries: 0 // If not connected, return errors immediately rather than waiting for reconnect
    };
    mongoose.connect(uri, options);
    connect函数可以传入回调方法 function(error),或者返回promise写成then形式:
    mongoose.connect(uri, options).then(
    () => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
    err => { /** handle initial connection error */ }
    );

    》model
    Models 是从 Schema 编译来的构造函数。 它们的实例就代表着可以从数据库保存和读取的 documents。 从数据库创建和读取 document 的所有操作都是通过 model 进行的。

    使用默认的connection把 schema 编译为一个 Model: mongoose.model(modelName, schema)
    使用自定义的connection把 schema 编译为一个 Model: connection.model(modelName, schema)

    var schema = new mongoose.Schema({ name: 'string', size: 'string' });
    var Car = mongoose.model('Car', schema);
    注意: mongoose.model里面定义的第一个参数,比如’Car’,实际上在db中的collection是’Cars’。要解决这种混淆,可以在创建Schema时明确设置collection名称:
    var schema = new mongoose.Schema({ name: 'string', size: 'string' },{collection:'Car'} );

    >有了Model,则可以创建文档、操作文档:
    var small = new Car({ size: 'small' });
    small.save(function (err) {
    if (err) return handleError(err);
    // saved!
    })
    // 或者
    Car.create({ size: 'small' }, function (err, small) {
    if (err) return handleError(err);
    // saved!
    })
    要注意,直到 model 使用的数据库连接( connection )被打开,small 文档才会被创建/删除。

    >查询
    mongoose支持 MongoDB 的查询语法,即直接使用find/findOne并传入json格式的查询条件(可回调或promise的then处理结果),或者用 model 简单封装 findById、where 这些静态方法。

    Mongoose 中每一处查询,被传入的回调函数都遵循 callback(error, result) 这种模式。查询结果的格式取决于做什么操作: findOne() 是单个文档(有可能是 null ),find() 是文档列表, count() 是文档数量,update() 是被修改的文档数量。

    Tank.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);
    Tank.findById(id, function (err, tank) {
    if (err) return handleError(err);
    tank.size = 'large'; // 更新操作,直接操作对象即可,或者用 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);
    });

    增删改查
    ;(async ()=>{
    //查
    var t = await studentModel.find({})
    //改 //注意! : 若使用 xxx.save() 则只有 schema 声明过的对象才能通过对应的 setter 传递值进入 xxx._doc.xxx.value
    await studentModel.update({_id:"ae86"},{$set:{username:"newwww"}})
    //增
    await studentModel.create({ username:'test',phone:'110'})
    //删除
    await studentModel.remove({phone:'110'})
    //$lt"(小于),"$lte"(小于等于),"$gt"(大于),"$gte"(大于等于),"$ne"(不等于)
    await userMode.find({"age": {"$lt": 18}})

    //简单分页查询
    Model.find({}).sort({'_id':-1}).skip(page * 5).limit(5)
    //复杂分页查询 要求前端返回一个 ObjectId
    if (id) {
    return Model.find({{'_id': {"$lt": id}}).sort({'_id':-1}).skip(page * 5).limit(5)
    }else {
    return Model.find({}).sort({'_id':-1}).skip(page * 5).limit(5)
    }

    //关闭连接
    mongoose.connection.close()
    })()

    防止函数声明式调用失效
    把( function a( ){ })()改写为;( function a( ) { })() 比较好,加一个分号防止上一行结尾没有分号导致的编译歧义

  • 相关阅读:
    树莓派摄像头直播程序,非常希望有贡献者一起玩
    Ansible 操作windows
    Python实现自平衡二叉树AVL
    Python非递归遍历多叉树
    Python 非递归遍历图
    使用ffmpeg进行网络直播
    Python安装mysqldb
    运维工程师速成
    科幻小说《霜与火》 by 雷·布雷德伯里
    jvm 内存调整
  • 原文地址:https://www.cnblogs.com/ccdat/p/11749448.html
Copyright © 2011-2022 走看看