mongoid 4.0.2 → 5.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/README.md +14 -13
  4. data/lib/config/locales/en.yml +28 -28
  5. data/lib/mongoid.rb +28 -21
  6. data/lib/mongoid/atomic.rb +2 -4
  7. data/lib/mongoid/attributes.rb +7 -7
  8. data/lib/mongoid/attributes/processing.rb +4 -1
  9. data/lib/mongoid/attributes/readonly.rb +2 -2
  10. data/lib/mongoid/changeable.rb +4 -6
  11. data/lib/mongoid/clients.rb +142 -0
  12. data/lib/mongoid/clients/factory.rb +78 -0
  13. data/lib/mongoid/{sessions → clients}/options.rb +30 -19
  14. data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
  15. data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
  16. data/lib/mongoid/clients/validators.rb +2 -0
  17. data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
  18. data/lib/mongoid/composable.rb +3 -3
  19. data/lib/mongoid/config.rb +39 -41
  20. data/lib/mongoid/config/environment.rb +1 -1
  21. data/lib/mongoid/config/validators.rb +1 -1
  22. data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
  23. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  24. data/lib/mongoid/contextual/atomic.rb +11 -11
  25. data/lib/mongoid/contextual/command.rb +9 -6
  26. data/lib/mongoid/contextual/geo_near.rb +17 -1
  27. data/lib/mongoid/contextual/map_reduce.rb +12 -11
  28. data/lib/mongoid/contextual/memory.rb +2 -5
  29. data/lib/mongoid/contextual/mongo.rb +92 -82
  30. data/lib/mongoid/contextual/none.rb +13 -0
  31. data/lib/mongoid/copyable.rb +6 -1
  32. data/lib/mongoid/criteria.rb +36 -3
  33. data/lib/mongoid/document.rb +3 -4
  34. data/lib/mongoid/errors.rb +6 -6
  35. data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
  36. data/lib/mongoid/errors/no_client_config.rb +22 -0
  37. data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
  38. data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
  39. data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
  40. data/lib/mongoid/errors/no_default_client.rb +23 -0
  41. data/lib/mongoid/extensions/hash.rb +5 -1
  42. data/lib/mongoid/extensions/object.rb +3 -2
  43. data/lib/mongoid/extensions/set.rb +5 -5
  44. data/lib/mongoid/factory.rb +4 -2
  45. data/lib/mongoid/fields.rb +7 -2
  46. data/lib/mongoid/findable.rb +4 -1
  47. data/lib/mongoid/indexable.rb +15 -9
  48. data/lib/mongoid/persistable.rb +1 -2
  49. data/lib/mongoid/persistable/creatable.rb +2 -2
  50. data/lib/mongoid/persistable/deletable.rb +3 -3
  51. data/lib/mongoid/persistable/incrementable.rb +1 -1
  52. data/lib/mongoid/persistable/logical.rb +1 -1
  53. data/lib/mongoid/persistable/poppable.rb +1 -1
  54. data/lib/mongoid/persistable/pullable.rb +2 -2
  55. data/lib/mongoid/persistable/pushable.rb +2 -2
  56. data/lib/mongoid/persistable/renamable.rb +1 -1
  57. data/lib/mongoid/persistable/settable.rb +1 -1
  58. data/lib/mongoid/persistable/unsettable.rb +1 -1
  59. data/lib/mongoid/persistable/updatable.rb +2 -2
  60. data/lib/mongoid/persistable/upsertable.rb +1 -1
  61. data/lib/mongoid/query_cache.rb +98 -104
  62. data/lib/mongoid/railtie.rb +1 -21
  63. data/lib/mongoid/railties/database.rake +1 -1
  64. data/lib/mongoid/relations/builders.rb +3 -1
  65. data/lib/mongoid/relations/counter_cache.rb +1 -1
  66. data/lib/mongoid/relations/embedded/batchable.rb +3 -10
  67. data/lib/mongoid/relations/embedded/many.rb +4 -2
  68. data/lib/mongoid/relations/many.rb +1 -0
  69. data/lib/mongoid/relations/proxy.rb +6 -6
  70. data/lib/mongoid/relations/referenced/many.rb +2 -1
  71. data/lib/mongoid/relations/targets/enumerable.rb +11 -11
  72. data/lib/mongoid/relations/touchable.rb +1 -1
  73. data/lib/mongoid/reloadable.rb +2 -2
  74. data/lib/mongoid/scopable.rb +6 -17
  75. data/lib/mongoid/selectable.rb +1 -36
  76. data/lib/mongoid/serializable.rb +2 -2
  77. data/lib/mongoid/stateful.rb +0 -1
  78. data/lib/mongoid/tasks/database.rake +2 -2
  79. data/lib/mongoid/tasks/database.rb +23 -16
  80. data/lib/mongoid/threaded.rb +54 -33
  81. data/lib/mongoid/threaded/lifecycle.rb +21 -16
  82. data/lib/mongoid/traversable.rb +16 -1
  83. data/lib/mongoid/validatable.rb +1 -1
  84. data/lib/mongoid/validatable/queryable.rb +1 -1
  85. data/lib/mongoid/validatable/uniqueness.rb +3 -20
  86. data/lib/mongoid/version.rb +1 -1
  87. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
  88. data/lib/rails/mongoid.rb +2 -2
  89. data/spec/app/models/audio.rb +1 -1
  90. data/spec/app/models/band.rb +1 -0
  91. data/spec/app/models/company.rb +5 -0
  92. data/spec/app/models/label.rb +7 -0
  93. data/spec/app/models/pub.rb +6 -0
  94. data/spec/app/models/staff.rb +7 -0
  95. data/spec/app/models/store_as_dup_test1.rb +5 -0
  96. data/spec/app/models/store_as_dup_test2.rb +5 -0
  97. data/spec/config/mongoid.yml +7 -25
  98. data/spec/mongoid/atomic/paths_spec.rb +3 -11
  99. data/spec/mongoid/attributes/nested_spec.rb +16 -16
  100. data/spec/mongoid/attributes/readonly_spec.rb +80 -18
  101. data/spec/mongoid/attributes_spec.rb +3 -3
  102. data/spec/mongoid/changeable_spec.rb +70 -0
  103. data/spec/mongoid/clients/factory_spec.rb +284 -0
  104. data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
  105. data/spec/mongoid/clients_spec.rb +739 -0
  106. data/spec/mongoid/config/environment_spec.rb +14 -11
  107. data/spec/mongoid/config_spec.rb +33 -48
  108. data/spec/mongoid/contextual/atomic_spec.rb +1 -17
  109. data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
  110. data/spec/mongoid/contextual/mongo_spec.rb +26 -83
  111. data/spec/mongoid/contextual/none_spec.rb +15 -0
  112. data/spec/mongoid/copyable_spec.rb +35 -1
  113. data/spec/mongoid/criteria/findable_spec.rb +197 -0
  114. data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
  115. data/spec/mongoid/criteria_spec.rb +74 -91
  116. data/spec/mongoid/document_spec.rb +1 -1
  117. data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
  118. data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
  119. data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
  120. data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
  121. data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
  122. data/spec/mongoid/fields/localized_spec.rb +1 -0
  123. data/spec/mongoid/fields_spec.rb +1 -0
  124. data/spec/mongoid/findable_spec.rb +2 -23
  125. data/spec/mongoid/indexable_spec.rb +12 -8
  126. data/spec/mongoid/interceptable_spec.rb +15 -0
  127. data/spec/mongoid/persistable/settable_spec.rb +16 -0
  128. data/spec/mongoid/persistable/updatable_spec.rb +3 -2
  129. data/spec/mongoid/persistable_spec.rb +4 -4
  130. data/spec/mongoid/query_cache_spec.rb +13 -8
  131. data/spec/mongoid/relations/auto_save_spec.rb +1 -1
  132. data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
  133. data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
  134. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
  135. data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
  136. data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
  137. data/spec/mongoid/relations/proxy_spec.rb +28 -0
  138. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  139. data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
  140. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
  141. data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
  142. data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
  143. data/spec/mongoid/reloadable_spec.rb +6 -6
  144. data/spec/mongoid/scopable_spec.rb +41 -28
  145. data/spec/mongoid/selectable_spec.rb +6 -16
  146. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  147. data/spec/mongoid/tasks/database_spec.rb +2 -2
  148. data/spec/mongoid/threaded_spec.rb +0 -7
  149. data/spec/mongoid/traversable_spec.rb +2 -2
  150. data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
  151. data/spec/mongoid_spec.rb +13 -15
  152. data/spec/rails/mongoid_spec.rb +13 -4
  153. data/spec/spec_helper.rb +44 -27
  154. data/spec/support/authorization.rb +12 -0
  155. data/spec/support/expectations.rb +14 -0
  156. metadata +52 -59
  157. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  158. data/lib/mongoid/contextual/text_search.rb +0 -178
  159. data/lib/mongoid/criteria/#findable.rb# +0 -141
  160. data/lib/mongoid/errors/no_default_session.rb +0 -23
  161. data/lib/mongoid/errors/no_session_config.rb +0 -22
  162. data/lib/mongoid/log_subscriber.rb +0 -55
  163. data/lib/mongoid/positional.rb +0 -71
  164. data/lib/mongoid/sessions.rb +0 -125
  165. data/lib/mongoid/sessions/factory.rb +0 -131
  166. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  167. data/lib/mongoid/sessions/validators.rb +0 -2
  168. data/lib/mongoid/support/query_counter.rb +0 -23
  169. data/spec/helpers.rb +0 -18
  170. data/spec/mongoid/#atomic_spec.rb# +0 -365
  171. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  172. data/spec/mongoid/contextual/text_search_spec.rb +0 -209
  173. data/spec/mongoid/log_subscriber_spec.rb +0 -75
  174. data/spec/mongoid/positional_spec.rb +0 -222
  175. data/spec/mongoid/sessions/factory_spec.rb +0 -333
  176. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  177. data/spec/mongoid/sessions_spec.rb +0 -1252
@@ -2,6 +2,7 @@
2
2
  module Mongoid
3
3
  module Contextual
4
4
  module Command
5
+ extend Gem::Deprecate
5
6
 
6
7
  # @attribute [r] collection The collection to query against.
7
8
  # @attribute [r] criteria The criteria for the context.
@@ -19,17 +20,19 @@ module Mongoid
19
20
  @command ||= {}
20
21
  end
21
22
 
22
- # Get the database session.
23
+ # Get the database client.
23
24
  #
24
- # @example Get the session.
25
- # command.session
25
+ # @example Get the client.
26
+ # command.client
26
27
  #
27
- # @return [ Session ] The Moped session.
28
+ # @return [ Mongo::Client ] The Mongo client.
28
29
  #
29
30
  # @since 3.0.0
30
- def session
31
- collection.database.session
31
+ def client
32
+ collection.database.client
32
33
  end
34
+ alias :session :client
35
+ deprecate :session, :client, 2015, 12
33
36
  end
34
37
  end
35
38
  end
@@ -90,6 +90,7 @@ module Mongoid
90
90
  near: #{command[:near]}
91
91
  multiplier: #{command[:distanceMultiplier] || "N/A"}
92
92
  max: #{command[:maxDistance] || "N/A"}
93
+ min: #{command[:minDistance] || "N/A"}
93
94
  unique: #{command[:unique].nil? ? true : command[:unique]}
94
95
  spherical: #{command[:spherical] || false}>
95
96
  }
@@ -118,6 +119,21 @@ module Mongoid
118
119
  end
119
120
  end
120
121
 
122
+ # Specify the minimum distance to find documents for.
123
+ #
124
+ # @example Set the min distance.
125
+ # geo_near.min_distance(0.5)
126
+ #
127
+ # @param [ Integer, Float ] value The minimum distance.
128
+ #
129
+ # @return [ GeoNear ] The GeoNear command.
130
+ #
131
+ # @since 3.1.0
132
+ def min_distance(value)
133
+ command[:minDistance] = value
134
+ self
135
+ end
136
+
121
137
  # Tell the command to calculate based on spherical distances.
122
138
  #
123
139
  # @example Add the spherical flag.
@@ -230,7 +246,7 @@ module Mongoid
230
246
  #
231
247
  # @since 3.0.0
232
248
  def results
233
- @results ||= session.command(command)
249
+ @results ||= client.command(command).first
234
250
  end
235
251
  end
236
252
  end
@@ -268,9 +268,9 @@ module Mongoid
268
268
  # @since 3.0.0
269
269
  def documents
270
270
  return results["results"] if results.has_key?("results")
271
- query = session[output_collection].find
272
- query.no_timeout if criteria.options[:timeout] == false
273
- query
271
+ view = client[output_collection].find
272
+ view.no_cursor_timeout if criteria.options[:timeout] == false
273
+ view
274
274
  end
275
275
 
276
276
  # Get the collection that the map/reduce results were stored in.
@@ -299,26 +299,27 @@ module Mongoid
299
299
  # @since 3.0.0
300
300
  def results
301
301
  raise Errors::NoMapReduceOutput.new(command) unless command[:out]
302
- @results ||= __session__.command(command)
302
+ @results ||= __client__.command(command).first
303
303
  end
304
304
 
305
- # Get the session with the proper consistency.
305
+ # Get the client with the proper consistency.
306
306
  #
307
307
  # @api private
308
308
  #
309
309
  # @note We can use eventual if the output is set to inline.
310
310
  #
311
- # @example Get the session.
312
- # map_reduce.__session__
311
+ # @example Get the client.
312
+ # map_reduce.__client__
313
313
  #
314
- # @return [ Session ] The session with consistency set.
314
+ # @return [ Mongo::Client ] The client with consistency set.
315
315
  #
316
316
  # @since 3.0.15
317
- def __session__
317
+ def __client__
318
318
  if command[:out][:inline] != 1
319
- session.with(read: :primary)
319
+ # @todo: close
320
+ client.with(read: { mode: :primary })
320
321
  else
321
- session
322
+ client
322
323
  end
323
324
  end
324
325
  end
@@ -9,7 +9,6 @@ module Mongoid
9
9
  include Aggregable::Memory
10
10
  include Relations::Eager
11
11
  include Queryable
12
- include Positional
13
12
 
14
13
  # @attribute [r] root The root document.
15
14
  # @attribute [r] path The atomic path.
@@ -47,9 +46,7 @@ module Mongoid
47
46
  doc.as_document
48
47
  end
49
48
  unless removed.empty?
50
- collection.find(selector).update(
51
- positionally(selector, "$pullAll" => { path => removed })
52
- )
49
+ collection.find(selector).update_one("$pullAll" => { path => removed })
53
50
  end
54
51
  deleted
55
52
  end
@@ -307,7 +304,7 @@ module Mongoid
307
304
  updates["$set"].merge!(doc.atomic_updates["$set"] || {})
308
305
  doc.move_changes
309
306
  end
310
- collection.find(selector).update(updates) unless updates["$set"].empty?
307
+ collection.find(selector).update_one(updates) unless updates["$set"].empty?
311
308
  end
312
309
 
313
310
  # Get the limiting value.
@@ -2,10 +2,8 @@
2
2
  require "mongoid/contextual/atomic"
3
3
  require "mongoid/contextual/aggregable/mongo"
4
4
  require "mongoid/contextual/command"
5
- require "mongoid/contextual/find_and_modify"
6
5
  require "mongoid/contextual/geo_near"
7
6
  require "mongoid/contextual/map_reduce"
8
- require "mongoid/contextual/text_search"
9
7
  require "mongoid/relations/eager"
10
8
 
11
9
  module Mongoid
@@ -17,8 +15,13 @@ module Mongoid
17
15
  include Relations::Eager
18
16
  include Queryable
19
17
 
20
- # @attribute [r] query The Moped query.
21
- attr_reader :query
18
+ # Options constant.
19
+ #
20
+ # @since 5.0.0
21
+ OPTIONS = [ :hint, :limit, :skip, :sort, :batch_size, :max_scan, :snapshot, :comment, :read ].freeze
22
+
23
+ # @attribute [r] view The Mongo collection view.
24
+ attr_reader :view
22
25
 
23
26
  # Is the context cached?
24
27
  #
@@ -37,27 +40,23 @@ module Mongoid
37
40
  # @example Get the number of matching documents.
38
41
  # context.count
39
42
  #
40
- # @example Get the count of documents matching the provided.
41
- # context.count(document)
43
+ # @example Get the count of documents with the provided options.
44
+ # context.count(limit: 1)
42
45
  #
43
46
  # @example Get the count for where the provided block is true.
44
47
  # context.count do |doc|
45
48
  # doc.likes > 1
46
49
  # end
47
50
  #
48
- # @param [ Document ] document A document to match or true if wanting
49
- # skip and limit to be factored into the count.
51
+ # @param [ Hash ] options The options, such as skip and limit to be factored
52
+ # into the count.
50
53
  #
51
54
  # @return [ Integer ] The number of matches.
52
55
  #
53
56
  # @since 3.0.0
54
- def count(document = false, &block)
57
+ def count(options = {}, &block)
55
58
  return super(&block) if block_given?
56
- if document.is_a?(Document)
57
- return collection.find(criteria.and(_id: document._id).selector).count
58
- end
59
- return query.count(document) if document
60
- try_cache(:count) { query.count }
59
+ try_cache(:count) { view.count(options) }
61
60
  end
62
61
 
63
62
  # Delete all documents in the database that match the selector.
@@ -70,7 +69,7 @@ module Mongoid
70
69
  # @since 3.0.0
71
70
  def delete
72
71
  self.count.tap do
73
- query.remove_all
72
+ view.delete_many
74
73
  end
75
74
  end
76
75
  alias :delete_all :delete
@@ -103,7 +102,7 @@ module Mongoid
103
102
  #
104
103
  # @since 3.0.0
105
104
  def distinct(field)
106
- query.distinct(klass.database_field_name(field))
105
+ view.distinct(klass.database_field_name(field))
107
106
  end
108
107
 
109
108
  # Iterate over the context. If provided a block, yield to a Mongoid
@@ -146,7 +145,7 @@ module Mongoid
146
145
  return @count > 0 if instance_variable_defined?(:@count)
147
146
 
148
147
  try_cache(:exists) do
149
- !!(query.dup.select(_id: 1).limit(1).first)
148
+ !!(view.projection(_id: 1).limit(1).first)
150
149
  end
151
150
  end
152
151
 
@@ -159,27 +158,64 @@ module Mongoid
159
158
  #
160
159
  # @since 3.0.0
161
160
  def explain
162
- query.explain
161
+ view.explain
163
162
  end
164
163
 
165
164
  # Execute the find and modify command, used for MongoDB's
166
165
  # $findAndModify.
167
166
  #
168
167
  # @example Execute the command.
169
- # context.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
168
+ # context.find_one_and_update({ "$inc" => { likes: 1 }})
170
169
  #
171
170
  # @param [ Hash ] update The updates.
172
171
  # @param [ Hash ] options The command options.
173
172
  #
174
- # @option options [ true, false ] :new Return the updated document.
175
- # @option options [ true, false ] :remove Delete the first document.
173
+ # @option options [ :before, :after ] :return_document Return the updated document
174
+ # from before or after update.
176
175
  # @option options [ true, false ] :upsert Create the document if it doesn't exist.
177
176
  #
178
177
  # @return [ Document ] The result of the command.
179
178
  #
180
- # @since 3.0.0
181
- def find_and_modify(update, options = {})
182
- if doc = FindAndModify.new(collection, criteria, update, options).result
179
+ # @since 5.0.0
180
+ def find_one_and_update(update, options = {})
181
+ if doc = view.find_one_and_update(update, options)
182
+ Factory.from_db(klass, doc)
183
+ end
184
+ end
185
+
186
+ # Execute the find and modify command, used for MongoDB's
187
+ # $findAndModify.
188
+ #
189
+ # @example Execute the command.
190
+ # context.find_one_and_update({ likes: 1 })
191
+ #
192
+ # @param [ Hash ] update The updates.
193
+ # @param [ Hash ] options The command options.
194
+ #
195
+ # @option options [ :before, :after ] :return_document Return the updated document
196
+ # from before or after update.
197
+ # @option options [ true, false ] :upsert Create the document if it doesn't exist.
198
+ #
199
+ # @return [ Document ] The result of the command.
200
+ #
201
+ # @since 5.0.0
202
+ def find_one_and_replace(replacement, options = {})
203
+ if doc = view.find_one_and_replace(replacement, options)
204
+ Factory.from_db(klass, doc)
205
+ end
206
+ end
207
+
208
+ # Execute the find and modify command, used for MongoDB's
209
+ # $findAndModify. This deletes the found document.
210
+ #
211
+ # @example Execute the command.
212
+ # context.find_one_and_delete
213
+ #
214
+ # @return [ Document ] The result of the command.
215
+ #
216
+ # @since 5.0.0
217
+ def find_one_and_delete
218
+ if doc = view.find_one_and_delete
183
219
  Factory.from_db(klass, doc)
184
220
  end
185
221
  end
@@ -189,15 +225,19 @@ module Mongoid
189
225
  # @example Get the first document.
190
226
  # context.first
191
227
  #
228
+ # @note Mongoid previously added an _id sort when no sort parameters were
229
+ # provided explicitly by the user. This caused bad performance issues
230
+ # and was not expected, so #first/#last will no longer guarantee order
231
+ # if no sorting parameters are provided. For order guarantees - a sort
232
+ # must be explicitly provided.
233
+ #
192
234
  # @return [ Document ] The first document.
193
235
  #
194
236
  # @since 3.0.0
195
237
  def first
196
238
  return documents.first if cached? && cache_loaded?
197
239
  try_cache(:first) do
198
- with_sorting do
199
- with_eager_loading(query.first)
200
- end
240
+ with_eager_loading(view.first)
201
241
  end
202
242
  end
203
243
  alias :one :first
@@ -209,7 +249,7 @@ module Mongoid
209
249
  # @since 4.0.2
210
250
  def find_first
211
251
  return documents.first if cached? && cache_loaded?
212
- with_eager_loading(query.first)
252
+ with_eager_loading(view.first)
213
253
  end
214
254
 
215
255
  # Execute a $geoNear command against the database.
@@ -260,7 +300,7 @@ module Mongoid
260
300
  end
261
301
 
262
302
  # Create the new Mongo context. This delegates operations to the
263
- # underlying driver - in Mongoid's case Moped.
303
+ # underlying driver.
264
304
  #
265
305
  # @example Create the new context.
266
306
  # Mongo.new(criteria)
@@ -272,7 +312,7 @@ module Mongoid
272
312
  @criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
273
313
  @collection = @klass.with(criteria.persistence_options || {}).collection
274
314
  criteria.send(:merge_type_selection)
275
- @query = collection.find(criteria.selector)
315
+ @view = collection.find(criteria.selector)
276
316
  apply_options
277
317
  end
278
318
 
@@ -283,13 +323,19 @@ module Mongoid
283
323
  # @example Get the last document.
284
324
  # context.last
285
325
  #
326
+ # @note Mongoid previously added an _id sort when no sort parameters were
327
+ # provided explicitly by the user. This caused bad performance issues
328
+ # and was not expected, so #first/#last will no longer guarantee order
329
+ # if no sorting parameters are provided. For order guarantees - a sort
330
+ # must be explicitly provided.
331
+ #
286
332
  # @return [ Document ] The last document.
287
333
  #
288
334
  # @since 3.0.0
289
335
  def last
290
336
  try_cache(:last) do
291
337
  with_inverse_sorting do
292
- with_eager_loading(query.first)
338
+ with_eager_loading(view.first)
293
339
  end
294
340
  end
295
341
  end
@@ -318,7 +364,7 @@ module Mongoid
318
364
  #
319
365
  # @since 3.0.0
320
366
  def limit(value)
321
- query.limit(value) and self
367
+ @view = view.limit(value) and self
322
368
  end
323
369
 
324
370
  # Initiate a map/reduce operation from the context.
@@ -356,7 +402,7 @@ module Mongoid
356
402
  hash
357
403
  end
358
404
 
359
- query.dup.select(normalized_select).map do |doc|
405
+ view.projection(normalized_select).map do |doc|
360
406
  if normalized_select.size == 1
361
407
  doc[normalized_select.keys.first]
362
408
  else
@@ -376,7 +422,7 @@ module Mongoid
376
422
  #
377
423
  # @since 3.0.0
378
424
  def skip(value)
379
- query.skip(value) and self
425
+ @view = view.skip(value) and self
380
426
  end
381
427
 
382
428
  # Sorts the documents by the provided spec.
@@ -401,20 +447,6 @@ module Mongoid
401
447
  end
402
448
  end
403
449
 
404
- # Execute a text command against the database.
405
- #
406
- # @example Find documents with the text "phase"
407
- # context.text_search("phase")
408
- #
409
- # @param [ String ] query The text search query.
410
- #
411
- # @return [ TextSearch ] The TextSearch command.
412
- #
413
- # @since 4.0.0
414
- def text_search(query)
415
- TextSearch.new(collection, criteria, query)
416
- end
417
-
418
450
  # Update the first matching document atomically.
419
451
  #
420
452
  # @example Update the first matching document.
@@ -440,7 +472,7 @@ module Mongoid
440
472
  #
441
473
  # @since 3.0.0
442
474
  def update_all(attributes = nil)
443
- update_documents(attributes, :update_all)
475
+ update_documents(attributes, :update_many)
444
476
  end
445
477
 
446
478
  private
@@ -476,10 +508,10 @@ module Mongoid
476
508
  # @return [ true, false ] If the update succeeded.
477
509
  #
478
510
  # @since 3.0.4
479
- def update_documents(attributes, method = :update)
511
+ def update_documents(attributes, method = :update_one)
480
512
  return false unless attributes
481
513
  attributes = Hash[attributes.map { |k, v| [klass.database_field_name(k.to_s), v] }]
482
- query.send(method, attributes.__consolidate__(klass))
514
+ view.send(method, attributes.__consolidate__(klass))
483
515
  end
484
516
 
485
517
  # Apply the field limitations.
@@ -492,7 +524,7 @@ module Mongoid
492
524
  # @since 3.0.0
493
525
  def apply_fields
494
526
  if spec = criteria.options[:fields]
495
- query.select(spec)
527
+ @view = view.projection(spec)
496
528
  end
497
529
  end
498
530
 
@@ -506,11 +538,11 @@ module Mongoid
506
538
  # @since 3.1.0
507
539
  def apply_options
508
540
  apply_fields
509
- [ :hint, :limit, :skip, :sort, :batch_size, :max_scan ].each do |name|
541
+ OPTIONS.each do |name|
510
542
  apply_option(name)
511
543
  end
512
544
  if criteria.options[:timeout] == false
513
- query.no_timeout
545
+ @view = view.no_cursor_timeout
514
546
  end
515
547
  end
516
548
 
@@ -524,33 +556,13 @@ module Mongoid
524
556
  # @since 3.1.0
525
557
  def apply_option(name)
526
558
  if spec = criteria.options[name]
527
- query.send(name, spec)
528
- end
529
- end
530
-
531
- # Apply an ascending id sort for use with #first queries, only if no
532
- # other sorting is provided.
533
- #
534
- # @api private
535
- #
536
- # @example Apply the id sorting params to the given block
537
- # context.with_sorting
538
- #
539
- # @since 3.0.0
540
- def with_sorting
541
- begin
542
- unless criteria.options.has_key?(:sort)
543
- query.sort(_id: 1)
544
- end
545
- yield
546
- ensure
547
- apply_option(:sort)
559
+ @view = view.send(name, spec)
548
560
  end
549
561
  end
550
562
 
551
563
  # Map the inverse sort symbols to the correct MongoDB values.
552
564
  #
553
- # @api private
565
+ # @api private
554
566
  #
555
567
  # @example Apply the inverse sorting params to the given block
556
568
  # context.with_inverse_sorting
@@ -559,9 +571,7 @@ module Mongoid
559
571
  def with_inverse_sorting
560
572
  begin
561
573
  if spec = criteria.options[:sort]
562
- query.sort(Hash[spec.map{|k, v| [k, -1*v]}])
563
- else
564
- query.sort(_id: -1)
574
+ @view = view.sort(Hash[spec.map{|k, v| [k, -1*v]}])
565
575
  end
566
576
  yield
567
577
  ensure
@@ -625,18 +635,18 @@ module Mongoid
625
635
  # @example Get the documents for iteration.
626
636
  # context.documents_for_iteration
627
637
  #
628
- # @return [ Array<Document>, Moped::Query ] The docs to iterate.
638
+ # @return [ Array<Document>, Mongo::Collection::View ] The docs to iterate.
629
639
  #
630
640
  # @since 3.0.0
631
641
  def documents_for_iteration
632
642
  if cached? && !documents.empty?
633
643
  documents
634
644
  elsif eager_loadable?
635
- docs = query.map{ |doc| Factory.from_db(klass, doc, criteria.options[:fields]) }
645
+ docs = view.map{ |doc| Factory.from_db(klass, doc, criteria.options[:fields]) }
636
646
  eager_load(docs)
637
647
  docs
638
648
  else
639
- query
649
+ view
640
650
  end
641
651
  end
642
652