I wasn't sure where to put this issue, but it seems more like a Moped problem than a Mongoid problem.
I have two related models
class MyUpload
include Mongoid::Document
has_many :my_documents
end
class MyDocument
include Mongoid::Document
shard_key :my_upload_id, :_id
field :_id, type: Moped::BSON::ObjectId, default: -> { Moped::BSON::ObjectId(SecureRandom.hex(12)) }
belongs_to :my_upload
end
The my_documents
collection is setup with three shards.
When I run a count
of my_documents
on an instance of MyUpload which has 328 documents the count method returns 0.
u = MyUpload.last
u.my_documents.count # returns 0 even though there are 328 in the collection
The corresponding mongo console query returns 328 as expected
db.my_documents.find({ "my_upload_id": ObjectId(...) }).count() // returns 328 as expected
I noticed in the Moped log, the previous Mongoid count command generates the following line
MOPED: 10.1.16.201:27017 COMMAND database=my_database command={:count=>:my_documents,
:query=>{"my_upload_id"=>"500d71bdd0821da854000004"}} (4.0605ms)
I noticed the value for :count
is the collection name as a Symbol rather than a String
When I run
session = Moped::Session.new(["localhost:27017"])
session.use :my_database
session.login <username>, <password>
# collection name as a Symbol
session[:my_documents].find({ "my_upload_id" => Moped::BSON::ObjectId(...) }).count
# returns 0
However, if I run the same command with the collection name as a String it returns the expected result of 328.
# collection name as a String
session["my_documents"].find({ ... }).count
# returns 328 as expected
So it appears there is an issue with the collection name being a symbol vs. string when querying a sharded collection. I have confirmed that is does not happen in a non-sharded collection. Still not sure if this is an actually bug or something with my specific implementation. Any help or advice would be appreciated.
My mongoid.yml looks something like this:
sessions:
default:
database: my_database
hosts:
- <mongos_hostname>:27017
username: <username>
password: <password>
options:
consistency: :strong
safe: true
options:
use_utc: true
tl;dr I've also turned on profiling level 2 on each of the shards and can see the count commands in question logged. Not sure if this is helpful or not.
{ "ts" : ISODate(...), "op" : "command", "ns" : "my_database.$cmd", "comm
and" : { "count" : "my_documents", "query" : { "my_upload_id" : ObjectId(...) } },
"ntoreturn" : 1, "responseLength" : 48, "millis" : 0, "client" : "127.0.1.1", "user" : "" }