使用NodeJS中的Mongoose + Mockgoose更新时忽略唯一索引

我目前正在使用Mongoose ODM来pipe理NodeJS应用程序到MongoDB的数据库连接,并在Mochatesting中使用Mockgoose拦截连接。 我遇到了在执行文档更新时忽略唯一索引的问题。 我只是用另一个叫Mongoose-bird的软件包来包装Mongoose,它只是允许使用promise。

一个模式特别如下:

// Gallery.js 'use strict'; var mongoose = require('mongoose-bird')(require("mongoose")); var Schema = mongoose.Schema; var ObjectId = Schema.Types.ObjectId; var deepPopulate = require('mongoose-deep-populate')(mongoose); var GallerySchema = new Schema({ _id: ObjectId, type: String, title: String, slug: String, _albums: [{ type: ObjectId, ref: 'Albums' }] }); GallerySchema.index({ slug: 1 }, { unique: true }); GallerySchema.plugin(deepPopulate, {}); mongoose.model('Galleries', GallerySchema); 

当在testing中调用我的控制器中的Gallery.update(conditions, data, opts) ,故意将slug设置为另一个副本,它会更新文档,然后最终得到两个具有相同slugpath的文档。

仅供参考,通过使用save()函数,我find了解决这个问题的办法,它似乎遵从唯一索引而没有任何问题。

但是,因为我更喜欢使用save()来更新save() (即每次更新文档而不是整个文档),所以我很想知道是否有其他人有过这个相同的问题,战胜它?

应用程序遵循一个基于MEAN.js的标准MVC模式,所以比起一个模型还要多一点,但是如果我遗漏了可能有用的东西,请告诉我。

更新
在查看Mockgoose NPM模块的源代码之后,我可以确认在运行update()时从不执行对模式的validation。 有一个问题logging在这里: http : //www.github.com/mccormicka/Mockgoose/issues/58

从mongoose的文档

当您的应用程序启动时,Mongoose将自动为您的模式中定义的每个索引调用ensureIndex。 Mongoose将依次为每个索引调用ensureIndex,并在所有ensureIndex调用成功或出现错误时在模型上发出“索引”事件。

尽pipe对开发很好,但build议在生产中禁用此行为,因为索引创build可能会对性能产生重大影响。 通过将模式的autoIndex选项设置为false来禁用此行为,或通过将选项config.autoIndex设置为false来在连接上全局禁用此行为。

因为,mongoose在开始时设置索引,你必须debugging具体的错误,为什么mongoDb不允许索引,使用下面的代码

 //keeping autoIndex to true to ensure mongoose creates indexes on app start GallerySchema.set('autoIndex', true); //enable index debugging GallerySchema.set('emitIndexErrors', false); GallerySchema.on('error', function(error) { // gets an error whenever index build fails }); GallerySchema.index({ slug: 1 }, { unique: true }); 

此外,请确保autoIndex文档中提到的autoIndex未设置为false,或者更好地将它设置为true,如上所述。

Additonally,

 mongoose.set('debug', true); 

debugging日志logging将显示您正在为您创build索引的ensureIndex调用。

可能你在testing钩子中使用mockgoose.reset (例如afterEach )。 它会删除数据库,并且在执行过程中不会再创build索引。

解决scheme是单独删除模型。