2016-12-29 67 views
0

子句是項目MajorFood中的數組。如果它們不存在,我想添加子句,如果它們存在,則更新它們。Mongodb:如果值不存在,如何爲數組添加值,但如果存在則更新值

我試着用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 

是否有一個函數來做到這一點的方法?

+0

你看過錯誤信息嗎?你的集合中有一些文檔,其中'subdishes'不像你期望的那樣是一個數組。 –

+0

您可以使用$ cond操作符來檢查字段是否存在(使用$ exists)或它的類型(使用$ type),然後使用$ addToSet或不使用 – felix

+0

@felix,'subdishes:{$ type:'object'}'將解析在這兩種情況下都爲true,當'subdishes'是一個對象並且它是一個對象數組時:https://docs.mongodb.com/manual/reference/operator/query/type/#arrays –

回答

0

您將無法使用單個原子更新執行此操作。您可以使用更新功能的回調,以檢查是否出現了更新,並推到數組,如果不是因爲該文件不存在:

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(); 
       } 
      ); 
     }    

    } 
); 
+0

這將是我的備份方法。我不想重複推動和設置部分的代碼。 – suku

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(); 
     }); 
+0

我收到此錯誤:'E11000重複鍵錯誤集合:appdb.food索引:_id_ dup鍵:{:ObjectId(\'5865076b8bd0fc2a900324fc \')}'' – suku

+0

我刪除集合中的每個文檔,並且仍然出現此錯誤 – suku

+0

此錯誤是因爲您有一個記錄(_id:majorFoodId),但(subdishes.food不等於rowVals [0])。所以它試圖用相同的_id插入記錄並拋出錯誤 –

相關問題