Mongodb有一个更新功能,它可以增加预先存在的字段。但是,我发现它只能更新平面JSON。每当JSONObject内部有一个JSONObject时,我想要增加一个值,我实际上似乎无法做到这一点。它将返回此错误:
com.mongodb.WriteConcernException: Write failed with error code 14 and error message
'Cannot increment with non-numeric argument: {laneQty: { BOTTOM: 1 }}'
正如你所看到的,我尝试将laneQty.BOTTOM更新递增1.我不想编写一个算法来将每个单独的json字段更改为点表示法(如laneQty.BOTTOM),所以有没有办法要么将JSON转换为点符号pre-upsert?
现在我的一般upsert函数如下所示:
public boolean incrementJson(BasicDBObject json, String colName, ArrayList<String> queryParams, ArrayList<String> removeParams){
/*make sure the game id AND the main player id can't both be the same.
If either/or, it's fine. We don't want duplicates.
*/
BasicDBObject query = new BasicDBObject();
DBCollection collection = db.getCollection(colName);
for(int i = 0; i < queryParams.size(); i++){
String param = queryParams.get(i);
query.put(param, json.get(param));
}
for(String param : removeParams){
json.remove(param);
}
return collection.update(query, new BasicDBObject("$inc", json), true, false).isUpdateOfExisting();
}
是否有任何建议的升级代码可以轻松更新分层json?谢谢!
顺便说一句,我很难对此进行硬编码。有大量的分层对象,这将永远带我。此外,我无法完全控制在图层中填充哪些字段,因此我不能每次都说“laneQty.BOTTOM”,因为它并不总是存在。在upserting之前,BasicDBObject json实际上是一个解析为BasicDBObject的java bean。如果它有任何帮助,这是它的构造函数:
public ChampionBean(int rank, int division, int assists, int deaths, int kills, int qty, int championId,
HashMap<String, Integer> laneQty, HashMap<String, Integer> roleQty,
ParticipantTimelineDataBean assistedLaneDeathsPerMinDeltas,
ParticipantTimelineDataBean assistedLaneKillsPerMinDeltas, ParticipantTimelineDataBean creepsPerMinDeltas,
ParticipantTimelineDataBean csDiffPerMinDeltas, ParticipantTimelineDataBean damageTakenDiffPerMinDeltas,
ParticipantTimelineDataBean damageTakenPerMinDeltas, ParticipantTimelineDataBean goldPerMinDeltas,
ParticipantTimelineDataBean xpDiffPerMinDeltas, ParticipantTimelineDataBean xpPerMinDeltas, int wins,
int weekDate, int yearDate) {
super();
this.rank = rank;
this.division = division;
this.assists = assists;
this.deaths = deaths;
this.kills = kills;
this.qty = qty;
this.championId = championId;
this.laneQty = laneQty;
this.roleQty = roleQty;
this.assistedLaneDeathsPerMinDeltas = assistedLaneDeathsPerMinDeltas;
this.assistedLaneKillsPerMinDeltas = assistedLaneKillsPerMinDeltas;
this.creepsPerMinDeltas = creepsPerMinDeltas;
this.csDiffPerMinDeltas = csDiffPerMinDeltas;
this.damageTakenDiffPerMinDeltas = damageTakenDiffPerMinDeltas;
this.damageTakenPerMinDeltas = damageTakenPerMinDeltas;
this.goldPerMinDeltas = goldPerMinDeltas;
this.xpDiffPerMinDeltas = xpDiffPerMinDeltas;
this.xpPerMinDeltas = xpPerMinDeltas;
this.wins = wins;
this.weekDate = weekDate;
this.yearDate = yearDate;
}
participantTimelineDataBean是另一个bean,里面有4个int字段。我想增加这些字段(所以是的,它只有2层深,所以如果有一个2层深层可用性的解决方案,我也会采用它。)
答案 0 :(得分:0)
使用点符号:
new BasicDBObject("$inc", new BasicDBObject("laneQty.BOTTOM", 1) )
替代快速和彻底的解决方案:只需collection.save
整个文档_id
下。
答案 1 :(得分:0)
使用此库:
https://github.com/rhalff/dot-object
例如,如果您有这样的对象:
var jsonObject = {
info : {
firstName : 'aamir',
lastName : 'ryu'
email : 'aamiryu@gmail.com'
},
}
那么你的node.js代码就像这样:
var dot = require('dot-object');
var jsonObject = // as above ;-);
var convertJsonObjectToDot = dot.dot(jsonObject);
console.log(convertJsonObjectToDot);
输出如下所示:
{
info.firstName : 'aamir',
info.lastName : 'ryu',
info.email : 'aamiryu@gmail.com
}
请耐心等待,这是我在stackoverflow上的第一个答案,因为我正在寻找相同的东西,我找到了一个解决方案,希望它可以帮助你。