3.6 Mongoose 基于DOC(实体)的CRUD
Mongoose 有两种CRUD方式
基于文档的操作 需要实例操作
基于model的操作 只需要通过medel来操作即可
基于Entity的操作
Document
的`CRUD都必须经过严格验证的,即Schema的strict严格配置
更新
有许多方式来更新文件,以下是常用的传统方式:
PersonModel.findById(id,function(err,person){
person.name = 'MDragon';
person.save(function(err){});
});
这里,利用Model
模型查询到了person
对象,该对象属于Entity
,可以有save操作,如果使用
Model`操作,需注意:
PersonModel.findById(id,function(err,person){
person.name = 'MDragon';
var _id = person._id; //需要取出主键_id
delete person._id; //再将其删除
PersonModel.update({_id:_id},person,function(err){});
//此时才能用Model操作,否则报错
});
update
第一个参数是查询条件,第二个参数是更新的对象,但不能更新主键,这就是为什么要删除主键的原因。
当然这样的更新很麻烦,可以使用$set
属性来配置,这样也不用先查询,如果更新的数据比较少,可用性还是很好的:
PersonModel.update({_id:_id},{$set:{name:'MDragon'}},function(err){});
需要注意,Document
的CRUD
操作都是异步执行,callback
第一个参数必须是err
,而第二个参数各个方法不一样,update
的callback
第二个参数是更新的数量,如果要返回更新后的对象,则要使用如下方法
Person.findByIdAndUpdate(_id,{$set:{name:'MDragon'}},function(err,person){
console.log(person.name); //MDragon
});
类似的方法还有findByIdAndRemove
,如同名字,只能根据id查询并作update
/remove
操作,操作的数据仅一条
新增
如果是Entity
,使用save
方法,如果是Model
,使用create
方法
//使用Entity来增加一条数据
var krouky = new PersonModel({name:'krouky'});
krouky.save(callback);
//使用Model来增加一条数据
var MDragon = {name:'MDragon'};
PersonModel.create(MDragon,callback);
两种新增方法区别在于,如果使用Model
新增时,传入的对象只能是纯净的JSON
对象,不能是由Model
创建的实体,原因是:由Model
创建的实体krouky
虽然打印是只有{name:'krouky'}
,但是krouky
属于Entity
,包含有Schema
属性和Model
数据库行为模型。如果是使用Model
创建的对象,传入时一定会将隐藏属性也存入数据库,虽然3.x
追加了默认严格属性,但也不必要增加操作的报错
删除
和新增一样,删除也有2种方式,但Entity
和Model
都使用remove
方法
基于Entity的子文档操作
如同SQL
数据库中2张表有主外关系,Mongoose
将2个Document
的嵌套叫做Sub-Docs
(子文档)
简单的说就是一个Document
嵌套另外一个Document
或者Documents
:
var ChildSchema1 = new Schema({name:String});
var ChildSchema2 = new Schema({name:String});
var ParentSchema = new Schema({
children1:ChildSchema1, //嵌套Document
children2:[ChildSchema2] //嵌套Documents
});
Sub-Docs
享受和Documents
一样的操作,但是Sub-Docs
的操作都由父类去执行
var ParentModel = db.model('Parent',parentSchema);
var parent = new ParentModel({
children2:[{name:'c1'},{name:'c2'}]
});
parent.children2[0].name = 'd';
parent.save(callback);
parent
在执行保存时,由于包含children2
,他是一个数据库模型对象,因此会先保存chilren2[0]
和chilren2[1]
。
如果子文档在更新时出现错误,将直接报在父类文档中,可以这样处理:
ChildrenSchema.pre('save',function(next){
if('x' === this.name) return next(new Error('#err:not-x'));
next();
});
var parent = new ParentModel({children1:{name:'not-x'}});
parent.save(function(err){
console.log(err.message); //#err:not-x
});
查询子文档
如果children
是parent
的子文档,可以通过如下方法查询到children
var child = parent.children.id(id);
新增、删除、更新
子文档是父文档的一个属性,因此按照属性的操作即可,不同的是在新增父类的时候,子文档是会被先加入进去的。
如果ChildrenSchema
是临时的一个子文档,不作为数据库映射集合,可以这样:
var ParentSchema = new Schema({
children:{
name:String
}
});
//其实就是匿名混合模式
Last updated
Was this helpful?