使用ObjectId时无法找到Ruby和MongoDB的文档



我在Ruby 1.9.2补丁级别136中编写了一些代码,我有一个问题,当我通过原始Ruby mongo驱动程序中的_id执行find时,我在尝试使用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。

我尝试了以下变体,它们都产生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。我得到了我的数据,如我所料。然而,如果我把它改为使用row[0],我得到nil。

为什么?我做错了什么?

系统细节

$ gem list
*** LOCAL GEMS ***
bson (1.4.0)
bson_ext (1.4.0)
mongo (1.4.0)

RVM Version: rvm 1.6.9

Ruby Version: 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

再次,为什么?我哪里做错了?谢谢!

第一行没有被读取为标题,要在: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

您确定您的CSV解析代码不处理标题作为第一行数据,实际上试图做BSON::ObjectId("_id") ?错误信息看起来是这样的。尝试使用FasterCSV.foreach('/tmp/somedata.csv', :headers => true)row['_id'] (IIRC,你仍然需要使用BSON::ObjectID)。

相关内容

  • 没有找到相关文章

最新更新