如何在MongoDB中创建持久唯一索引
问题描述:
声明:我使用猫鼬的时间少于48小时。如何在MongoDB中创建持久唯一索引
我有一个模型,看起来像这样:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Schema definition
var CategorySchema = new Schema({
name: String,
url: { type: [String], index: true },
extra: Array,
frequency: Number,
last_processed: Date
});
// Model definition
var Category = mongoose.model('categories', CategorySchema);
当我的应用程序启动,它有一个方法来自动更新集合,使用结构类似于以下(js文件一个js文件,该文件是不我的控制之下):
var categories = {
retailer: 'ret1',
name: 'c1',
url: 'url1',
extra: ['tag1'],
frequency: 2,
last_processed: ''
}, {
retailer: 'ret2',
name: 'c2',
url: 'url2',
extra: ['tag2'],
frequency: 2,
last_processed: ''
},
........
];
module.exports = categories;
我创建使用循环记录:
var Category = mongoose.model('categories');
for (var j = 0; j < categories.length; j++) {
new Category(categories[j]).save();
}
我的问题是这样的:
当我启动我的应用程序在第一时间,db.categories.count()= 308(因为它应该是)。如果我关闭应用程序并重新启动,count()= 616,所以它复制记录。我认为使用索引可以避免这种行为,但显然不是。关于索引的文档并不清楚,来自RDB背景。我在调试中看到索引已创建:Mongoose: categories.ensureIndex({ url: 1 }) { safe: undefined, background: true }
如何在我的集合上创建持久性唯一索引,以便我从不重复?在这个简单的启动例程之后,我会不断地写在这张表上,每次写入后我是否必须重新创建一个索引?更多的研究后
更新:
我在308周的网址我写不重复,我从一个空数据库启动。
答
您可以定义唯一索引:
var CategorySchema = new Schema({
name: String,
url: {
type: String,
index: {
unique: true
}
},
extra: Array,
frequency: Number,
last_processed: Date
});
然后,给你一个回调添加到save()
for (var j = 0; j < categories.length; j++) {
new Category(categories[j]).save(function(err, doc) {
console.error(err);
});
}
您将看到以下印刷
{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.categories.$url_1 dup key: { : "url2" }]
name: 'MongoError',
code: 11000,
err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.categories.$url_1 dup key: { : "url2" }' }
你可以使用findOneAndUpdate
其中,给出选项upsert: true
,woul d创建或更新对象。如果您不想更新,但只是跳过,因为使用save()
的类别可能足够好。
for (var j = 0; j < categories.length; j++) {
Category.findOneAndUpdate(
{ url: categories[j].url },
categories[j],
{ upsert: true },
function(err, doc) {
console.error(err);
}
);
}
是的,这是纠正索引中的错字(我相信是从文档copypasted)后工作。谢谢! – xShirase 2014-10-27 09:44:06