1

Ruby 1.9.2 パッチ レベル 136 で記述されたコードがいくつかありfind、生の Ruby mongo ドライバーで _id を介して実行すると、csv ファイルの値を使用しようとすると nil が返されるという問題があります。コードは次のとおりです。

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 の objectId です。最初の列の値を mongo コマンド ラインからローカル検索を実行すると、必要なデータが得られます。ただし、上記のコードは@game.inspect呼び出し時に nil を返します。

次のバリエーションを試しましたが、すべてゼロになります。

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

BSON クラスを使用して ObjectId を構築しようとしました。

@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 を実行すると、期待どおりにデータが返されます。ただし、これをrow[0]を使用するように変更すると、nilになります。

なんで?私は何を間違っていますか?

システム詳細

$ gem list

*** LOCAL GEMS ***

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

RVM バージョン:rvm 1.6.9

ルビーのバージョン:ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]

モンゴのバージョン:

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

繰り返しますが、なぜですか?ここで何が間違っていますか?ありがとう!

4

2 に答える 2

2

CSV 解析コードがヘッダーをデータの最初の行として処理しておらず、実際に処理しようとしていBSON::ObjectId("_id")ますか? エラーメッセージはそのようなものです。FasterCSV.foreach('/tmp/somedata.csv', :headers => true)withと using を試してくださいrow['_id'](IIRCはまだ使用する必要がありますBSON::ObjectID)。

于 2011-11-28T23:07:13.603 に答える
2

: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
于 2011-11-28T23:50:15.993 に答える