1

我正在尝试在整个集合中保存具有唯一属性的文档。

因此,如果有人试图用 {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);
        }
    }));
}
4

2 回答 2

1

您的示例几乎可以按原样运行,但有一些拼写错误和范围问题。

第一次调用时kitten.save,回调的参数是kitten. 问题是 localkitten参数掩盖了 external 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”等。

于 2013-03-28T17:25:21.500 回答
0

在 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.");
        }
    }));    
});

找到名称和使用它之间可能存在竞争条件,但我认为我可以忍受。

于 2013-03-28T18:26:06.307 回答