This came to my attention because a database engineer over at Compose let us know about it.
In a project with:
class Action include Mongoid::Document include Mongoid::Timestamps belongs_to :account end class ActionOne < Action end class ActionTwo < Action end class Account has_many :action_ones has_many :action_twos end
Querying on the root document while explicitly specifying the _type and
associated key works as expected. The following query
a = Account.first
Action.where(account: a, _type: 'ActionOne').count
will appropriately generate
MOPED: 127.0.0.1:27017 COMMAND database=development command={:count=>"actions", :query=>{"account_id"=>BSON::ObjectId('5570c1586361736413000000'), "_type"=>"ActionOne"}} runtime: 0.1970ms
However, the more sensible way to do the query, and the one that's mentioned in
the docs
a = Account.first a.action_ones.count
will generate an $in selector for the _type field, with a single element
array. This is less efficient.
MOPED: 127.0.0.1:27017 COMMAND database=development command={:count=>"actions", :query=>{"account_id"=>BSON::ObjectId('5570c1586361736413000000'), "_type"=>{"$in"=>["ActionOne"]}}} runtime: 0.3272ms
This has become an issue in our deployment, since according to the engineer at
Compose, "MongoDB can't do an efficient query that includes both a range (like
you're doing on created_at) and an $in." (We are tallying up documents, and
using a query like :created_at.gt => 7.days.ago, for example.) As far as I
can tell, there's no reason to use an $in selector here, and it seems to just
be odd behavior. Until this changes, I'll just be rewriting the queries to
specifically specify the related document and _type.