我运行我的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;
};

07-24 13:12