在NodeJS中使用Mongoose+Mockgoose更新时忽略了唯一索引
Unique index ignored when updating with Mongoose + Mockgoose in NodeJS
我目前在NodeJS应用程序中使用Mongoose ODM管理与MongoDB的数据库连接,并在Mocha测试中使用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);
当在测试中从我的控制器调用Gallery.update(conditions, data, opts)
时,故意将slug
设置为另一个的副本,它会更新文档,然后我得到两个具有相同slug
路径的文档。
仅供参考,我已经找到了一种方法,使用save()
函数来代替它,它似乎毫无疑问地遵循了唯一索引。
然而,由于我更喜欢使用update()
而不是save()
(即每次更新部分文档而不是整个文档),我很想知道是否有其他人也遇到过同样的问题,以及您是如何克服的?
该应用程序遵循基于MEAN.js的标准MVC模式,因此它不仅仅是一个模型,但如果我遗漏了任何可能有用的内容,请告诉我。
更新
在查看了Mockgoose NPM模块的源代码后,我可以确认在运行update()时从未执行过针对模式的验证。此处记录了一个问题:http://www.github.com/mccormicka/Mockgoose/issues/58
可能您正在测试挂钩中使用mockgoose.reset
(例如afterEach
)。它会删除数据库,并且在执行过程中不会再次创建索引。
解决方案是单独删除模型。
添加到Diego的帖子中。在测试挂钩中调用mockgoose.helper.reset()
以可能清除临时存储中的集合也会删除索引。您应该在使用下面的代码段调用reset之后重置索引。
await mockgoose.helper.reset()
const db = mongoose.connection
db.modelNames().map(async (model) => {
await db.models[model].createIndexes()
})
这为我解决了问题。希望这能有所帮助。
来自猫鼬文档
当你的应用程序启动时,Mongoose会自动调用模式中每个定义索引的ensureIndex。Mongoose会呼叫依次为每个索引设置ensureIndex,并在上发出"index"事件所有ensureIndex调用成功时的模型,或者错误。
虽然对开发来说很好,但建议使用这种行为在生产中被禁用,因为创建索引可能会导致性能影响。通过设置autoIndex禁用行为将您的模式选项设置为false,或通过将选项config.autoIndex设置为false。
由于mongoose在启动时设置了索引,您需要调试特定的错误,为什么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
没有像mongoose文档中提到的那样设置为false,或者最好像上面所做的那样显式设置为true。
此外,
mongoose.set('debug', true);
调试日志将显示它为您创建索引而进行的ensureIndex
调用。
- 名称输入的索引
- 在jQuery中获取表的行索引
- 测试索引值是否等于某个数字的倍数
- 循环遍历数组中的特定索引
- 按照选项卡索引的顺序循环一个jQuery选择
- 在JavaScript中通过索引从对象数组中获取值
- 尝试在PHP中回显输入文本时出现未定义的索引错误
- 在索引.html和应用.js [node.js] 之间共享变量
- 如何为高图中的区域线创建z索引
- 下拉列表在使用z索引放置在前面后停止工作
- 使用onkeyup JS事件检查输入的值是否唯一
- 复合唯一索引
- E11000 重复键错误索引:创建唯一索引时
- 唯一索引不适用于猫鼬架构
- 猫鼬唯一索引不起作用
- 在NodeJS中使用Mongoose+Mockgoose更新时忽略了唯一索引
- 表示多个数组的唯一索引的数字
- Vue.js在我的对象数组中使用唯一 id 来获取我的对象的索引
- 分配,在主索引页上为脚本使用唯一的Wordpress帖子id
- 如何在插入违反唯一索引的MongoDB文档时捕获错误