Brian Armstrong
Brian Armstrong

Reputation: 19873

Mongoid intersect criteria on embedded document

I'm trying to get the intersection of two queries on some embedded docuements using Mongoid 3.

So (fake example) imagine I have:

class Post
  embeds_many :comments

  index 'comments.author_id' => 1
end

class Comments
  embedded_in :post
  belongs_to :author
end

If I wanted to get posts with a comment from a user I could just do

Post.where(:'comments.author_id' => User.first.id)

But what if I want to get posts that have comments by both of these users:

u1 = User.first.id
u2 = User.last.id
Post.where(:'comments.author_id' => u1.id, :'comments.author_id' => u2.id)

This doesn't work in mongoid 3. It overwrites the first comments.author_id with the second so you get something like this:

command={:count=>"posts", :query=>{"comments.author_id"=>"505d1eb5f8182b7082000017"}}

Other variations I've tried without any luck:

Post.where(:'comments.author_id' => u1.id).where(:'comments.author_id' => u2.id)
Post.where(:'comments.author_id' => u1.id).and.where(:'comments.author_id' => u2.id)
Post.where(:'comments.author_id' => u1.id).intersect.where(:'comments.author_id' => u2.id)
Post.all_of(:'comments.author_id' => u1.id, :'comments.author_id' => u2.id)

Is there a better way to construct this query? Thanks!

Upvotes: 0

Views: 462

Answers (1)

modetojoy
modetojoy

Reputation: 166

The issue here is that by the example Mongoid doesn't get a chance to do anything with it, since you've provided a Ruby hash where before the method is executed it gets evaluated to having only 1 key in it (since the keys are the same):

Post.where(:'comments.author_id' => u1.id, :'comments.author_id' => u2.id)

What you want to do is:

Post.any_in(:'comments.author_id' => [ u1.id, u2.id ])

Upvotes: 1

Related Questions