Как заставить to_json работать на BSON :: Code объекте также в mongo-ruby-driver - PullRequest
0 голосов
/ 18 января 2012

Я пытаюсь использовать 'mongo-ruby-driver' для какого-то проекта.Работает нормально, кроме случаев, когда я вызываю to_json для объекта Монго.Он дает хорошо сформированный json, но не преобразует BSON :: Code в читаемое значение, в результате чего получается JSON.

Вместо отображения кода, он показывает что-то вроде

#<BSON::Code:0x00000100af6fa8>

Кто-нибудь пробовал.Мы высоко ценим любой идентификатор помощи.

ОБНОВЛЕНИЕ

Вот фрагмент кода:

@ records - переменная, которая содержит массив документов MongoDB в хэше.

Когда я вызываю 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, мы можем преобразовать его в код.Но для этого мне нужно зациклить документы mongo, проверить значения для каждого ключа, вызвать код для него, если это объект BSON :: Code, и затем присвоить его обратно ключу.И наконец мы можем вызвать to_json.Но я не хочу столько накладных расходов.Мне нужно, чтобы to_json сам позаботился об этом.

Ответы [ 3 ]

1 голос
/ 21 января 2012

Сериализатор, который выполняет итерацию по атрибутам объектов в массиве, вероятно, вызывает метод to_s, что приведет к выводу, который вы видите.

Вы можете либо обезьяньей заплатить класс BSON :: Code, чтобывключите метод to_s, который вызывает inspect (метод, который производит желаемый вывод), или измените сериализатор так, чтобы он обнаруживал, когда он встречает экземпляр BSON :: Code, и вызывайте inspect на нем, а не to_s.

Код дляmokey patch класс BSON :: Code будет выглядеть следующим образом:

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 в драйвере, но сейчас просто включите его в ваш код, и он должен работать как чемпион.

0 голосов
/ 21 января 2012

BSON (http://bsonspec.org/) - это двоичное представление JSON (http://www.json.org/). JSON не предназначен для описания функций, так как он должен быть переносимым. Функции таким образом не переносимы на другие системы. Так что нет возможности сериализовать его. Здесь определены некоторые хаки, которые могут дать вам то, что вам нужно, но в конечном итоге BSON / JSON может оказаться странным инструментом для работы, если вы пытаетесь сериализовать функции.

0 голосов
/ 19 января 2012

Какой объект Монго, вы имеете в виду модуль?Если вы можете, пожалуйста, опубликуйте код и то, что вы пытаетесь сделать.

Единственный to_json, который я вижу в драйвере, это BSON :: ObjectId # to_json, который (из документации) описывается как метод, который делаетследующее:

Преобразовать в расширенный формат JSON MongoDB.Поскольку 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\"}" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...