Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-4128

Querying on documents with inheritance should not generate $in query

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 5.0.2
    • Affects Version/s: 5.0.1, 5.0.0
    • Component/s: None

      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.

            Assignee:
            durran.jordan@mongodb.com Durran Jordan
            Reporter:
            danarnold danarnold
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: