2014-10-27 2 views
0

Отказ от ответственности: Я использую мангуст менее чем за 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 }

Как создать постоянный уникальный индекс в моей коллекции, чтобы у меня НИКОГДА не было дубликатов? После этой простой процедуры запуска я буду писать на этой таблице постоянно, мне нужно воссоздать индекс после каждой записи?

Update после дополнительных исследований:

У меня нет никаких дубликатов в 308 адресах, которые я пишу, и я начинаю с пустым дб.

ответ

1

Вы можете определить индекс уникальным:

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); 
     } 
    ); 
} 
+0

yup, который работает после исправления опечатки в индексе (который, я считаю, был скопирован из документов). Благодаря! – xShirase

Смежные вопросы