2013-06-05 56 views
2

重複鍵的錯誤有沒有在紅寶石的mongodb處理有關的異常任何很好的例子? 在這種情況下,我有:如何處理MongoDB的E11000紅寶石

/home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/networking.rb:89:in `send_message_with_gle': 11000: E11000 duplicate key error index: somedb.somecoll.$_id_ dup key: { : "some_id" } (Mongo::OperationFailure) 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/collection.rb:1108:in `block in insert_documents' 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/util/logging.rb:33:in `block in instrument' 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/util/logging.rb:65:in `instrument' 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/util/logging.rb:32:in `instrument' 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/collection.rb:1106:in `insert_documents' 
    from /home/askar/.rvm/gems/ruby-1.9.3-p429/gems/mongo-1.8.6/lib/mongo/collection.rb:375:in `insert' 
    from lib/tasks/getorders.rb:47:in `block in <main>' 
    from lib/tasks/getorders.rb:25:in `each' 
    from lib/tasks/getorders.rb:25:in `<main>' 

我有這個錯誤,因爲我試圖插入已存在MongoDB中的數據庫ID的文檔,我只是想知道如何處理的MongoDB相關的異常在紅寶石。 例如,如果出現異常,那麼我會改變散列的ID,然後重新嘗試插入。

如何救援塊會是什麼樣子?

回答

5

紅寶石塊看起來是這樣的:

begin 
    # your operation 
rescue Mongo::OperationFailure => e 
    if e.message =~ /^11000/ 
    puts "Duplicate key error #{$!}" 
    # do something to recover from duplicate 
    else 
    raise e 
    end 
end 
# the rest of the exceptions follow .. 
# if you just care about the dup error 
# then ignore them 
#rescue Mongo::MongoRubyError 
# #Mongo::ConnectionError, Mongo::ConnectionTimeoutError, Mongo::GridError, Mongo::InvalidSortValueError, Mongo::MongoArgumentError, Mongo::NodeWithTagsNotFound 
# puts "Ruby Error : #{$!}" 
#rescue Mongo::MongoDBError 
# # Mongo::AuthenticationError, Mongo::ConnectionFailure, Mongo::InvalidOperation, Mongo::OperationFailure 
# puts "DB Error : #{$!}" 
#rescue Mongo::OperationTimeout 
# puts "Socket operation timeout Error : #{$!}" 
#rescue Mongo::InvalidNSName 
# puts "invalid collection or database Error : #{$!}" 
#end 

但是,如果要更新已經存在,爲什麼你不使用upsert的記錄。

如果要創建一個新的記錄,那麼爲什麼不讓mongod的創建_id?

+0

嗨!我有意識地在ruby中創建了_id,然後用這個_id創建一個文檔。 _id根據我下載的文件創建。所以,如果發生_id重複錯誤,它會給我一個信號,表明我要下載相同的文件。而不是搜索mongodb數據庫中的所有文檔,以檢查是否已經有一個具有相同_id的記錄,我認爲最好是捕獲異常並進一步操作,不要下載或更改此dup記錄的_id。感謝您的回答! – Askar

+1

注意:最新的Ruby驅動程序將錯誤顯示爲Mongo :: Error :: OperationFailure。 – Joerg

+0

通過@Joerg添加評論,e.message的正則表達式使用最新的驅動程序應該是/^E11000/ – neilfws

0

也可以用寫的擔憂。

@mongo_client.save({:doc => 'foo'}, {:w => 0}) # writes are not acknowledged

這不是因爲搶救雖然一樣好。

+0

好的提示,謝謝。 – kylemclaren

0

如果你的Ruby驅動程序是>= 2.0.0,你應該使用Mongo::Error類對於大多數的MongoDB相關的異常。以下是您的rescue塊的外觀應該如何:

begin 
    # Document insert code 
rescue Mongo::Error => e 
    if e.message.include? 'E11000' 
    # Change the id of the hash & re-try to insert it 
    end 
end