mongoid 4.0.2 → 5.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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