Mongodb:如果值不存在,如何向数组添加值,但如果值存在则更新值

时间:2016-12-29 12:05:19

标签: mongodb mongoose

Subdishes是MajorFood项目中的一个数组。如果它们不存在,我想添加子目录,如果它们存在则更新子目录。

我尝试使用addToSet进行更新。这适用于普通元素但对于数组失败。

                MajorFood.update({'_id' : majorFoodId, 'subdishes.food' : rowVals[0]},
                {$addToSet : {subdishes : {
                    food : rowVals[0],
                    energy : {
                        calories : s.getIntVal(rowVals[1]),
                        unit : rowVals[2]
                    }           
                }}}, {upsert : true}, function(err, doc){
                if(err){
                    s.l("err update" );
                    callback(err);
                    return;
                }
                s.l("success");
                callback(); 
            });

当子菜单中已存在值食物时,更新正常工作。但是当必须将一个元素添加到数组时它会崩溃。

我收到以下错误:

MongoError: Cannot apply $addToSet to a non-array field. 
Field named 'subdishes' has a non-array type Object

有没有一种方法可以在一个函数中执行此操作?

2 个答案:

答案 0 :(得分:1)

您无法通过单个原子更新来完成此操作。你可以使用update函数中的回调来检查是否有更新,如果没有则推送到数组,因为文档不存在:

MajorFood.update(
    { 
        "_id": majorFoodId,
        "subdishes.food" : rowVals[0]
    },
    { 
        "$set": {
            "subdishes.$": {        
                //without $ you get the error The dotted field is not valid for storage     
                "energy.$.calories": s.getIntVal(rowVals[1]),
                "energy.$.unit": rowVals[2]
            } 
       }
    },
    function(err, numAffected, rawResponse) {
        console.log(numAffected);
        console.log(rawResponse);
        if (!numAffected) {
            /* Push to array if subdish doesn't exist hence there's no update */
            MajorFood.update(
                { "_id": majorFoodId }
                { 
                    "$push": { 
                        "subdishes": {
                            "food": rowVals[0],
                            "energy": {
                                "calories": s.getIntVal(rowVals[1]),
                                "unit": rowVals[2]
                            } 
                        }
                    }
                },
                function(err, numAffected) {
                    if(err){
                        s.l("err update" );
                        callback(err);
                        return;
                    }
                    s.l("success");
                    callback(); 
                }
            );
        }            

    }
);

答案 1 :(得分:0)

可能是这个链接可以帮助你: mongodb addToSet a non-array field

   MajorFood.update({'_id' : majorFoodId, 'subdishes.food' : {$in:[rowVals[0]]}},
            {$addToSet : {subdishes : {
                food : rowVals[0],
                energy : {
                    calories : s.getIntVal(rowVals[1]),
                    unit : rowVals[2]
                }           
            }}}, {upsert : true}, function(err, doc){
            if(err){
                s.l("err update" );
                callback(err);
                return;
            }
            s.l("success");
            callback(); 
        });