mongoid / origin

A Ruby DSL for building MongoDB queries
http://mongoid.org/en/origin/index.html
MIT License
62 stars 29 forks source link

How to select children documents in mongoid? #85

Closed ellmo closed 11 years ago

ellmo commented 11 years ago

This is a copy of a question I posted on StackOverflow: http://stackoverflow.com/questions/17013703/how-to-select-children-documents-in-mongoid

The specific problem

I have three classes set up in a tree

Group Owner class:

class GroupOwner
  include Mongoid::Document
  field :origin_id,    type: BSON::ObjectId
  field :origin_type,  type: String

  embeds_many :groups
end

Group class:

class Group
  include Mongoid::Document

  field :slug,                type: String

  embedded_in :owner,         class_name: "GroupOwner"
  embeds_many :members,       class_name: "GroupMember"
end

Group Member class:

class GroupMember
  include Mongoid::Document

  field :origin_id,            type: BSON::ObjectId
  field :origin_type,          type: String

  embedded_in :group
end

And I want to do, is to grab all Groups meeting specified criteria, like all Groups with a given slug. I don't care which GroupOwner they're embedded in. I want them all. And when I have them, I want all GroupMembers inside them, that meet another set of criteria.

Since they don't exist outside the embedding, Group.where() obviously will not work. The furthest I've gone so far was:

GroupOwner.elem_match(groups: {slug: 'friends'}).map(&:groups).flatten but I hate this solution, since it uses Ruby to actually map the values. Queryable.pluck method is available in Mongoid, but it plucks the mongo documents so hard, they stop being objects in Ruby and become Hashes.

Even when I do map all the Group model objects, somehow this:

groups = GroupOwner.elem_match(groups: {slug: 'friends'}).map(&:groups).flatten
groups.elem_match(members: {origin_id: value})

...returns no elements at all. As if elem_match decided to stop working anywhere but in the root document.

The very general problem

This is all an elaborate approach to a much more generic problem I seem to have: Finding and/or deleting children documents that have a specific set of values.

i.e. – all that I'm trying to do, is to delete all GroupMember documents, which have a specific origin_id.

ellmo commented 11 years ago

Should've posted this in mongoid's issues, closing here