我正在为某个项目尝试"mongo ruby驱动程序"。除了在mongo对象上调用to_json时,它工作得很好。它提供了格式良好的json,但并没有将BSON::Code转换为可读值i生成的json。
它不显示代码文本,而是显示类似的内容
#<BSON::Code:0x00000100af6fa8>
有人试过了吗?我非常感谢你的帮助。
更新
以下是一些代码片段:
@records是一个变量,包含散列中的MongoDB文档数组。
@records.to_json
当我对它调用to_json时,它会按预期提供一切。除了包含BSON::Code(表示javascript代码)的键。例如,考虑以下文档:
{
"_id" : "contains",
"value" : function( obj, target ) { return obj.indexOf(target) != -1; };
}
从ruby查询同一个文档会得到如下输出:
{
"_id"=>"contains",
"value"=><BSON::Code:2160165280 @data="function( obj, target ) { return obj.indexOf(target) != -1; };" @scope="{}">
}
并在此调用to_json得到以下结果:
{"_id":"contains","value":"#<BSON::Code:0x00000100b54658>"}
这就是问题所在。我得到的不是"value"键的实际代码,而是字符串形式的ruby对象。
在BSON::code上调用code方法,我们可以将其转换为代码。但为此,我需要循环mongo-docs,检查每个键的值,如果它是BSON::code的对象,则调用它的代码,然后将其分配回键。最后我们可以在上面调用to_json。但是我不想要这么多开销。我需要to_json本身来处理它。
迭代数组中对象属性的序列化程序可能正在调用to_s方法,这将导致您看到的输出。
您可以对BSON::Code类进行monkey修补,使其包含一个调用inspect(生成所需输出的方法)的to_s方法,或者修改序列化程序以检测它何时遇到BSON::Code实例,并对它而不是to_s调用inspect。
对BSON::code类进行mokey补丁的代码如下所示:
module BSON
class Code
def to_s
inspect
end
end
end
这将具有与inspect相同的行为。如果你只是想要代码,你可以在中进行猴子补丁
module BSON
class Code
def to_s
@code
end
end
end
我可能会将此作为to_s在驱动程序中的默认行为,但现在只需将其包含在代码中,它应该会像冠军一样工作。
你指的是哪个Mongo对象,模块?如果可以的话,请张贴代码和你试图做的事情。
我在驱动程序中看到的唯一to_json是BSON::ObjectId#to_json,它(从文档中)被描述为一种执行以下操作的方法:
转换为MongoDB扩展的JSON格式。由于JSON包含类型信息,但缺少ObjectId类型,因此此JSON格式使用$oid键对类型进行编码。
当我使用它时,我得到了相同的结果:
1.9.3-p0 :001 > require 'mongo'
=> true
1.9.3-p0 :002 > BSON::ObjectId
=> BSON::ObjectId
1.9.3-p0 :003 > BSON::ObjectId.new()
=> BSON::ObjectId('4f17350eadd361e91d000001')
1.9.3-p0 :004 > BSON::ObjectId.new().to_json
=> "{"$oid": "4f173512add361e91d000002"}"
BSON(http://bsonspec.org/)是JSON(http://www.json.org/)。JSON不是用来描述函数的,因为它是可移植的。这种方式的功能不能移植到其他系统。所以没有办法序列化它。这里定义了一些技巧,可能会得到你需要的东西,但最终,如果你试图序列化函数,BSON/JSON可能是一个奇怪的工具。