猫鼬模型保存错误E11000

时间:2014-11-28 23:21:58

标签: node.js mongodb mongoose

我有以下架构:

var loftSchema = new mongoose.Schema({
    name        : { type: String, trim: true, required: true },
    location    : { type: { type: String, enum: 'Point', default: 'Point'}, coordinates: { type:      [Number], default: [0,0] } },
    radius      : { type: Number, required: true },
    private     : { type: Boolean, required: true },
    created     : { type: Date, default: Date.now },
    updated     : { type: Date, default: Date.now },
    members     : [{ type: mongoose.Schema.ObjectId, ref: 'Users'}],
    posts       : [{ type: mongoose.Schema.ObjectId, ref: 'Posts'}]
});

请注意,成员和帖子都是对其他Mongoose Schema的引用。 下面是我用来创建Loft对象的函数。

function createLoft(req, res) {
    var params = req.body;
    var deferred = q.defer();

    var form = new multiparty.Form();
    var image, lat, lon, name, radius, private, path, creatorID;

    form.on('file', function(name, file){
        path = file.path;
    });

    // listen on field event for title
    form.on('field', function(key, value){
        if(key == "lat"){
            lat = value;
        }else if(key == "lon"){
            lon = value;
        }else if(key == "name"){
            name = value;
        }else if(key == "radius"){
            radius = value;
        }else if(key == "creator_id"){
            creatorID = value;
        }else if(key == "private"){
            private = value;
        }else return;
    });

    // listen on part event for image file
    form.on('part', function(part){
         if (!part.filename) return;
         if (part.name !== 'image') return part.resume();
         image = {};
         image.filename = part.filename;
         image.size = 0;
         part.on('data', function(buf){
           image.size += buf.length;
         });
    });

    form.on('close', function(){
        var response = { "status": 200, "created": null };
        var created = new Loft({
            name: name,
            location: { type: 'Point', coordinates: [lat, lon] },
            radius: radius,
             private:private
        });
        response.created = created;
        created.members = [creatorID];
        created.attach('image', {'path': path}, function(err){
            if(err){
                response.status = 500;
                response.created = err;
                 deferred.resolve(response);
                 return;
            }else {
                response.created = created;
                created.save(function (err, object) {
                    if (err) {
                        response.status = 400;
                        response.created = err;
                    }
                    deferred.resolve(response);
                });
             }
         });   
    });
    // parse the form
    form.parse(req);

    return deferred.promise;
}

我从客户端(iOS)进行分段上传并解析服务器上的表单。我第一次创建一个阁楼时,一切都很好,我可以添加相应的用户ID作为该组的第一个成员。但是,如果我第二次尝试这个电话,我会回复:

{
  "name": "MongoError",
  "code": 11000,
  "err": "insertDocument :: caused by :: 11000 E11000 duplicate key error index:    loft.lofts.$creator_id_1 dup key: { : null }"
}

我的目标是能够创建与MongoDB生成的_id字段几乎完全相同的Lofts。每当我尝试创建一个类似的阁楼时,我都会抛出这个错误。反正有没有规避那个?这个错误甚至意味着什么?

1 个答案:

答案 0 :(得分:1)

这意味着您的lofts集合的creator_id字段被设置为唯一索引。但是我没有在你的架构上看到它。我可能会错过它,或者你可能改变了你的架构并且习惯了它?不能获得此错误的唯一方法是删除该唯一索引要求。如果修复您的代码不成功,您可能必须使用shell重新索引mongo。

使用mongo登录终端中的shell,然后键入use loft以切换数据库。您可以使用db.lofts.getIndexes()查看索引 - 您可能会看到creator_id字段。您可以使用db.lofts.reIndex()

强制重新索引

您需要评估您的代码,因为creator_id可能需要是一个唯一字段,但您可以根据自己的需要来确定。