简体   繁体   中英

mongoid - querying embedded docs

class Foo
  include Mongoid::Document
  field :name, type: String
  embeds_many :bars
end

class Bar
  include Mongoid::Document
  field :name, type: String
  embedded_in :foo
end

Is there a way that I can query all of the bars here? In AR I'd do something like Bar.where(name: 'something') - just give me all the bars that match some criteria.

As it stands, I can only query the specific bars on a single foo. `Foo.first.bars.where(name: 'something'). I know mongoDB has no joins, so... I'm curious how to go about this.

I'm about ready to lose the Foo all together and do something like:

class Bar
  include Mongoid::Document
  field :foo_name, type: String
  field :name, type: String
end

You are not able to return Bar object without first returning the Foo object it is embedded in.

You can query for a top level document ( Foo ) as matches for embedded documents.

foo = Foo.create(:name => 'foo1')
foo.bars << Bar.new(:name => 'bar1')

Foo.where(:'bars.name' => 'bar1').first
=> #<Foo _id: 53c4a380626e6f813d000000, name: "foo1">

Then once you have the Foos that match some embedded bar, you can find the bar you are looking for with another query (which just maps to an Array#find or Array#select

foo.bars << Bar.new(:name => 'bar2')
Foo.where(:'bars.name' => 'bar1').first.bars.where(:name => 'bar2').first
=> #<Bar _id: 53c4a380626e6f813d000001, name: "bar2">

Update: In cases where you are querying for the embedded document out of the parent document context, I recommend against the use of an embedded document. When you embed a document, you are saying "I do not intend for the document to exist on it's own". If you find yourself query for it directly then ditch the embedding. It is tempting to embed but typically you don't need/require it.

Note: I have de-embedded 100M+ entries and it was a long hectic process.

Note2: embedding some metadata or aggregate is an optimization best kept for times when you really need it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM