mongoose克隆对象的问题

来源:互联网 发布:网络电视怎么连接wifi 编辑:程序博客网 时间:2024/05/22 11:18

mongoose克隆对象的问题

  • mongoose克隆对象的问题
    • 问题说明
    • 研读mongoose源代码
    • 经验教训
    • 附录完整的测试用例

@(技术笔记)[mongodb]

问题说明

通过mongoose进行克隆一个对象,就跟如何把大象放到冰箱一样,分为三步
1. 查到docoment
2. 修改docoment的id;
3. 存docoment

代码如下,运行过程没有异常,但是在数据库中却找不到对应记录。更诡异的是,升级mongoose版本前还是好好的!

var mongoose = require('mongoose');mongoose.connect('mongodb://localhost/test');var Cat = mongoose.model('Cat', {name: String});new Cat({name: '123'}).save(function (err, doc) {    var cloneObj = doc;    cloneObj._id = new Cat()._id;//修改Id;    new Cat(cloneObj).save(function (err, doc) {        Cat.findOne({_id:doc._id},function(err,doc2){            console.log(doc2);        })    });})

比较了升级前后的mongoose版本,发现一个是mongoose@4.3.x,一个是mongoose@4.4.x。

研读mongoose源代码

原来在mongoose@4.4.x版本中,lib/docment.js的下列代码,this.isNew这段代码是在4.4新增的
这里写图片描述
在lib/model.js中,当执行save操作时,判断this.isNew,如果值为false,执行update操作
Alt text
其中where = this.$__where(delta[0]) 再来看看delta[0]是什么?
这里写图片描述
那么where条件:_id =xxx
至此一切都清楚了,我们把docoment用一个新的id赋值,在更新时根据这个mongoose做了一些优化处理,用这个id取进行更新操作。那么数据库什么没有执行就返回了,没有报错,但是结果没有宝座。

这就解释了mongoose@4.3能正常执行的代码,由于mongoose4.4做了优化,反而不能正常执行的原因了。

经验教训

针对不同mongoose版本的问题,保险的做法,克隆时要调用toObject()做转换

    var cloneObj = doc.toObject();

附录,完整的测试用例

通过mocha执行

var mongoose = require('mongoose');var assert = require('assert');mongoose.connect('mongodb://localhost/test');var Cat = mongoose.model('Cat', {name: String});var objDb;describe('test clone document by mongoose', function () {    it('create obj', function (done) {        new Cat({name:'123'}).save(function(err,doc){            assert(!err);            assert(doc);            Cat.findOne({_id:doc._id},function(err,doc2){                assert(!err);                assert(doc2);                objDb = doc2;                done();            })        });    });    it('clone obj by modified _id(mongoose@4.3.3 supported,>=4.4 not supported)', function (done) {        var cloneObj = objDb;        cloneObj._id = new Cat()._id;//修改Id;        new Cat(cloneObj).save(function(err,doc){            assert(!err);            assert(doc);            Cat.findOne({_id:doc._id},function(err,doc2){                assert(!err);                assert(doc2);                done();            })        });    });    it('clone obj after toObject(), function (done) {        var cloneObj = objDb.toObject();        cloneObj._id = new Cat()._id;//修改Id;        new Cat(cloneObj).save(function(err,doc){            assert(!err);            assert(doc);            Cat.findOne({_id:doc._id},function(err,doc2){                assert(!err);                assert(doc2);                done();            });        });    });});
0 0
原创粉丝点击