我需要对需要在数组中旋转一些值的文档执行更新操作。MongoDB 更新查询目前不允许您$pop
再$push
对同一字段进行更新。在网上搜索了建议后,我决定这db.eval()
将最适合我的使用,因为它确保了原子性并且我正在执行的操作非常短,因此它不会锁定数据库太久。
这是我正在尝试做的事情的一个例子:
db.eval(function (id, newVal) {
doc = db.collection.findOne({_id: id});
doc.values.shift();
doc.values.push(newVal);
db.collection.save(doc);
}, id, newVal);
这非常有效!然后我启用了 mongoDB 分析以查看命令花费了多少毫秒,eval()
并且我总是得到少于 1 毫秒的结果:
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 0 }
{ "millis" : 0 }
...
这对我来说是个好消息,除了我的应用程序是在 python 中,所以我使用 pymongo 客户端来执行eval()
命令。(上面的数据来自 mongo shell)但是现在,当我eval()
使用 pymongo 运行相同的命令时:
conn = pymongo.Connection(mongo_server_hostname)
db = conn.my_db
db.eval("""function (id, newVal) {
doc = db.collection.findOne({_id: id});
doc.values.shift();
doc.values.push(newVal);
db.collection.save(doc);
}""", id, new_val)
我得到了非常不同的分析结果:
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 13 }
{ "millis" : 14 }
{ "millis" : 14 }
...
从 mongo shell 和 pymongo 中运行相同的命令是否有根本的不同eval()
,导致服务器从 pymongo 运行相同的命令要多花 14 毫秒?