防止猫鼬中的重复记录
Preventing duplicate records in Mongoose
我是 MongoDb / Mongoose 的新手,更习惯于 SQL Server 或 Oracle。
我有一个相当简单的事件架构。
EventSchema.add({
pkey: { type: String, unique: true },
device: { type: String, required: true },
name: { type: String, required: true },
owner: { type: String, required: true },
description: { type: String, required: true },
});
我正在查看 Mongoose Indexes,其中显示了两种实现方式,我使用了字段定义。
我还有一个非常简单的 API,它接受 POST 并在此集合上调用创建以插入记录。
我编写了一个测试来检查插入具有相同 pkey 的记录是否应该发生并且 unique:true 是否正常运行。我已经有一组事件读入数组,所以我只是再次 POST 这些事件中的第一个,看看会发生什么,我预计 mongo DB 会抛出 E11000 重复键错误,但是这没有发生。
var url = 'api/events';
var evt = JSON.parse(JSON.stringify(events[0]));
// POST'ed new record won't have an _id yet
delete evt._id;
api.post(url)
.send(evt)
.end(err, res) {
err.should.exist;
err.code.should.equal(11000);
});
测试失败,没有错误,插入了重复的记录。
当我查看集合时,我可以看到两条记录,它们都具有相同的 pkey(原始记录和我为测试发布的副本)。我确实注意到第二条记录的创建日期与第一条记录的创建日期相同,但修改日期晚了。
(mongo是不是希望我使用最新的修改版本记录???,URL不一样,ID也不一样)
[ { _id: 2,
pkey: '6fea271282eb01467020ce70b5775319',
name: 'Event name 01',
owner: 'Test Owner',
device: 'Device X',
description: 'I have no idea what\'s happening',
__v: 0,
url: '/api/events/2',
modified: '2016-03-23T07:31:18.529Z',
created: '2016-03-23T07:31:18.470Z' },
{ _id: 1,
pkey: '6fea271282eb01467020ce70b5775319',
name: 'Event name 01',
owner: 'Test Owner',
device: 'Device X',
description: 'I have no idea what\'s happening',
__v: 0,
url: '/api/events/1',
modified: '2016-03-23T07:31:18.470Z',
created: '2016-03-23T07:31:18.470Z' }
]
我假设 unique: true 在字段定义上告诉 mongo db 这就是你想要的并且 mongo 在保存时为你强制执行,或者也许我只是误解了一些东西......
在 SQL 术语中,您创建一个可用于 URL 查找的键,但您可以构建一个唯一的复合索引,以防止重复插入。我需要能够定义事件中的哪些字段使记录唯一,因为在表单数据 POST 上,表单提交者没有下一个可用的 _id 值,但使用 _id(由 [=42 完成=]) 这样 URL 在应用程序其他部分的使用是干净的,例如
/events/1
而不是像
这样一团糟的复合值
/events/Event%20name%2001%5fDevice%20X%5fTest%20Owner
我正要开始编写代码,所以现在我只是针对这个单个字符串编写了一个简单的测试,但真正的模式有更多的字段,并将使用它们的组合来实现唯一性,我真的想要在开始添加更多测试、更多字段和更多代码之前让初始测试正常工作。
我应该做些什么来确保第二条记录实际上没有被插入?
添加:
EventSchema.index({ pkey: 1 }, { unique: true });
好的,这看起来与索引在发布第二个插入之前没有时间更新有关(因为在我的测试套件中它们之间只有 9 毫秒)。
- 需要对等待 "index"
的插入做些什么
- 需要 API 端,因为并非 API 的所有用户都是 Web 应用程序
我还找到了其他一些关于约束的 SO 文章:
mongoose unique: true not work
Unique index not working with Mongoose / MongoDB
MongoDB/Mongoose unique constraint on Date field
在数据库中插入一些记录后,您似乎已经完成了唯一索引(在模式级别)。
请按照以下步骤避免重复 -
1) 删除你的数据库:
$mongo
> use <db-name>;
> db.dropDatabase();
2) 现在在架构级别或数据库级别进行索引
var EventSchema = new mongoose.Schema({
pkey: { type: String, unique: true },
device: { type: String, required: true },
name: { type: String, required: true },
owner: { type: String, required: true },
description: { type: String, required: true },
});
它将避免重复插入具有相同 pKey 值的记录。
为了确保索引,使用命令db.db_name.getIndexes()
。
希望对您有所帮助。
谢谢
在 mongoose.connect 添加 {useCreateIndex: true}
它应该是这样的
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
})
// Rebuild all indexes
await User.syncIndexes();
我是 MongoDb / Mongoose 的新手,更习惯于 SQL Server 或 Oracle。
我有一个相当简单的事件架构。
EventSchema.add({
pkey: { type: String, unique: true },
device: { type: String, required: true },
name: { type: String, required: true },
owner: { type: String, required: true },
description: { type: String, required: true },
});
我正在查看 Mongoose Indexes,其中显示了两种实现方式,我使用了字段定义。
我还有一个非常简单的 API,它接受 POST 并在此集合上调用创建以插入记录。
我编写了一个测试来检查插入具有相同 pkey 的记录是否应该发生并且 unique:true 是否正常运行。我已经有一组事件读入数组,所以我只是再次 POST 这些事件中的第一个,看看会发生什么,我预计 mongo DB 会抛出 E11000 重复键错误,但是这没有发生。
var url = 'api/events';
var evt = JSON.parse(JSON.stringify(events[0]));
// POST'ed new record won't have an _id yet
delete evt._id;
api.post(url)
.send(evt)
.end(err, res) {
err.should.exist;
err.code.should.equal(11000);
});
测试失败,没有错误,插入了重复的记录。
当我查看集合时,我可以看到两条记录,它们都具有相同的 pkey(原始记录和我为测试发布的副本)。我确实注意到第二条记录的创建日期与第一条记录的创建日期相同,但修改日期晚了。
(mongo是不是希望我使用最新的修改版本记录???,URL不一样,ID也不一样)
[ { _id: 2,
pkey: '6fea271282eb01467020ce70b5775319',
name: 'Event name 01',
owner: 'Test Owner',
device: 'Device X',
description: 'I have no idea what\'s happening',
__v: 0,
url: '/api/events/2',
modified: '2016-03-23T07:31:18.529Z',
created: '2016-03-23T07:31:18.470Z' },
{ _id: 1,
pkey: '6fea271282eb01467020ce70b5775319',
name: 'Event name 01',
owner: 'Test Owner',
device: 'Device X',
description: 'I have no idea what\'s happening',
__v: 0,
url: '/api/events/1',
modified: '2016-03-23T07:31:18.470Z',
created: '2016-03-23T07:31:18.470Z' }
]
我假设 unique: true 在字段定义上告诉 mongo db 这就是你想要的并且 mongo 在保存时为你强制执行,或者也许我只是误解了一些东西......
在 SQL 术语中,您创建一个可用于 URL 查找的键,但您可以构建一个唯一的复合索引,以防止重复插入。我需要能够定义事件中的哪些字段使记录唯一,因为在表单数据 POST 上,表单提交者没有下一个可用的 _id 值,但使用 _id(由 [=42 完成=]) 这样 URL 在应用程序其他部分的使用是干净的,例如
/events/1
而不是像
这样一团糟的复合值/events/Event%20name%2001%5fDevice%20X%5fTest%20Owner
我正要开始编写代码,所以现在我只是针对这个单个字符串编写了一个简单的测试,但真正的模式有更多的字段,并将使用它们的组合来实现唯一性,我真的想要在开始添加更多测试、更多字段和更多代码之前让初始测试正常工作。
我应该做些什么来确保第二条记录实际上没有被插入?
添加:
EventSchema.index({ pkey: 1 }, { unique: true });
好的,这看起来与索引在发布第二个插入之前没有时间更新有关(因为在我的测试套件中它们之间只有 9 毫秒)。
- 需要对等待 "index" 的插入做些什么
- 需要 API 端,因为并非 API 的所有用户都是 Web 应用程序
我还找到了其他一些关于约束的 SO 文章:
mongoose unique: true not work
Unique index not working with Mongoose / MongoDB
MongoDB/Mongoose unique constraint on Date field
在数据库中插入一些记录后,您似乎已经完成了唯一索引(在模式级别)。
请按照以下步骤避免重复 -
1) 删除你的数据库:
$mongo
> use <db-name>;
> db.dropDatabase();
2) 现在在架构级别或数据库级别进行索引
var EventSchema = new mongoose.Schema({
pkey: { type: String, unique: true },
device: { type: String, required: true },
name: { type: String, required: true },
owner: { type: String, required: true },
description: { type: String, required: true },
});
它将避免重复插入具有相同 pKey 值的记录。
为了确保索引,使用命令db.db_name.getIndexes()
。
希望对您有所帮助。 谢谢
在 mongoose.connect 添加 {useCreateIndex: true}
它应该是这样的
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
})
// Rebuild all indexes
await User.syncIndexes();