搜索
您的当前位置:首页在mongoose中有关于更新对象的详细介绍

在mongoose中有关于更新对象的详细介绍

时间:2023-11-29 来源:红星娱乐
最近在使用mongoose的时候发现了一个之前一直没注意的知识点,下面这篇文章主要给大家介绍了关于mongoose更新对象的两种方法,通过示例代码将两种方法进行详细的对比,以给大家更好的参考学习,需要的朋友可以参考下。

前言

Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具

那么要使用它,首先你得装上node.js和mongodb,关于mongodb的安装和操作介绍可以参考://www.gxlcms.com/article/80296.htm

演示

描述场景

更新购物车数量与勾选状态

业务逻辑

查询到当前用户的购物车对象Cart,更新前端传递过来的quantity与selected字段

方法一

var _ = require('underscore');Cart.findOneAndUpdate({ _id: req.body.cart._id, user: user }, _.pick(req.body.cart, 'quantity', 'selected'), { new: true }, function(err, updatedCart) { res.send( utils.json({ data: updatedCart }) ); });

注:_.pick相当于

 { quantity: req.body.cart.quantity, selected: req.body.cart.selected }

方法二

var _ = require('underscore');Cart.findOne({ _id: req.body.cart._id, user: user }, function(err, cart) { if (err) { console.log(err); } // 复制对象 _.extend(cart, req.body.cart); cart.save(function(err, updatedCart) { res.send( utils.json({ data: updatedCart }) ); }); });

对比

第一种代码使用findOneAndUpdate只用了一步,更加简洁,适用于更新的字段少且非常明确的场景

第二种先findOne再对entity进行save操作,利用了underscore对象复制,面向整个对象操作更加灵活,适用于字段多且不确定的场景

结论

需求总是在变的,所以我一般采用第二种。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在Angular4中如何实现HTML属性绑定

使用JS如何编写的九九乘法表

使用JS计算买100只鸡问题

小编还为您整理了以下内容,可能对您也有帮助:

mongoose使用之查询篇

mongoose查询使用最基础的方法就是find、findOne方法,前者查询所有满足条件的值,后者取满足条件的某一个值。

mongoose查询条件其实就是在find方法的基础上添加mongodb条件操作符,如 Thing.find().gt('age', 21) 就等同于 Thing.find({age: {$gt: 21}}) ,mongodb条件操作符如下:

查询对象时,对象中存在其他对象的引用,查询出来的引用对象默认是显示引用对象的id,如果需要引用对象的其他属性就需要使用populate方法填充引用对象。

如果对以上知识点不太了解可以参考:

schema.js

有些对象结构比较复杂,属性可能存在多层嵌套关系,有时需要通过对象属性下属的属性查询对象,如通过content的label的值查询Comment

如果二维数组结构为[[]],这样的数组是可以查询,但是填充数组里对象时会有问题

所以需要填充二维数组里的对象时,不能使用这种结构,而应该如schema.js中一样,将里面的数组先作为对象保存

结构如Point,读取point时,需要填充children,而childern的childern也需要填充,使用populate只能填充当前的childern,在schema.js添加:

这样每次查询时,自动为point填充childern

mongoose其实没有多表联合查询的方法,不过我们可以通过多次查询来实现。

通过user的name、post的content查询post:

有时我们也需要对取出来的数据进行再次过滤,而不是通过查询语句查询

通过user的name、post的content、comment的content.main查询post:

怎么理解 Mongoose 的 pre 中间件,还有 path

我曾经翻译过mongoose的文档,并对里面的很多例子进行了实践,虽然不多,一开始也有很多疑惑,但是使用多了,就慢慢知道什么意思了。

8.Middleware中间件

8.1 什么是中间件

中间件是一种控制函数,类似插件,能控制流程中的init、validate、save、remove方法

8.2 中间件的分类

8.2.1 Serial串行

串行使用pre方法,执行下一个方法使用next调用

var schema = new Schema(…);

schema.pre(‘save’,function(next){

//做点什么

next();

});

8.2.2 Parallel并行

并行提供更细粒度的操作

var schema = new Schema(…);

schema.pre(‘save’,function(next,done){

//下一个要执行的中间件并行执行

next();

doAsync(done);

});

8.3 中间件特点

一旦定义了中间件,就会在全部中间件执行完后执行其他操作

使用中间件可以雾化模型,避免异步操作的层层迭代嵌套

8.4 使用范畴

1.复杂的验证

2.删除有主外关联的doc

3.异步默认

4.某个特定动作触发异步任务,例如触发自定义事件和通知

例如,可以用来做自定义错误处理

schema.pre(‘save’,function(next){

var err = new Eerror(‘some err’);

next(err);

});

entity.save(function(err){

console.log(err.message);//some err

});

不知道这看的明不明白,简单的说,中间件就相当于java中的过滤器、,在执行某个方法前,将其拦截住,也有点像AOP中的前置注入。举个简单的例子,当我们要执行save方法时,我们往往需要对存入的数据进行验证,虽然mongoose提供了safe、strict、schematype、default、validaition验证,但是这些验证都没有提供完善的错误处理或者拦截机制,而利用中间件,可以对错误的数据进行拦截、错误处理、修订等等。比如存入的用户名可能带有代码注入,这时候,通过中间件拦截用户名,给与转义,或进行错误提示、日志记录等。经过中间件的拦截,进入到save方法的数据从理想状态下应该是符合规范且完善的。由此看来,safe、strict、schematype、default、validaition本身就是内部提供的中间件。

关于path,其实也是一种中间件,如同xml的path解析,mongoose是针对mongodb数据库的一种orm模型,mongodb是javascript的json数据存储,有的时候,我们并不希望中间件只针对一个操作,而是针对操作对象的某个属性,那么就能使用path快速定位。这个类似于2.x的get和set方法,只是3.x貌似取消了。

3.x相对于2.x来说,有比较大的改进,学习的时候还得有2.x的一些基础方可。

mongoose怎么populate一个对象数组里的某个属性字段

ASchema=newmongoose.Schema({name:String,B:[BSchema]});varBSchema=newSchema({name:String});varCSchema=newSchema({name:String,B:{type:Schema.ObjectId,ref:'BSchema'}});//ThisisOK,butnotonetimemongoosesearch:CSchema.find({name:'C_xxx'}).exec(function(err,docC){docC.forEach(function(o){varBId=o.B;A.findOne({'B._id':BId},{'B.$':1}).exec(function(err,docA){varBname=docA.B[0].name;varCname=docA.name;});});});//wronginpopulate:CSchema.find({name:'C_xxx'}).populate('ASchema.B').exec(function(err,docC){docC.forEach(function(o){varBname=o.B.name;//ERROR:o.BisaobjectId,o.B.nameisundefined//Anamecan'tfind});});

mongoose中的schema.index方法有什么用

TopicSchema.index({create_at: -1});
TopicSchema.index({top: -1, last_reply_at: -1});
TopicSchema.index({last_reply_at: -1});
TopicSchema.index({author_id: 1, create_at: -1});

建索引是为了提高查询速度,要根据实际业务建立索引,太多了也不好,这样更新数据会变慢,因为要更新索引。

mongoose中的schema.index方法有什么用

TopicSchema.index({create_at: -1});
TopicSchema.index({top: -1, last_reply_at: -1});
TopicSchema.index({last_reply_at: -1});
TopicSchema.index({author_id: 1, create_at: -1});

建索引是为了提高查询速度,要根据实际业务建立索引,太多了也不好,这样更新数据会变慢,因为要更新索引。

详解关于mongoose设置unique不生效问题的解决及如何移除unique的限制

本文主要给大家介绍了关于mongoose数据库设置unique不生效问题的解决方法,以及Mongoose如何移除unique的方法示例,文中通过示例代码介绍的非常详细,需要的朋友们可以参考借鉴,下面随着小编来一起学习学习吧。

前言

unique属于schema约束验证中的一员,他的作用主要就是让某一个字段的值具有唯一性(不能重复)

保持字段的唯一性使用type值: {type:String,unique:true,dropDups: true}

注意:mongoose一旦修改了数据存储的机构,数据库一定要重启,很多新手在设置一些属性不生效时都是这个原因

这里说的重启,不是简单的关闭mongoose数据库服务器重新打开,而是先将该数据库整个删除,然后再重启数据库服务

简单的schema特殊用法示例

//导入模块

var mongoose = require('mongoose');

//连接数据库

mongoose.connect('mongodb://localhost/itheima');

//创建schema

//schema第一个参数是我们自定义的数据类型 第二个参数是管理schema默认的数据类型

var studentSchema = mongoose.Schema({

name:{type:String,required:true},//数据类型为string,不能非空

age:{type:Number,default:18},//数据类型为string,默认值18

study_id:{type:Number,select:true},//学号,默认查询字段

address:{type:String,lowercase:true},//地址,默认小写

email:{type:String,match:RegExp(/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/)},//邮箱,正则表达式验证

phone:{type:String,unique:true,dropDups: true}//电话号码唯一性

},{

versionKey: false,//去掉版本锁 __v0

timestamps: { createdAt: 'createTime', updatedAt: 'updateTime' }//自动管理修改时间

});

//创建model

var student = mongoose.model('student',studentSchema);

//创建Entity

var zhangsan = new student({

name:'zhangsan',//名字必须要有,否则会报错: name: Path `name` is required.

address:'ZhongLiang',//字符串都会变成小写

email:'a12345@qq.com',//邮箱格式不对,添加会报错 Path `email` is invalid (a12345qq.com).

study_id:2017001,

phone:'123456789'//在添加唯一性字段时,mongoose会先查询数据库所有的phone值,一旦发现该值已存在则会报错

});

//添加数据

student.create(zhangsan,function(err){

if(err){

throw err;

}

console.log('插入成功' + zhangsan);

});Mongoose 移除unique的

程序中email最开始设置了unque,导致email在此collection中无法重复插入,现在想要移除unique。

db.your_collection.dropIndexes();

关于NodeJs为什么要用mongoose操作mongodb

为了防止刷新得太快,或者多个用户同时访问数据库,数据库没来得及关闭。

可以做一下实验,在访问数据库的页面按住F5,就会很容易看到在页面上或者控制台上抛出的Error勒

用mongoose就不会出现这错误勒,因为一旦连接好数据库,db就会处于open状态,不存在访问时要打开,然后又要关闭的规则,然后我果断把所有mongodb部分改为mongoose,按住F5毫无压力啊,而且尼玛代码又短了一大截!

前后代码对比一下:

之前每次操作要open:

User.get = function get(username, callback) {

mongodb.open(function(err, db) {

if (err) {

return callback(err);

}

//读取 users 集合

db.collection('users', function(err, collection) {

if (err) {

mongodb.close();

return callback(err);

}

//查找 name 属性为 username 的文档

collection.findOne({name: username}, function(err, doc) {

mongodb.close();

if (doc) callback (err, doc);

else callback (err, null);

});

});

});

};

现在,建立好mongoose对象模型后只需几行代码即可实现相同的功能:

User.get = function get(username, callback) {

users.findOne({name:username}, function(err, doc){

if (err) {

return callback(err, null);

}

return callback(err, doc);

});

};

红星娱乐还为您提供以下相关内容希望对您有帮助:

mongoose是什么意思?

Mongoose是一种流行的开源对象文档映射(ODM)库,用于在Node.js环境中管理MongoDB数据库。它提供了一种简单而优雅的方式来定义数据模型,并提供了非常便利的API对MongoDB进行操作。Mongoose被广泛应用于构建各种Node.js Web应用...

mongoose怎么populate一个对象数组里的某个属性字段

ASchema=newmongoose.Schema({name:String,B:[BSchema]});varBSchema=newSchema({name:String});varCSchema=newSchema({name:String,B:{type:Schema.ObjectId,ref:'BSchema'}});//ThisisOK,butnotonetimemongoosesearc...

详解关于mongoose设置unique不生效问题的解决及如何移除unique的...

前言unique属于schema约束验证中的一员,他的作用主要就是让某一个字段的值具有唯一性(不能重复)保持字段的唯一性使用type值: {type:String,unique:true,dropDups: true}注意:mongoose一旦修改了数据存储的机构,数据库一定...

mongoose使用之查询篇

mongoose查询条件其实就是在find方法的基础上添加mongodb条件操作符,如 Thing.find().gt('age', 21) 就等同于 Thing.find({age: {$gt: 21}}) ,mongodb条件操作符如下:查询对象时,对象中存在其他对象的引用,查询...

怎么理解 Mongoose 的 pre 中间件,还有 path

关于path,其实也是一种中间件,如同xml的path解析,mongoose是针对mongodb数据库的一种orm模型,mongodb是javascript的json数据存储,有的时候,我们并不希望中间件只针对一个操作,而是针对操作对象的某个属性,那么就能使用path...

关于NodeJs为什么要用mongoose操作mongodb

现在,建立好mongoose对象模型后只需几行代码即可实现相同的功能:User.get = function get(username, callback) { users.findOne({name:username}, function(err, doc){ if (err) { return callback(err, null);} re...

使用three.js如何实现3D影院

1.创建一个3d的空间可以想象一下我们在房间内,房间是一个立方体,如果你有生活品味,可能会在房间内贴上壁纸,three.js可以很方便的创建一个立方体,并且给它的周围贴上纹理,让照相机在立方体之中,照相机可以360旋转,就...

mongoose exec和find的区别

而加上.exec()则将会返回成为一个完整的 promise 对象,但是其是 mongoose 自行封装的 promise ,与 ES6 标准的 promise 是有所出入的(你应该会在控制台看到相关的警告),而且官方也明确指出,在未来的版本将会废除自行...

nodejs 连接mongoose 报错 connect ECONNREFUSED怎么解决

它是一个MongoDB对象建模工具(object modeling tool),以前在sails上用的Waterline是ORM (Object Relational Mapper)。当使用Mongoose时,不在需要在数据库中创建好结构(Schema)之后,再与后端代码中 ...

如何使用iphone搭建httpserver

它的使用非常简单,你可以直接在项目中以源代码的方式引用。使用Mongoose时,首先要#import "MongooseDaemon.h",然后在应用程序委托中声明一个MongooseDaemon对象:MongooseDaemon *mongooseDaemon;在应用程序委托的application...

Top