2013-06-05 54 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