用Mongoose更新信息,dynamic地在对象内部对象内部数组

我试图更新从1到3的JSON字段“champ_x”,并在一个dynamic函数中同时更新两个玩家1:

{ "_id": { "$oid": "58a3521edf127d0a0c417cda" }, "room": "room_0.0940045412694186", "player_1": "eee", "player_2": "fff", "player_1_details": { "history_moves": [], "champions": [ { "champ_1": "na" }, { "champ_2": "na" }, { "champ_3": "na" } ] }, "player_2_details": { "history_moves": [], "champions": [ { "champ_1": "na" }, { "champ_2": "na" }, { "champ_3": "na" } ] }, "game_state": "789", "__v": 0 } 

我有这个模型:

 match_schema.statics.update_champ = function(room, turn, champ_num, champ_select, callback){ if(champ_num == "champ_1"){ match_mongoose.update({ room: room }, { $set: { 'player_1_details.champions.0.champ_1': champ_select}}) .exec(function(error){ if(error){ return callback(error); }else{ return callback(null); } }); } }; 

这个模型工作正常

我的问题是,我试图使它dynamic的,我可以通过function参数发送当前转(1或2),和select的位置(champ_1,2或3)。

我试过这个:

 //Update Champion match_schema.statics.update_champ = function(room, turn, champ_num, champ_select, callback){ match_mongoose.update({ room: room }, { $set: { 'player_'+turn+'_details.champions.0.'+champ_num: champ_select}}) .exec(function(error){ if(error){ return callback(error); }else{ return callback(null); } }); }; var match_mongoose = mongoose.model('matches', match_schema, 'matches'); module.exports = match_mongoose; 

但我得到一个错误,说“意外的令牌+”似乎连接的价值不起作用。 有没有办法做到这一点?

谢谢!

您可以按照@dNitro的build议构build$set修饰符和匹配部分:

 var modifier = { $set: {} }; modifier.$set['player_' + turn + '_details.champions.$.champ_' + champ_num] = champ_select; 

你也将有一个数组索引的问题,你指定的champions.0所以它总是会采取第一个数组项不会匹配的champs_2champs_3 。 对此的一个解决scheme是使用位置参数$与数组中的匹配:

 var match = {}; match['room'] = room; match['player_' + turn + '_details.champions.champ_' + champ_num] = { $exists: true }; 

完整的更新function是:

 matchSchema.statics.update_champ = function(room, turn, champ_num, champ_select, callback) { var modifier = { $set: {} }; modifier.$set['player_' + turn + '_details.champions.$.champ_' + champ_num] = champ_select; var match = {}; match['room'] = room; match['player_' + turn + '_details.champions.champ_' + champ_num] = { $exists: true }; this.update(match, modifier) .exec(function(error) { if (error) { return callback(error); } else { return callback(null); } }); }; 

并用以下方式调用它:

 Match.update_champ("room_0.0940045412694186", 1, 1, "new_value", function(err, res) { if (!err) { console.log(err); return; } console.log(res); }); 

你可以在这里find一个完整的例子