我目前正在使用mongoose
和mongoose-unique-validator
来将unique
的索引强制到某个字段,以避免重复的值。我已经知道unique
在mongoose
中是如何工作的,所以我决定使用mongoose-unique-validator
来简化开发
但是,在删除文档并在unique
字段中插入具有相同值的新文档后,查询被拒绝,并出现重复错误。
这是有问题的模式
export const categorySchema = new Schema({
name: {
type: String,
unique: true,
trim: true,
required: true,
index: true,
maxlength: 25,
},
desc: {
type: String,
trim: true,
required: true,
maxlength: 100,
},
}, {
versionKey: false,
});
categorySchema.plugin(uniqueValidator);
export const Category = model<CategoryDocument>(
'Category',
categorySchema,
);
据我所知,mongoDB总是在update
和delete
之后更新索引。所以,我没想到会有这个结果。
任何帮助将不胜感激。谢谢。
编辑:这是错误日志
MongoError: E11000 duplicate key error dup key: { : "Category 1" }
at Function.create (node_modules\mongoose\node_modules\mongodb\lib\core\error.js:44:12)
at toError (node_modules\mongoose\node_modules\mongodb\lib\utils.js:150:22)
at coll.s.topology.insert (node_modules\mongoose\node_modules\mongodb\lib\operations\common_functions.js:265:39)
at handler (node_modules\mongoose\node_modules\mongodb\lib\core\sdam\topology.js:971:24)
at wireProtocol.(anonymous function) (node_modules\mongoose\node_modules\mongodb\lib\core\sdam\server.js:496:5)
at C:\Users\Namchee\Desktop\brita\node_modules\mongoose\node_modules\mongodb\lib\core\connection\pool.js:420:18
at process._tickCallback (internal/process/next_tick.js:61:11)
EDIT2:实际的测试脚本(省略了相关性)
const expect = chai.expect;
before(async () => {
const mongod = new MongoMemoryServer();
mongoose.Promise = Promise;
const uri = await mongod.getConnectionString();
const mongooseOpts = {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
};
await mongoose.connect(uri, mongooseOpts);
// clear it before test
await Promise.all([
Announcement.deleteMany({}),
Category.deleteMany({}),
]);
});
after(async () => {
// clear it after testing
await Promise.all([
Announcement.deleteMany({}),
Category.deleteMany({}),
]);
mongoose.disconnect();
});
describe('Announcement repository test', () => {
let category1;
let category2;
let announcement1;
let announcement2;
const announcementRepository = new AnnouncementRepositoryMongo(
Announcement,
);
before(async () => {
const categoryFetch = await Category.find();
console.log(categoryFetch); // empty
const category = await Category.create(
{
name: 'Category 1',
desc: 'This is category 1',
},
{
name: 'Category 2',
desc: 'This is category 2',
},
); // error when trying to execute this
category1 = category[0];
category2 = category[1];
const announcements = await Announcement.create(
{
title: faker.random.word(),
content: faker.random.words(10),
validUntil: faker.date.recent(),
important: false,
categories: [category1, category2],
},
{
title: faker.random.word(),
content: faker.random.words(15),
validUntil: faker.date.recent(),
important: true,
categories: [category1],
},
);
announcement1 = announcements[0];
announcement2 = announcements[1];
});
describe('findAll', () => {
it('should return all announcements', async () => {
const spy = sinon.spy(Announcement, 'find');
const announcements = await announcementRepository.findAll();
spy.restore();
expect(spy.calledOnce).to.be.true;
expect(announcements.length).to.equal(2);
expect(announcements[0].id.toString())
.to.equal(announcement1.id.toString());
expect(announcements[1].id.toString())
.to.equal(announcement2.id.toString());
});
});