我运行我的mongo shell脚本如下:
mongo --quiet myscript.js > /tmp/my.json
我在myscript.js中使用
printjson
。mongodb printjson将objectid输出到my.json
,如下所示:"_id" : ObjectId("5444a932ca62bbcba14a1082")
我读了一些MongoShell的源代码。
printjson
将为objectid对象运行此代码。> x._id.tojson
function (){
return this.toString();
}
在Mongo版本2.2之后,
ObjectId("507c7f79bcf86cd7994f6c0e").toString()
将返回以下字符串:ObjectId("507c7f79bcf86cd7994f6c0e")
不是我想要的。我使用
ObjectId("507c7f79bcf86cd7994f6c0e").valueOf()
。这将返回以下字符串:
507c7f79bcf86cd7994f6c0e
最后,我在
myscript.js
中添加一行:ObjectId.prototype.toString = function() { return '"' + this.valueOf() + '"'; }
我解决了我的问题。但我不喜欢改变
toString()
的原始行为。有更好的解决办法吗?
最佳答案
同意,像这样修改框架函数是一个危险的想法。这也改变了所有其他代码的ObjectID.toString
行为,而不仅仅是printjson
。
由于mongodb聚合框架不允许使用任意javascript,因此我们不能只做db.test.aggregate({$project: {_id: '$_id.valueOf()'}})
之类的事情,也不能给它一个自定义的转换函数来使用。
MongoDB Map Reduce框架可以使用自定义的JavaScript函数,并且可能能够实现这一点,但是它相当复杂、缓慢,而且似乎通常不鼓励使用它。
最好的选择是以某种形式将这个id转换作为脚本的一部分。在根据需要打印临时文档之前,只需转换文档即可:
var cursor = db.test.find();
while (cursor.hasNext()) {
var doc = cursor.next();
doc._id = doc._id.valueOf();
printjson(doc);
}
或者变得更复杂并将其包装在您自己的打印功能中,或者替换或装饰原来的
printjson
功能,例如,仅为打印而修改文档并回滚更改:var theirPrintjson = printjson;
var printjson = function(doc) {
var id = doc._id;
doc._id = doc._id.valueOf();
theirPrintjson(doc);
doc._id = id;
};