假设以下代码都运行在
let mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test');
let db = mongoose.connection;
db.on('error', () => {
console.error('链接失败');
});
db.once('open', function () {
//下面讲到的所有代码都在这里运行
});
Documents
Mongoose文档表示对存储在MongoDB中的文档的一对一映射。每个文档都是其模型的实例。
Updating
有多种方式可以更新文档。我们首先来看一个使用findById的传统方法:
let Schema = mongoose.Schema;
let schema = new Schema({
name:String
});
let Person = mongoose.model('Person',schema);
Person.findById("5879c65893963d18fe77a31b",function(err,man){
if(err){
return console.error(err);
}
man.name = 'Blu';
man.save(function(err){
if(err){
return console.error(err);
}
console.log('保存成功');
});
});
这种方法包括首先从Mongo中检索文档,然后发出更新命令(通过调用save触发)。但是,如果我们不需要在我们的应用程序中返回的文档,并且只想直接更新数据库中的属性,那么Model#update适合我们:
let Schema = mongoose.Schema;
let schema = new Schema({
name:String
});
let Person = mongoose.model('Person',schema);
Person.update({_id:"5879c65893963d18fe77a31b"},{$set:{name:'SHE'}},function(){
//这里不返回文档
});
如果我们确实需要在我们的应用程序中返回文档,有另一个更好的选择:
let Schema = mongoose.Schema;
let schema = new Schema({
name:String
});
let Person = mongoose.model('Person',schema);
Person.findByIdAndUpdate('5879c65893963d18fe77a31b',{$set:{name:"李寻欢"}},function(err,man){
if(err){
return console.error(err);
}
console.log(man);
});
Sub Docs
子文档是具有自己的模式的文档,它们是父文档数组的元素:
let childSchema = new Schema({ name: 'string' });
let parentSchema = new Schema({ children: [childSchema]});
子文档享有与普通文档相同的功能。唯一的区别是它们不单独保存,它们在保存顶级父文档时保存。
let Schema= mongoose.Schema;
let childrenSchema = new Schema({
name:String
});
let parentSchema = new Schema({
children:[childrenSchema]
});
let Parent = mongoose.model('Parent',parentSchema);
let parent = new Parent({
children:[{
name:'Matt'
},{
name:'Sarah'
}]
});
parent.save(function(err,parent){
if(err){
return console.error(err);
}
console.log(parent);
});
如果在子文档中间件中发生错误,它会冒泡到父对象的save()回调,因此错误处理是一个快速!
let Schema= mongoose.Schema;
let childrenSchema = new Schema({
name:String
});
childrenSchema.pre('save',function(next){
if('noshower' == this.name){
return next(new Error(this.name+'禁止取'));
}
next();
});
let parentSchema = new Schema({
children:[childrenSchema]
});
let Parent = mongoose.model('Parent',parentSchema);
let parent = new Parent({
children:[{
name:'noshwoer'
},{
name:'noshower'
}]
});
parent.save(function(err,parent){
if(err){
return console.error(err); //Error: noshower禁止取
}
console.log(parent);
});
Finding a sub-document
每个文档都有一个_id。 DocumentArrays有一个特殊的id方法,通过其_id查找文档。
let Schema= mongoose.Schema;
let childrenSchema = new Schema({
name:String
});
childrenSchema.pre('save',function(next){
if('noshower' == this.name){
return next(new Error(this.name+'禁止取'));
}
next();
});
let parentSchema = new Schema({
children:[childrenSchema]
});
let Parent = mongoose.model('Parent',parentSchema);
//先找到父文档 Parent.findOne({_id:'5879d25dc3352e1ad7855f65'},function(err,parent){
if(err){
return console.error(err);
}
//查询子文档
let doc =parent.children.id('5879d25dc3352e1ad7855f67');
console.log(doc.name); //Matt
});
Adding sub-docs
MongooseArray方法(例如push,unshift,addToSet和其他方法)将参数强制转换为其正确类型:
// 一次性存五个名字
let Schema= mongoose.Schema;
let childrenSchema = new Schema({
name:String
});
childrenSchema.pre('save',function(next){
if('noshower' == this.name){
return next(new Error(this.name+'禁止取'));
}
next();
});
let parentSchema = new Schema({
children:[childrenSchema]
});
let Parent = mongoose.model('Parent',parentSchema);
let parent = new Parent();
let names = ['John','Michelle','Amy','Kim','Mary'];
for(let val of names){
parent.children.push({name:val});
}
parent.save(function(err,parent){
if(err){
return console.error(err);
}
console.log('success'); //success
});
Removing docs
每个子文档都有自己的remove方法。
let Schema= mongoose.Schema;
let childrenSchema = new Schema({
name:String
});
childrenSchema.pre('save',function(next){
if('noshower' == this.name){
return next(new Error(this.name+'禁止取'));
}
next();
});
let parentSchema = new Schema({
children:[childrenSchema]
});
let Parent = mongoose.model('Parent',parentSchema);
Parent.findOne({'_id':"5879d25dc3352e1ad7855f65"},function(err,parent){
parent.children.id('5879d25dc3352e1ad7855f67').remove();
parent.save(function(err){
if(err){
return console.error(err);
}
console.log('删除成功');
})
});
如果你不需要访问子文档模式实例,那么你也可以通过传递一个对象来声明sub-docs
let parentSchema = new Schema({
children: [{ name: 'string' }]
})