如何在mongo-ruby驱动程序中使to_json在BSON::Code对象上工作



我正在为某个项目尝试"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可能是一个奇怪的工具。

最新更新