mongoid-eager-loading 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +13 -12
- data/README.md +12 -10
- data/benchmark/benchmark.rb +11 -4
- data/lib/mongoid-eager-loading.rb +1 -6
- data/lib/mongoid-eager-loading/mongoid/criterion/eager_loading.rb +36 -36
- data/lib/mongoid-eager-loading/version.rb +1 -1
- data/mongoid-eager-loading.gemspec +4 -3
- data/spec/models/account.rb +11 -5
- data/spec/models/address.rb +8 -1
- data/spec/models/address_component.rb +5 -0
- data/spec/models/agent.rb +2 -3
- data/spec/models/animal.rb +8 -5
- data/spec/models/answer.rb +1 -1
- data/spec/models/bar.rb +5 -0
- data/spec/models/book.rb +5 -0
- data/spec/models/business.rb +7 -0
- data/spec/models/callbacks.rb +2 -2
- data/spec/models/category.rb +3 -3
- data/spec/models/country_code.rb +1 -1
- data/spec/models/description.rb +3 -0
- data/spec/models/drug.rb +5 -0
- data/spec/models/favorite.rb +1 -3
- data/spec/models/fruits.rb +11 -0
- data/spec/models/game.rb +2 -1
- data/spec/models/house.rb +4 -0
- data/spec/models/inheritance.rb +19 -4
- data/spec/models/location.rb +1 -1
- data/spec/models/membership.rb +4 -0
- data/spec/models/movie.rb +5 -0
- data/spec/models/name.rb +1 -1
- data/spec/models/page.rb +5 -0
- data/spec/models/page_question.rb +4 -0
- data/spec/models/paranoid_post.rb +1 -1
- data/spec/models/parents.rb +1 -1
- data/spec/models/patient.rb +2 -2
- data/spec/models/person.rb +27 -12
- data/spec/models/pet.rb +1 -1
- data/spec/models/pet_owner.rb +1 -1
- data/spec/models/phone.rb +1 -1
- data/spec/models/post.rb +6 -4
- data/spec/models/preference.rb +2 -1
- data/spec/models/question.rb +3 -3
- data/spec/models/quiz.rb +4 -0
- data/spec/models/rating.rb +6 -0
- data/spec/models/role.rb +5 -0
- data/spec/models/shelf.rb +5 -0
- data/spec/models/slave_address_numbers.rb +14 -0
- data/spec/models/survey.rb +1 -2
- data/spec/models/tracking_id_validation_history.rb +25 -0
- data/spec/models/translation.rb +1 -1
- data/spec/models/user.rb +3 -2
- data/spec/models/user_account.rb +3 -2
- data/spec/models/vet_visit.rb +1 -1
- data/spec/models/video.rb +1 -1
- data/spec/models/wiki_page.rb +6 -0
- data/spec/mongoid-eager-loading/mongoid/criterion/eager_loading_spec.rb +19 -0
- data/spec/spec_helper.rb +1 -1
- metadata +93 -59
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mongoid-eager-loading (0.
|
4
|
+
mongoid-eager-loading (0.3.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -11,18 +11,18 @@ GEM
|
|
11
11
|
builder (~> 2.1.2)
|
12
12
|
i18n (~> 0.4)
|
13
13
|
activesupport (3.0.3)
|
14
|
-
bson (1.
|
15
|
-
bson_ext (1.
|
14
|
+
bson (1.2.0)
|
15
|
+
bson_ext (1.2.0)
|
16
16
|
builder (2.1.2)
|
17
17
|
diff-lcs (1.1.2)
|
18
|
-
i18n (0.
|
18
|
+
i18n (0.5.0)
|
19
19
|
mocha (0.9.9)
|
20
20
|
rake
|
21
|
-
mongo (1.
|
22
|
-
bson (>= 1.
|
23
|
-
mongoid (2.0.0.
|
21
|
+
mongo (1.2.0)
|
22
|
+
bson (>= 1.2.0)
|
23
|
+
mongoid (2.0.0.rc.6)
|
24
24
|
activemodel (~> 3.0)
|
25
|
-
mongo (~> 1.
|
25
|
+
mongo (~> 1.2)
|
26
26
|
tzinfo (~> 0.3.22)
|
27
27
|
will_paginate (~> 3.0.pre)
|
28
28
|
rake (0.8.7)
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
rspec-mocks (2.0.1)
|
37
37
|
rspec-core (~> 2.0.1)
|
38
38
|
rspec-expectations (~> 2.0.1)
|
39
|
-
tzinfo (0.3.
|
39
|
+
tzinfo (0.3.24)
|
40
40
|
watchr (0.7)
|
41
41
|
will_paginate (3.0.pre2)
|
42
42
|
|
@@ -44,11 +44,12 @@ PLATFORMS
|
|
44
44
|
ruby
|
45
45
|
|
46
46
|
DEPENDENCIES
|
47
|
-
|
47
|
+
bson (= 1.2.0)
|
48
|
+
bson_ext (= 1.2.0)
|
48
49
|
bundler (>= 1.0.0)
|
49
50
|
mocha
|
50
|
-
mongo (
|
51
|
-
mongoid (= 2.0.0.
|
51
|
+
mongo (= 1.2.0)
|
52
|
+
mongoid (= 2.0.0.rc.6)
|
52
53
|
mongoid-eager-loading!
|
53
54
|
rspec (~> 2.0.0)
|
54
55
|
watchr
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ mongoid-eager-loading adds the eager loading feature for mongoid.
|
|
5
5
|
|
6
6
|
Originally it is my [pull request][0] for mongoid, but it is not accepted yet, so I created this gem to get the eager loading benefits easily for my projects.
|
7
7
|
|
8
|
-
I only test it in mongoid
|
8
|
+
I only test it in mongoid 2.0.0.beta.19 and 2.0.0.beta.20, maybe you can try it on other mongoid version, and let me know if it works fine.
|
9
9
|
|
10
10
|
Usage
|
11
11
|
-----
|
@@ -18,7 +18,7 @@ suppose you have a mongoid model Post
|
|
18
18
|
|
19
19
|
class Post
|
20
20
|
include Mongoid::Document
|
21
|
-
|
21
|
+
|
22
22
|
referenced_in :user
|
23
23
|
references_many :comments
|
24
24
|
end
|
@@ -27,9 +27,9 @@ then you can use the eager loading like
|
|
27
27
|
|
28
28
|
Post.includes(:user)
|
29
29
|
Post.includes(:user, :comments)
|
30
|
-
|
30
|
+
|
31
31
|
eager loading can be only used on referenced_in, references_one and references_many associations.
|
32
|
-
|
32
|
+
|
33
33
|
Benchmark
|
34
34
|
---------
|
35
35
|
|
@@ -37,12 +37,14 @@ I also run a [benchmark][1] on my local computer, the result is as follows
|
|
37
37
|
|
38
38
|
Starting benchmark...
|
39
39
|
user system total real
|
40
|
-
Finding 10 posts with person, without eager loading 0.
|
41
|
-
Finding 10 posts with person, with eager loading 0.
|
42
|
-
Finding 50 posts with person, without eager loading 0.
|
43
|
-
Finding 50 posts with person, with eager loading 0.
|
44
|
-
Finding 100 posts with person, without eager loading 0.040000 0.000000 0.040000 ( 0.
|
45
|
-
Finding 100 posts with person, with eager loading 0.
|
40
|
+
Finding 10 posts with person, without eager loading 0.000000 0.000000 0.000000 ( 0.005373)
|
41
|
+
Finding 10 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.002984)
|
42
|
+
Finding 50 posts with person, without eager loading 0.010000 0.000000 0.010000 ( 0.022207)
|
43
|
+
Finding 50 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.006831)
|
44
|
+
Finding 100 posts with person, without eager loading 0.040000 0.000000 0.040000 ( 0.050991)
|
45
|
+
Finding 100 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.012867)
|
46
|
+
Finding 1000 posts with person, without eager loading 0.390000 0.050000 0.440000 ( 0.477983)
|
47
|
+
Finding 1000 posts with person, with eager loading 0.120000 0.010000 0.130000 ( 0.128879)
|
46
48
|
|
47
49
|
Author
|
48
50
|
------
|
data/benchmark/benchmark.rb
CHANGED
@@ -5,7 +5,8 @@ require "mongoid"
|
|
5
5
|
require "mongoid-eager-loading"
|
6
6
|
|
7
7
|
Mongoid.configure do |config|
|
8
|
-
config.master = Mongo::Connection.new
|
8
|
+
#config.master = Mongo::Connection.new('localhost', 27018, :logger => Logger.new($stdout)).db("mongoid_perf_test")
|
9
|
+
config.master = Mongo::Connection.new.db("mongoid_perf_test")
|
9
10
|
end
|
10
11
|
|
11
12
|
Mongoid.master.collection("people").drop
|
@@ -36,22 +37,28 @@ Benchmark.bm(60) do |bm|
|
|
36
37
|
bm.report("Finding 10 posts with person, without eager loading") do
|
37
38
|
Post.limit(10).each { |p| p.person.name }
|
38
39
|
end
|
39
|
-
|
40
40
|
bm.report("Finding 10 posts with person, with eager loading") do
|
41
41
|
Post.limit(10).includes(:person).each { |p| p.person.name }
|
42
42
|
end
|
43
|
+
|
43
44
|
bm.report("Finding 50 posts with person, without eager loading") do
|
44
45
|
Post.limit(50).each { |p| p.person.name }
|
45
46
|
end
|
46
|
-
|
47
47
|
bm.report("Finding 50 posts with person, with eager loading") do
|
48
48
|
Post.limit(50).includes(:person).each { |p| p.person.name }
|
49
49
|
end
|
50
|
+
|
50
51
|
bm.report("Finding 100 posts with person, without eager loading") do
|
51
52
|
Post.limit(100).each { |p| p.person.name }
|
52
53
|
end
|
53
|
-
|
54
54
|
bm.report("Finding 100 posts with person, with eager loading") do
|
55
55
|
Post.limit(100).includes(:person).each { |p| p.person.name }
|
56
56
|
end
|
57
|
+
|
58
|
+
bm.report("Finding 1000 posts with person, without eager loading") do
|
59
|
+
Post.limit(1000).each { |p| p.person.name }
|
60
|
+
end
|
61
|
+
bm.report("Finding 1000 posts with person, with eager loading") do
|
62
|
+
Post.limit(1000).includes(:person).each { |p| p.person.name }
|
63
|
+
end
|
57
64
|
end
|
@@ -1,8 +1,3 @@
|
|
1
1
|
require 'mongoid-eager-loading/mongoid/criterion/eager_loading'
|
2
2
|
require 'mongoid-eager-loading/mongoid/criteria'
|
3
|
-
require 'mongoid-eager-loading/mongoid/finders'
|
4
|
-
|
5
|
-
module Mongoid
|
6
|
-
module EagerLoading
|
7
|
-
end
|
8
|
-
end
|
3
|
+
require 'mongoid-eager-loading/mongoid/finders'
|
@@ -35,75 +35,75 @@ module Mongoid
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def setup_associations(documents, reflection)
|
38
|
-
|
38
|
+
case reflection.macro
|
39
|
+
when :references_one
|
39
40
|
setup_associations_with_ids(documents, reflection, true)
|
40
|
-
|
41
|
+
when :references_many
|
41
42
|
setup_associations_with_ids(documents, reflection, false)
|
42
|
-
|
43
|
+
when :references_and_referenced_in_many
|
43
44
|
setup_associations_with_foreign_keys(documents, reflection, false)
|
44
|
-
|
45
|
+
when :referenced_in
|
45
46
|
setup_associations_with_foreign_keys(documents, reflection, true)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
50
|
def setup_associations_with_ids(documents, reflection, one=true)
|
50
|
-
ids =
|
51
|
-
documents.each do |document|
|
52
|
-
add_id_document(document.id, document)
|
53
|
-
ids << document.id if document.id
|
54
|
-
end
|
51
|
+
ids = association_ids(documents, reflection)
|
55
52
|
|
56
|
-
association_class = reflection.name.singularize.camelize.constantize
|
57
53
|
ignore_includes
|
58
|
-
eager_associations =
|
54
|
+
eager_associations = reflection.klass.where(reflection.foreign_key.to_sym.in => ids.uniq).to_a
|
59
55
|
eager_associations.each do |eager_association|
|
60
56
|
add_id_association(eager_association.send(reflection.foreign_key), eager_association)
|
61
57
|
end
|
62
58
|
|
63
|
-
|
64
|
-
documents.each do |document|
|
65
|
-
document.instance_variable_set("@#{reflection.name}", one ? id_associations_map[id].first : id_associations_map[id])
|
66
|
-
end
|
67
|
-
end
|
59
|
+
assign_associations(documents, reflection)
|
68
60
|
end
|
69
61
|
|
70
62
|
def setup_associations_with_foreign_keys(documents, reflection, one)
|
71
|
-
ids =
|
72
|
-
foreign_key_name = reflection.foreign_key
|
73
|
-
documents.each do |document|
|
74
|
-
foreign_key_value = document.send(foreign_key_name)
|
75
|
-
if one
|
76
|
-
add_id_document(foreign_key_value, document)
|
77
|
-
ids << foreign_key_value if foreign_key_value
|
78
|
-
elsif foreign_key_value
|
79
|
-
foreign_key_value.each do |fkv|
|
80
|
-
add_id_document(fkv, document)
|
81
|
-
ids << fkv if fkv
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
63
|
+
ids = association_ids(documents, reflection)
|
85
64
|
|
86
|
-
association_class = reflection.name.singularize.camelize.constantize
|
87
65
|
ignore_includes
|
88
|
-
eager_associations =
|
66
|
+
eager_associations = reflection.klass.find(ids.uniq).to_a
|
89
67
|
eager_associations.each do |eager_association|
|
90
68
|
add_id_association(eager_association.id, eager_association)
|
91
69
|
end
|
92
70
|
|
71
|
+
assign_associations(documents, reflection)
|
72
|
+
end
|
73
|
+
|
74
|
+
def association_ids(documents, reflection)
|
75
|
+
ids = []
|
76
|
+
key_name = reflection.key
|
77
|
+
documents.each do |document|
|
78
|
+
key_value = document.send(key_name)
|
79
|
+
to_array(key_value).each do |v|
|
80
|
+
add_id_document(v, document)
|
81
|
+
ids << v
|
82
|
+
end
|
83
|
+
end
|
84
|
+
ids
|
85
|
+
end
|
86
|
+
|
87
|
+
def assign_associations(documents, reflection)
|
93
88
|
id_documents_map.each do |id, documents|
|
94
89
|
documents.each do |document|
|
95
|
-
|
90
|
+
key_value = document.send(reflection.key)
|
96
91
|
associations = \
|
97
|
-
if
|
98
|
-
id_associations_map[
|
92
|
+
if key_value.is_a?(Array)
|
93
|
+
key_value.collect { |v| id_associations_map[v] }
|
99
94
|
else
|
100
|
-
|
95
|
+
id_associations_map[key_value] ? id_associations_map[key_value].first : nil
|
101
96
|
end
|
102
97
|
document.instance_variable_set("@#{reflection.name}", associations)
|
103
98
|
end
|
104
99
|
end
|
105
100
|
end
|
106
101
|
|
102
|
+
def to_array(value)
|
103
|
+
array = value.is_a?(Array) ? value : [value]
|
104
|
+
array.compact
|
105
|
+
end
|
106
|
+
|
107
107
|
def id_documents_map
|
108
108
|
@id_documents_map ||= {}
|
109
109
|
end
|
@@ -15,12 +15,13 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "mongoid-eager-loading"
|
16
16
|
|
17
17
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
18
|
-
s.add_development_dependency "
|
18
|
+
s.add_development_dependency "mongo", "1.2.0"
|
19
|
+
s.add_development_dependency "bson", "1.2.0"
|
20
|
+
s.add_development_dependency "bson_ext", "1.2.0"
|
21
|
+
s.add_development_dependency "mongoid", "2.0.0.rc.6"
|
19
22
|
s.add_development_dependency "rspec", "~> 2.0.0"
|
20
23
|
s.add_development_dependency "mocha"
|
21
24
|
s.add_development_dependency "watchr"
|
22
|
-
s.add_development_dependency "bson_ext", "~> 1.1.1"
|
23
|
-
s.add_development_dependency "mongo", "~> 1.1.1"
|
24
25
|
|
25
26
|
s.files = `git ls-files`.split("\n")
|
26
27
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
data/spec/models/account.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
class Account
|
2
2
|
include Mongoid::Document
|
3
|
+
field :number, :type => String
|
4
|
+
field :balance, :type => String
|
5
|
+
field :nickname, :type => String
|
6
|
+
field :name, :type => String
|
7
|
+
|
8
|
+
embeds_many :memberships
|
3
9
|
referenced_in :creator, :class_name => "User", :foreign_key => :creator_id
|
4
10
|
referenced_in :person
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
11
|
+
|
12
|
+
attr_accessible :nickname, :name
|
13
|
+
|
14
|
+
validates_presence_of :name
|
15
|
+
validates_length_of :name, :maximum => 10, :on => :create
|
10
16
|
end
|
data/spec/models/address.rb
CHANGED
@@ -15,7 +15,7 @@ class Address
|
|
15
15
|
key :street
|
16
16
|
embeds_many :locations
|
17
17
|
|
18
|
-
embedded_in :addressable, :
|
18
|
+
embedded_in :addressable, :polymorphic => true do
|
19
19
|
def extension
|
20
20
|
"Testing"
|
21
21
|
end
|
@@ -24,6 +24,8 @@ class Address
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
referenced_in :account
|
28
|
+
|
27
29
|
named_scope :rodeo, where(:street => "Rodeo Dr") do
|
28
30
|
def mansion?
|
29
31
|
all? { |address| address.street == "Rodeo Dr" }
|
@@ -31,11 +33,16 @@ class Address
|
|
31
33
|
end
|
32
34
|
|
33
35
|
validates_presence_of :street, :on => :update
|
36
|
+
validates_format_of :street, :with => /\D/, :allow_nil => true
|
34
37
|
|
35
38
|
def set_parent=(set = false)
|
36
39
|
self.parent_title = addressable.title if set
|
37
40
|
end
|
38
41
|
|
42
|
+
def <=>(other)
|
43
|
+
street <=> other.street
|
44
|
+
end
|
45
|
+
|
39
46
|
class << self
|
40
47
|
def california
|
41
48
|
where(:state => "CA")
|
data/spec/models/agent.rb
CHANGED
@@ -2,7 +2,6 @@ class Agent
|
|
2
2
|
include Mongoid::Document
|
3
3
|
field :title
|
4
4
|
field :number
|
5
|
-
embeds_many :names
|
6
|
-
|
7
|
-
accepts_nested_attributes_for :posts, :allow_destroy => true
|
5
|
+
embeds_many :names, :as => :namable
|
6
|
+
referenced_in :game
|
8
7
|
end
|
data/spec/models/animal.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
class Animal
|
2
2
|
include Mongoid::Document
|
3
3
|
field :name
|
4
|
-
field :tags, :type => Array
|
4
|
+
field :tags, :type => Array
|
5
5
|
key :name
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
embedded_in :person
|
8
|
+
|
9
|
+
accepts_nested_attributes_for :person
|
10
|
+
|
8
11
|
def tag_list
|
9
12
|
tags.join(", ")
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
def tag_list=(_tag_list)
|
13
16
|
self.tags = _tag_list.split(",").map(&:strip)
|
14
|
-
end
|
17
|
+
end
|
15
18
|
end
|
data/spec/models/answer.rb
CHANGED
data/spec/models/bar.rb
ADDED
data/spec/models/book.rb
ADDED
data/spec/models/callbacks.rb
CHANGED
@@ -20,13 +20,13 @@ end
|
|
20
20
|
class Song
|
21
21
|
include Mongoid::Document
|
22
22
|
field :title
|
23
|
-
embedded_in :artist
|
23
|
+
embedded_in :artist
|
24
24
|
end
|
25
25
|
|
26
26
|
class Label
|
27
27
|
include Mongoid::Document
|
28
28
|
field :name
|
29
|
-
embedded_in :artist
|
29
|
+
embedded_in :artist
|
30
30
|
before_validation :cleanup
|
31
31
|
|
32
32
|
private
|
data/spec/models/category.rb
CHANGED
@@ -5,9 +5,9 @@ end
|
|
5
5
|
|
6
6
|
class Category
|
7
7
|
include Mongoid::Document
|
8
|
-
embedded_in :root_category
|
9
|
-
embedded_in :category
|
8
|
+
embedded_in :root_category
|
9
|
+
embedded_in :category
|
10
10
|
embeds_many :categories
|
11
11
|
|
12
12
|
field :name
|
13
|
-
end
|
13
|
+
end
|