3. CVBEAST
Mongo has many cool
features such as schema-
free, aggregation w
map/reduce and many
others
Side project
interested more in
domain modeling more
than performance and
scaling benefits of
Mongo
EMBEDDED OBJECTS
4. CVBEAST
App to represent people’s curriculum vitae, but not in an
academic sense
5. CVBEAST
Focus on “micro” experiences not suitable for a typical CV
(definitely not suitable for a resumé)
12. RELATIONAL SCHEMA
people
- id
- name
- ...
cvs
- id
- person_id
- ...
experiences
- id
- cv_id
- ...
13. RELATIONAL SCHEMA
people
- id
- name
- ...
cvs tags
- id
- id - name
- person_id - ...
- ...
links
experiences - id
- name
- id - ...
- cv_id
- ...
14. not b/c of premature
optimization
this bothers me
25. RUBY MODEL CODE
class Person
include Mongoid::Document
field :keywords, :type => Array
index :keywords
index 'cv.experiences.tags'
end
26. class Experience
include Mongoid::Document
embeds_many :links
end
class Link
include Mongoid::Document
field :url
field :title
embedded_in :experience, :inverse_of => :links
end
27. class Experience
include Mongoid::Document
embeds_many :links
end Both models are embedded in the
person collection
class Link
include Mongoid::Document
field :url
field :title
embedded_in :experience, :inverse_of => :links
end
44. MONGO DOCUMENT “SCHEMA”
{"name": "Alex Sharp",
"cv": {
"experiences": [
{ "title": "spoke at MongoLA",
"date" : "Thu Jan 13 2011",
"tags" : ["mongodb", "speaking"]
},
{"title": "..."}
]
}
}
we want to search for these
45. RUBY MODEL CODE
class Person
include Mongoid::Document
field :keywords, :type => Array
index :keywords
index 'cv.experiences.tags'
end
46. RUBY MODEL CODE
class Cv
include Mongoid::Document
embeds_many :experiences
end
class Experience
include Mongoid::Document
field :tags, :type => Array, :default => []
embedded_in :cv, :inverse_of => :experiences
embeds_many :links
after_save lambda { |exp| exp.cv.person.update_keywords }
end
47. RUBY MODEL CODE
class Cv
include Mongoid::Document
simple property
embeds_many :experiences
end (not relationship)
class Experience
include Mongoid::Document
field :tags, :type => Array, :default => []
embedded_in :cv, :inverse_of => :experiences
embeds_many :links
after_save lambda { |exp| exp.cv.person.update_keywords }
end
48. RUBY SEARCH CODE
class Person
# i.e. db.people.find({"cv.experiences.tags": "ruby"})
def self.search_by_tag(term)
collection.find('cv.experiences.tags' => 'ruby')
end
end
49. COMPARISON
select * from people
inner join cvs on cvs.person_id = people.id
inner join experiences on experiences.cv_id = cvs.id
inner join tags on tags.experience_id = experiences.id
where tags.name = 'ruby';
vs
db.people.find('cv.experiences.tags' => 'ruby')