Не удается найти документ с Ruby и MongoDB при использовании ObjectId - PullRequest
1 голос
/ 29 ноября 2011

У меня есть некоторый код, написанный на патче Ruby 1.9.2 уровня 136, и у меня есть проблема, когда при выполнении find через _id в необработанном драйвере ruby ​​mongo я получаю ноль при попытке использовать значениеиз CSV-файла.Вот код:

require 'mongo'
require 'csv'
require 'bson'

# Games database
gamedb = Mongo::Connection.new("localhost", 27017).db("gamedb")
@games = gamedb.collection("games")

# Loop over CSV data.
CSV.foreach("/tmp/somedata.csv") do |row|

  puts row[0] # Puts the ObjectId

  @game = @games.find( { "_id" => row[0] } ).first  
  puts @game.inspect

end

Файл CSV выглядит следующим образом:

_id,game_title,platform,upc_db_match,upc
4ecdacc339c7d7a2a6000002,TMNT,PSP,TMNT,085391157663
4ecdacc339c7d7a2a6000004,Super Mario Galaxy,Wii,Super Mario Galaxy,045496900434
4ecdacc339c7d7a2a6000005,Beowulf,PSP,Beowulf,097363473046

Первый столбец - это идентификатор объекта в Монго, который у меня уже есть.Если я выполняю локальный поиск из командной строки mongo значений в первом столбце, я получаю нужные данные.Однако приведенный выше код возвращает ноль при вызове @game.inspect.

Я пробовал следующие варианты, которые все дают ноль:

@game = @games.find( { "_id" => row[0].to_s } ).first
@game = @games.find( { "_id" => row[0].to_s.strip } ).first

Я даже пытался создать ObjectId с классами BSON как таковые:

@game = @games.find( { "_id" => BSON::ObjectId(row[0]) } ).first

или

@game = @games.find( { "_id" => BSON::ObjectId("#{row[0]}") } ).first

В обоих случаях выдается следующая ошибка:

/Users/donnfelker/.rvm/gems/ruby-1.9.2-p136@upc-etl/gems/bson-1.4.0/lib/bson/types/object_id.rb:126:in `from_string': illegal ObjectId format: _id (BSON::InvalidObjectId)
    from /Users/donnfelker/.rvm/gems/ruby-1.9.2-p136@upc-etl/gems/bson-1.4.0/lib/bson/types/object_id.rb:26:in `ObjectId'
    from migrate_upc_from_csv.rb:14:in `block in <main>'
    from /Users/donnfelker/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1768:in `each'
    from /Users/donnfelker/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1202:in `block in foreach'
    from /Users/donnfelker/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1340:in `open'
    from /Users/donnfelker/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1201:in `foreach'
    from migrate_upc_from_csv.rb:10:in `<main>'

Сумасшедшая вещь, если я вручную создаю BSON ObjectId вручную, он работает (как показано ниже):

@game = @games.find( { "_id" => BSON::ObjectId("4ecdacc339c7d7a2a6000004") } ).first

Когда я запускаю @ game.inspect, я получаю свои данные обратно, как я и ожидал.Однако, если я изменю это на использование строки [0], я получу ноль.

Почему?Что я делаю неправильно?

Сведения о системе

$ gem list

*** LOCAL GEMS ***

bson (1.4.0)
bson_ext (1.4.0)
mongo (1.4.0)

Версия RVM: rvm 1.6.9

Версия Ruby: ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]

Версия Mongo:

[initandlisten] db version v1.8.2, pdfile version 4.5
[initandlisten] git version: 433bbaa14aaba6860da15bd4de8edf600f56501b

Опять же, почему?Что я здесь не так делаю?Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

Первая строка не читается как заголовок, для этого передается :headers => true, например:

require 'csv'

# Loop over CSV data.
CSV.foreach("/tmp/somedata.csv", :headers => true) do |row|

  puts row[0] # Puts the ObjectId

end

Если вы не передаете параметр: headers, вы можете увидеть первую строку[0] объект - это строка "_id":

_id
4ecdacc339c7d7a2a6000002
4ecdacc339c7d7a2a6000004
4ecdacc339c7d7a2a6000005

Когда вы включаете его, вы получаете золотой:

4ecdacc339c7d7a2a6000002
4ecdacc339c7d7a2a6000004
4ecdacc339c7d7a2a6000005
2 голосов
/ 29 ноября 2011

Вы уверены, что ваш код синтаксического анализа CSV не рассматривает заголовки как первую строку данных и фактически пытается сделать BSON::ObjectId("_id")?Сообщение об ошибке вроде как выглядит.Попробуйте с FasterCSV.foreach('/tmp/somedata.csv', :headers => true) и с row['_id'] (IIRC вам все равно придется использовать BSON::ObjectID).

...