1

I'm likely missing something here, but it seems like this is a performance oversight. I first noticed this when looking at the query logs of Errbit and noticing hundreds of queries for the same objects.

It seems that all the children of a has_many relation don't have a reference back to their parent object after being loaded through the relation. i.e. accessing parent.children.map &:parent will get the parent from the DB once for each child instead of being setup with the in-memory copy of parent

Example:

Using a very simple belongs_to / has_many setup:

class Person
  include Mongoid::Document
  field :name
  has_many :posts, :inverse_of => :person
end

class Post
  include Mongoid::Document
  field :text
  belongs_to :person, :inverse_of => :posts
end

Then, in the Rails console, a simple demonstration:

Loading development environment (Rails 3.2.12)
[1] pry(main)> tom = Person.create(:name => 'Tom')
[2] pry(main)> tom.posts.create(:text => 'stuff')
[3] pry(main)> tom.posts.create(:text => 'other stuff')
[4] pry(main)> Person.first.posts.map {|post| post.person.object_id}
=> [50687740, 50719060]

Note that last line, each person reference points to a different ruby object. I'm using ruby's object_id attribute to highlight the fact that these are literally different objects and this requires two round-trips to the database.

Why isn't the parent relation just a reference to the parent object after loading through the has_many relation?

Daniel Beardsley
  • 19,907
  • 21
  • 66
  • 79

1 Answers1

0

Turns out that this is a known deficiency and adding this feature is planned for version 4.0.

In the mean time, you can drastically reduce duplicated queries and improve performance by enabling the Mongoid Identity Map

Daniel Beardsley
  • 19,907
  • 21
  • 66
  • 79