我对MongoDB完全不熟悉......我错过了一个“新手”标签,所以专家们不必看到这个问题。
我正在尝试使用表达式更新集合中的所有文档。我期望解决的问题是:
db.QUESTIONS.update({}, { $set: { i_pp : i_up * 100 - i_down * 20 } }, false, true);
然而,这会导致以下错误消息:
ReferenceError:未定义i_up(shell):1
与此同时,数据库吃这个没有任何问题:
db.QUESTIONS.update({}, { $set: { i_pp : 0 } }, false, true);
我是否必须同时执行此一个文档?这似乎过于复杂。
更新 谢谢Sergio Tulentsev告诉我它不起作用。现在,我真的在努力解决这个问题。我向有用的灵魂提供500 Profit Points,他可以用MongoDB理解的方式写这个。如果您在our forum注册,我可以将利润点添加到您的帐户。
答案 0 :(得分:5)
您无法在更新中使用表达式。或者,您不能使用依赖于文档字段的表达式。简单的自包含数学表达式很好(例如2 * 2
)。
如果要为所有与其他字段相关的文档设置新字段,则必须循环它们并手动更新。多重更新在这里无济于事。
答案 1 :(得分:4)
我在搜索MongoDB等效的SQL时遇到了这个:
update t
set c1 = c2
where ...
Sergio是正确的,您无法在直接更新中将其他属性作为值引用。但是,db.c.find(...)
会返回cursor and that cursor has a forEach
method:
对MongoDB的查询返回一个游标,可以迭代该游标进行检索 结果。查询的确切方式因语言驱动程序而异。 下面的细节集中在来自MongoDB shell的查询(即
mongo
过程)。shell
find()
方法返回一个游标对象,然后我们可以迭代它以从结果中检索特定文档。我们用 用于此目的的hasNext()
和next()
方法。for( var c = db.parts.find(); c.hasNext(); ) { print( c.next()); }
此外,在shell中,
forEach()
可以与游标一起使用:db.users.find().forEach( function(u) { print("user: " + u.name); } );
所以你可以这样说:
db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
db.QUESTIONS.update(
{ _id: q._id },
{ $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
);
});
在不离开MongoDB的情况下一次更新一个。
如果你使用驱动程序连接到MongoDB,那么应该有一些方法可以将一串JavaScript发送到MongoDB;例如,使用Ruby驱动程序,您可以使用eval
:
connection.eval(%q{
db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
db.QUESTIONS.update(
{ _id: q._id },
{ $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
);
});
})
其他语言应该类似。
答案 2 :(得分:1)
Rha7提出了一个好主意,但如果没有定义临时变量,上面的代码就无法工作。
此示例代码基于生日'生成近似的年龄计算(场景背后的闰年)。字段并将值插入到不包含此类的所有文档的适当字段中:
db.employers.find({age: {$exists: false}}).forEach(function(doc){
var new_age = parseInt((ISODate() - doc.birthday)/(3600*1000*24*365));
db.employers.update({_id: doc._id}, {$set: {age: new_age}});
});
答案 3 :(得分:0)
从来电者ID开头删除“00”的示例:
db.call_detail_records_201312.find(
{ destination: /^001/ },
{ "destination": true }
).forEach(function(row){
db.call_detail_records_201312.update(
{ _id: row["_id"] },
{ $set: {
destination: row["destination"].replace(/^001/, '1')
}
}
)
});
答案 4 :(得分:0)
//the only differnce is to make it look like and aggregation pipeline
db.table.updateMany({}, [{
$set: {
col3:{"$sum":["$col1","$col2"]}
},
}]
)