2011-11-28 78 views
1

我有一些代碼寫在Ruby 1.9.2補丁程序級別136,我有一個問題,當我通過原始ruby mongo驅動程序中的_id執行find我得到嘗試使用csv文件中的值時爲零。下面的代碼:使用ObjectId時無法找到與Ruby和MongoDB的文檔

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 

的第一列是OBJECTID在蒙戈,我已經有了。如果我從mongo命令行執行本地查找第一列中的值,我將獲得我想要的數據。但是,上述代碼在@game.inspect調用中返回零。

我嘗試了以下的變化,而這一切產生零:

@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/[email protected]/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/[email protected]/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 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 

再次,爲什麼呢?我在這裏做錯了什麼?謝謝!

回答

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 

如果你沒有通過:頭參數中可以看到第一行[0]對象是字符串 「_id」:

_id 
4ecdacc339c7d7a2a6000002 
4ecdacc339c7d7a2a6000004 
4ecdacc339c7d7a2a6000005 

當你有,你有黃金:

4ecdacc339c7d7a2a6000002 
4ecdacc339c7d7a2a6000004 
4ecdacc339c7d7a2a6000005 
+0

這不是我說的嗎? –

+0

對不起!在我開始寫作之前,我沒有刷新頁面。至少Donn現在也有一個明確的答案,可能會更清楚一點。我在我的電腦上試過上面的內容,可以確認我們的解決方案可以解決他遇到的問題,並且他可以接受答案。如果我在這裏踩任何腳趾道歉。 –

+1

接受這個作爲代碼示例的答案顯示我需要什麼。我沒有使用FasterCSV(我知道它已被1.9.2等等替換)等等。儘管如此,我仍然投票贊成原創。謝謝! –

2

您確定您的CSV解析代碼沒有將標題視爲第一行數據,並且實際上試圖執行BSON::ObjectId("_id")?錯誤消息有點像它。試用FasterCSV.foreach('/tmp/somedata.csv', :headers => true)並使用row['_id'](IIRC,你仍然必須使用BSON::ObjectID)。

+0

感謝發表評論。我沒有使用CSV,但是您的回答確實可以幫助我在下面的正確語法的幫助下獲得正確的最終結果。謝謝邁克爾! –

相關問題