2014-10-27 58 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 }

如何在我的集合上創建持久性唯一索引,以便我從不重複?在這個簡單的啓動例程之後,我會不斷地寫在這張表上,每次寫入後我是否必須重新創建一個索引?更多的研究後

更新:

我在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

是的,這是糾正索引中的錯字(我相信是從文檔copypasted)後工作。謝謝! – xShirase 2014-10-27 09:44:06