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
Arraymongodb
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.json
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 });promise
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数据库的最低须要。app
咱们也能根据你的环境指定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);
});socket
要链接到副本集,你能够用逗号分隔,传入多个地址
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);async
多个链接
有时候咱们须要多个链接,例如权限不一样,或是链接到不一样数据库。这个状况下咱们可使用 mongoose.createConnection(), 它接受以前提到的全部参数,给你返回一个新的链接。
const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
connection 对象后续用于建立和检索 models。 models 的范围老是局限于单个链接。mongoose
调用 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( ) { })() 比较好,加一个分号防止上一行结尾没有分号致使的编译歧义