mongo-ruby-driver
mongo-ruby-driver copied to clipboard
RUBY-3355 - Create when key '_id' (as string) is nil results in error
Hi!
While investigating an issue in an application I'm working on I discovered that trying to insert a document containing '_id' => nil
will raise the following exception:
.../lib/mongo/operation/result.rb:364:in `raise_operation_failure': [2]: can't have multiple _id fields in one document (on 127.0.0.1:27017, legacy retry, attempt 1) (Mongo::Error::OperationFailure)
Here's a reproduction script:
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'mongo'
end
client = Mongo::Client.new(['127.0.0.1:27017'], database: 'PoC_DTM') # Assuming you have a mongo server running on port 27017
db = client.database
collection = db[:fake_collection]
collection.insert_one({ field: 'test', _id: nil }) # => OK
collection.insert_one({ field: 'test', '_id' => nil }) # => KO
I was able to track down the issue in the lib/mongo/operation/shared/idable.rb
file:
...
def id(doc)
doc.respond_to?(:id) ? doc.id : (doc['_id'] || doc[:_id])
end
def has_id?(doc)
!!id(doc)
end
def ensure_ids(documents)
@ids = []
documents.collect do |doc|
doc_with_id = has_id?(doc) ? doc : doc.merge(_id: id_generator.generate)
@ids << id(doc_with_id)
doc_with_id
end
end
...
When '_id'
is equal to nil
has_id?
returns false
which causes ensure_ids
to generate an id that it stores in :_id
but without removing the '_id'
key which results in the document having both '_id'
and :_id
, hence the exception mentioned above.
Let me know if I should create an issue in JIRA first