在Mongoose中创build具有唯一属性的文档

我正在尝试在集合中保存具有独特属性的文档。

所以,如果有人试图用{name:'kitty'}保存一只小猫,而且这个名字已经存在,它将失败,然后重试{name:'kitty1'}(然后'kitty2'等)。

我真的无法弄清楚这样做的好方法,有什么想法吗?

这是我到目前为止(不起作用)。

var kittenSchema = new Schema ({ name: {type: String, index: {unique: true}} }) var Kitten = mongoose.model('Kitten', kittenSchema); var kitten = new Kitten({ name: 'kitty' }); kitten.save(function(err, kitten){ if (err){ saveKitten(kitten, 1, function(err, kitten){ if (err){ console.log("Damn, no kitten"); } else { console.log("New kitten " + kitten.name + "saved."); }); } else { console.log("New kitten " + kitten.name + "saved."); } })); function saveKitten(kitten, count, callback){ kitten.name = kitten.name + count; kitten.save(function(err, newKitten){ if (err){ if (count > 100){ // Give up! callback(err, null); } saveKitten(kitten, count + 1, callback); } else { callback(null, newKitten); } })); } 

你的例子几乎可以正常工作,但是有一些错别字和一个范围问题。

你第一次打电话给kitten.save ,你的callback的参数是kitten 。 问题是本地kitten参数会影响外部kitten ,并且在发生错误的情况下,本地kittenundefined

 var kittenSchema = new mongoose.Schema ({ name: {type: String, index: {unique: true}} }) var Kitten = mongoose.model('Kitten', kittenSchema); var kitten = new Kitten({ name: 'kitty' }); kitten.save(function(err, newKitten){ if (err){ saveKitten(kitten, 1, function(err, newKitten){ if (err){ console.log("Damn, no kitten"); } else { console.log("New kitten " + newKitten.name + " saved."); } }); } else { console.log("New kitten " + newKitten.name + " saved."); } }); function saveKitten(kitten, count, callback){ kitten.name = kitten.name + count; kitten.save(function(err, newKitten){ if (err){ if (count > 100){ // Give up! callback(err, null); } saveKitten(kitten, count + 1, callback); } else { callback(null, newKitten); } }); } 

还要注意,在这里使用'+'的方式意味着这个代码将插入“kitten”,“kitten1”,“kitten12”,“kitten123”等。

在来自NilsH的指针之后,我想我可能会尝试撤回所有可能的名称冲突,并在本地查找新名称。

像这样的东西:

 var Kitten = mongoose.model('Kitten', kittenSchema); var kitten = new Kitten({ name: 'kitty' }); Kitten.find({name: new RegExp('^'+ kitten.name +'*', "i")}, 'name').exec(function(err, docs){ var tryName = name; var count = 0; while (True){ if (_.indexOf(docs, tryName) != -1){ break; } else { tryName = name + count; } } kitten.name = tryName; kitten.save(function(err, kitten){ if (err){ console.log("Damn, no kitten"); } else { console.log("New kitten " + kitten.name + "saved."); } })); }); 

在find名字和使用名字之间有一种可能的竞争条件,但我认为我可以忍受这一点。