mongoid 6.3.0 → 6.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +12 -0
- data/lib/config/locales/en.yml +21 -0
- data/lib/mongoid.rb +2 -2
- data/lib/mongoid/clients.rb +2 -0
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +7 -2
- data/lib/mongoid/contextual/mongo.rb +11 -2
- data/lib/mongoid/criteria.rb +1 -0
- data/lib/mongoid/criteria/modifiable.rb +12 -2
- data/lib/mongoid/criteria/queryable/mergeable.rb +3 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +34 -7
- data/lib/mongoid/document.rb +4 -4
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +3 -1
- data/lib/mongoid/indexable.rb +4 -4
- data/lib/mongoid/matchable.rb +3 -0
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/persistable.rb +1 -1
- data/lib/mongoid/persistable/creatable.rb +4 -2
- data/lib/mongoid/persistable/deletable.rb +4 -2
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistence_context.rb +4 -0
- data/lib/mongoid/railtie.rb +17 -0
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/embedded/batchable.rb +10 -4
- data/lib/mongoid/relations/embedded/many.rb +23 -0
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/referenced/many.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/reloadable.rb +1 -1
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/attributes/nested_spec.rb +4 -0
- data/spec/mongoid/clients/factory_spec.rb +52 -28
- data/spec/mongoid/clients/options_spec.rb +30 -15
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +40 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +74 -6
- data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +4 -1
- data/spec/mongoid/document_spec.rb +54 -0
- data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +35 -7
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +1 -1
- data/spec/mongoid/interceptable_spec.rb +1 -1
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable_spec.rb +26 -1
- data/spec/mongoid/persistable/deletable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +19 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/settable_spec.rb +35 -1
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/relations/embedded/many_spec.rb +246 -16
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/spec_config.rb +42 -0
- metadata +471 -443
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6df494597043866e131edd0f3ac733a2b9858819d0ea5e64dd71a876dc0f5c92
|
4
|
+
data.tar.gz: 11b00b2c3c74e486c605729487caacbad6b6790ad1168d9f9f25088018187c1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef53e2257470d0ba736764568da53a4ccef25e525d1f5782c7e364f313be22f0b6c5bbabab354608da0de5887e7f505602936cc3e701fc1487c0969bcae3061e
|
7
|
+
data.tar.gz: 2fe686e8ad285385f787079a8a065e4ad7311dc1a034be6bcc722611d976b5b9b3bf421fc9a6fab861dce3d296178138c325998bada913e5b8f8d83298b3ee6c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Rakefile
CHANGED
@@ -33,3 +33,15 @@ RSpec::Core::RakeTask.new('spec:progress') do |spec|
|
|
33
33
|
end
|
34
34
|
|
35
35
|
task :default => :spec
|
36
|
+
|
37
|
+
desc "Generate all documentation"
|
38
|
+
task :docs => 'docs:yard'
|
39
|
+
|
40
|
+
namespace :docs do
|
41
|
+
desc "Generate yard documention"
|
42
|
+
task :yard do
|
43
|
+
out = File.join('yard-docs', Mongoid::VERSION)
|
44
|
+
FileUtils.rm_rf(out)
|
45
|
+
system "yardoc -o #{out} --title mongoid-#{Mongoid::VERSION}"
|
46
|
+
end
|
47
|
+
end
|
data/lib/config/locales/en.yml
CHANGED
@@ -206,6 +206,20 @@ en:
|
|
206
206
|
\_\_\_\_include Mongoid::Document\n
|
207
207
|
\_\_\_\_scope :inactive, ->{ where(active: false) }\n
|
208
208
|
\_\_end\n\n"
|
209
|
+
invalid_session_use:
|
210
|
+
message: "A session was attempted to be used with a model whose client cannot use
|
211
|
+
that session."
|
212
|
+
summary: "Sessions are started via driver clients (Model#mongo_client) and, in most cases, driver
|
213
|
+
clients are shared across models. When different models have their own clients, a session cannot
|
214
|
+
be obtained via one model and used for operations on another model."
|
215
|
+
resolution: "Only execute operations on the model class or instances of the model through which
|
216
|
+
the session was created. Otherwise, ensure that all models on which operations are executed
|
217
|
+
in the session block share the same driver client. For example, a model may have a different
|
218
|
+
client specified in its 'store_in' options.\n\n"
|
219
|
+
invalid_session_nesting:
|
220
|
+
message: "A session was started while another session was being used."
|
221
|
+
summary: "Sessions cannot be nested. Only one session can be used in a thread at once."
|
222
|
+
resolution: "Only use one session at a time; sessions cannot be nested."
|
209
223
|
invalid_storage_options:
|
210
224
|
message: "Invalid options passed to %{klass}.store_in: %{options}."
|
211
225
|
summary: "The :store_in macro takes only a hash of parameters with
|
@@ -452,6 +466,13 @@ en:
|
|
452
466
|
with the already defined method %{model_name}, or set the
|
453
467
|
configuration option Mongoid.scope_overwrite_exception to false,
|
454
468
|
which is its default. In this case a warning will be logged."
|
469
|
+
sessions_not_supported:
|
470
|
+
message: "Sessions are not supported by the connected server(s)."
|
471
|
+
summary: "A session was attempted to be used with a MongoDB server version
|
472
|
+
that doesn't support sessions. Sessions are supported in MongoDB
|
473
|
+
server versions 3.6 and higher."
|
474
|
+
resolution: "Verify that all servers in your deployment are at least
|
475
|
+
version 3.6 or don't attempt to use sessions with older server versions."
|
455
476
|
taken:
|
456
477
|
"is already taken"
|
457
478
|
too_many_nested_attribute_records:
|
data/lib/mongoid.rb
CHANGED
@@ -42,7 +42,7 @@ module Mongoid
|
|
42
42
|
PLATFORM_DETAILS = "mongoid-#{VERSION}".freeze
|
43
43
|
|
44
44
|
# The minimum MongoDB version supported.
|
45
|
-
MONGODB_VERSION = "2.
|
45
|
+
MONGODB_VERSION = "2.6.0"
|
46
46
|
|
47
47
|
# Sets the Mongoid configuration options. Best used by passing a block.
|
48
48
|
#
|
@@ -101,5 +101,5 @@ module Mongoid
|
|
101
101
|
# Mongoid.database = Mongo::Connection.new.db("test")
|
102
102
|
#
|
103
103
|
# @since 1.0.0
|
104
|
-
delegate(*(Config.public_instance_methods(false) - [ :logger=, :logger ]
|
104
|
+
delegate(*(Config.public_instance_methods(false) - [ :logger=, :logger ]), to: Config)
|
105
105
|
end
|
data/lib/mongoid/clients.rb
CHANGED
@@ -3,12 +3,14 @@ require "mongoid/clients/factory"
|
|
3
3
|
require "mongoid/clients/validators"
|
4
4
|
require "mongoid/clients/storage_options"
|
5
5
|
require "mongoid/clients/options"
|
6
|
+
require "mongoid/clients/sessions"
|
6
7
|
|
7
8
|
module Mongoid
|
8
9
|
module Clients
|
9
10
|
extend ActiveSupport::Concern
|
10
11
|
include StorageOptions
|
11
12
|
include Options
|
13
|
+
include Sessions
|
12
14
|
|
13
15
|
class << self
|
14
16
|
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Clients
|
3
|
+
|
4
|
+
# Encapsulates behavior for getting a session from the client of a model class or instance,
|
5
|
+
# setting the session on the current thread, and yielding to a block.
|
6
|
+
# The session will be closed after the block completes or raises an error.
|
7
|
+
#
|
8
|
+
# @since 6.4.0
|
9
|
+
module Sessions
|
10
|
+
|
11
|
+
# Execute a block within the context of a session.
|
12
|
+
#
|
13
|
+
# @example Execute some operations in the context of a session.
|
14
|
+
# band.with_session(causal_consistency: true) do
|
15
|
+
# band.records << Record.create
|
16
|
+
# band.name = 'FKA Twigs'
|
17
|
+
# band.save
|
18
|
+
# band.reload
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @param [ Hash ] options The session options. Please see the driver
|
22
|
+
# documentation for the available session options.
|
23
|
+
#
|
24
|
+
# @note You cannot do any operations in the block using models or objects
|
25
|
+
# that use a different client; the block will execute all operations
|
26
|
+
# in the context of the implicit session and operations on any models using
|
27
|
+
# another client will fail. For example, if you set a client using store_in on a
|
28
|
+
# particular model and execute an operation on it in the session context block,
|
29
|
+
# that operation can't use the block's session and an error will be raised.
|
30
|
+
# An error will also be raised if sessions are nested.
|
31
|
+
#
|
32
|
+
# @raise [ Errors::InvalidSessionUse ] If an operation is attempted on a model using another
|
33
|
+
# client from which the session was started or if sessions are nested.
|
34
|
+
#
|
35
|
+
# @return [ Object ] The result of calling the block.
|
36
|
+
#
|
37
|
+
# @yieldparam [ Mongo::Session ] The session being used for the block.
|
38
|
+
#
|
39
|
+
# @since 6.4.0
|
40
|
+
def with_session(options = {})
|
41
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
|
42
|
+
session = persistence_context.client.start_session(options)
|
43
|
+
Threaded.set_session(session)
|
44
|
+
yield(session)
|
45
|
+
rescue Mongo::Error::InvalidSession => ex
|
46
|
+
if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
47
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
48
|
+
end
|
49
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|
50
|
+
ensure
|
51
|
+
Threaded.clear_session
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def _session
|
57
|
+
Threaded.get_session
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
|
62
|
+
# Execute a block within the context of a session.
|
63
|
+
#
|
64
|
+
# @example Execute some operations in the context of a session.
|
65
|
+
# Band.with_session(causal_consistency: true) do
|
66
|
+
# band = Band.create
|
67
|
+
# band.records << Record.new
|
68
|
+
# band.save
|
69
|
+
# band.reload.records
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# @param [ Hash ] options The session options. Please see the driver
|
73
|
+
# documentation for the available session options.
|
74
|
+
#
|
75
|
+
# @note You cannot do any operations in the block using models or objects
|
76
|
+
# that use a different client; the block will execute all operations
|
77
|
+
# in the context of the implicit session and operations on any models using
|
78
|
+
# another client will fail. For example, if you set a client using store_in on a
|
79
|
+
# particular model and execute an operation on it in the session context block,
|
80
|
+
# that operation can't use the block's session and an error will be raised.
|
81
|
+
# You also cannot nest sessions.
|
82
|
+
#
|
83
|
+
# @raise [ Errors::InvalidSessionUse ] If an operation is attempted on a model using another
|
84
|
+
# client from which the session was started or if sessions are nested.
|
85
|
+
#
|
86
|
+
# @return [ Object ] The result of calling the block.
|
87
|
+
#
|
88
|
+
# @yieldparam [ Mongo::Session ] The session being used for the block.
|
89
|
+
#
|
90
|
+
# @since 6.4.0
|
91
|
+
def with_session(options = {})
|
92
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
|
93
|
+
session = persistence_context.client.start_session(options)
|
94
|
+
Threaded.set_session(session)
|
95
|
+
yield(session)
|
96
|
+
rescue Mongo::Error::InvalidSession => ex
|
97
|
+
if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
98
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
99
|
+
end
|
100
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|
101
|
+
ensure
|
102
|
+
Threaded.clear_session
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def _session
|
108
|
+
Threaded.get_session
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -23,7 +23,7 @@ module Mongoid
|
|
23
23
|
#
|
24
24
|
# @since 3.0.0
|
25
25
|
def aggregates(field)
|
26
|
-
result = collection.find.aggregate(pipeline(field)).to_a
|
26
|
+
result = collection.find.aggregate(pipeline(field), session: _session).to_a
|
27
27
|
if result.empty?
|
28
28
|
{ "count" => 0, "sum" => nil, "avg" => nil, "min" => nil, "max" => nil }
|
29
29
|
else
|
@@ -165,13 +165,13 @@ module Mongoid
|
|
165
165
|
def raw
|
166
166
|
validate_out!
|
167
167
|
cmd = command
|
168
|
-
opts = { read: cmd.delete(:read)
|
169
|
-
@map_reduce.database.command(cmd, opts || {}).first
|
168
|
+
opts = { read: cmd.delete(:read) } if cmd[:read]
|
169
|
+
@map_reduce.database.command(cmd, (opts || {}).merge(session: _session)).first
|
170
170
|
end
|
171
171
|
alias :results :raw
|
172
172
|
|
173
173
|
# Execute the map/reduce, returning the raw output.
|
174
|
-
# Useful when you don't care about map/reduce's
|
174
|
+
# Useful when you don't care about map/reduce's output.
|
175
175
|
#
|
176
176
|
# @example Run the map reduce
|
177
177
|
# map_reduce.execute
|
@@ -249,6 +249,10 @@ module Mongoid
|
|
249
249
|
def validate_out!
|
250
250
|
raise Errors::NoMapReduceOutput.new({}) unless @map_reduce.out
|
251
251
|
end
|
252
|
+
|
253
|
+
def _session
|
254
|
+
criteria.send(:_session)
|
255
|
+
end
|
252
256
|
end
|
253
257
|
end
|
254
258
|
end
|
@@ -48,7 +48,8 @@ module Mongoid
|
|
48
48
|
end
|
49
49
|
unless removed.empty?
|
50
50
|
collection.find(selector).update_one(
|
51
|
-
positionally(selector, "$pullAll" => { path => removed })
|
51
|
+
positionally(selector, "$pullAll" => { path => removed }),
|
52
|
+
session: _session
|
52
53
|
)
|
53
54
|
end
|
54
55
|
deleted
|
@@ -303,7 +304,7 @@ module Mongoid
|
|
303
304
|
updates["$set"].merge!(doc.atomic_updates["$set"] || {})
|
304
305
|
doc.move_changes
|
305
306
|
end
|
306
|
-
collection.find(selector).update_one(updates) unless updates["$set"].empty?
|
307
|
+
collection.find(selector).update_one(updates, session: _session) unless updates["$set"].empty?
|
307
308
|
end
|
308
309
|
|
309
310
|
# Get the limiting value.
|
@@ -444,6 +445,10 @@ module Mongoid
|
|
444
445
|
doc._parent.remove_child(doc)
|
445
446
|
doc.destroyed = true
|
446
447
|
end
|
448
|
+
|
449
|
+
def _session
|
450
|
+
@criteria.send(:_session)
|
451
|
+
end
|
447
452
|
end
|
448
453
|
end
|
449
454
|
end
|
@@ -95,7 +95,8 @@ module Mongoid
|
|
95
95
|
def destroy
|
96
96
|
each.inject(0) do |count, doc|
|
97
97
|
doc.destroy
|
98
|
-
count += 1
|
98
|
+
count += 1 if acknowledged_write?
|
99
|
+
count
|
99
100
|
end
|
100
101
|
end
|
101
102
|
alias :destroy_all :destroy
|
@@ -340,7 +341,7 @@ module Mongoid
|
|
340
341
|
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
341
342
|
@collection = @klass.collection
|
342
343
|
criteria.send(:merge_type_selection)
|
343
|
-
@view = collection.find(criteria.selector)
|
344
|
+
@view = collection.find(criteria.selector, session: _session)
|
344
345
|
apply_options
|
345
346
|
end
|
346
347
|
|
@@ -704,6 +705,14 @@ module Mongoid
|
|
704
705
|
yield(doc)
|
705
706
|
documents.push(doc) if cacheable?
|
706
707
|
end
|
708
|
+
|
709
|
+
def _session
|
710
|
+
@criteria.send(:_session)
|
711
|
+
end
|
712
|
+
|
713
|
+
def acknowledged_write?
|
714
|
+
collection.write_concern.nil? || collection.write_concern.acknowledged?
|
715
|
+
end
|
707
716
|
end
|
708
717
|
end
|
709
718
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -3,6 +3,10 @@ module Mongoid
|
|
3
3
|
class Criteria
|
4
4
|
module Modifiable
|
5
5
|
|
6
|
+
# @attribute [r] create_attrs Additional attributes to add to the Document upon creation.
|
7
|
+
# @api private
|
8
|
+
attr_reader :create_attrs
|
9
|
+
|
6
10
|
# Build a document given the selector and return it.
|
7
11
|
# Complex criteria, such as $in and $or operations will get ignored.
|
8
12
|
#
|
@@ -57,6 +61,9 @@ module Mongoid
|
|
57
61
|
|
58
62
|
# Define attributes with which new documents will be created.
|
59
63
|
#
|
64
|
+
# Note that if `find_or_create_by` is called after this in a method chain, the attributes in
|
65
|
+
# the query will override those from this method.
|
66
|
+
#
|
60
67
|
# @example Define attributes to be used when a new document is created.
|
61
68
|
# Person.create_with(job: 'Engineer').find_or_create_by(employer: 'MongoDB')
|
62
69
|
#
|
@@ -64,7 +71,9 @@ module Mongoid
|
|
64
71
|
#
|
65
72
|
# @since 5.1.0
|
66
73
|
def create_with(attrs = {})
|
67
|
-
|
74
|
+
tap do
|
75
|
+
(@create_attrs ||= {}).merge!(attrs)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
|
70
79
|
# Find the first +Document+ given the conditions, or creates a new document
|
@@ -172,7 +181,8 @@ module Mongoid
|
|
172
181
|
#
|
173
182
|
# @since 3.0.0
|
174
183
|
def create_document(method, attrs = nil, &block)
|
175
|
-
|
184
|
+
attrs = (create_attrs || {}).merge(attrs || {})
|
185
|
+
attributes = selector.reduce(attrs) do |hash, (key, value)|
|
176
186
|
unless invalid_key?(hash, key) || invalid_embedded_doc?(value)
|
177
187
|
hash[key] = value
|
178
188
|
end
|
@@ -259,7 +259,9 @@ module Mongoid
|
|
259
259
|
def prepare(field, operator, value)
|
260
260
|
unless operator =~ /exists|type|size/
|
261
261
|
value = value.__expand_complex__
|
262
|
-
|
262
|
+
field = field.to_s
|
263
|
+
name = aliases[field] || field
|
264
|
+
serializer = serializers[name]
|
263
265
|
value = serializer ? serializer.evolve(value) : value
|
264
266
|
end
|
265
267
|
selection = { operator => value }
|
@@ -24,7 +24,7 @@ module Mongoid
|
|
24
24
|
# @since 2.0.0
|
25
25
|
POLYGON = "Polygon"
|
26
26
|
|
27
|
-
# @attribute [rw] negating If the next
|
27
|
+
# @attribute [rw] negating If the next expression is negated.
|
28
28
|
# @attribute [rw] selector The query selector.
|
29
29
|
attr_accessor :negating, :selector
|
30
30
|
|
@@ -134,13 +134,21 @@ module Mongoid
|
|
134
134
|
::Boolean.evolve(value)
|
135
135
|
end
|
136
136
|
|
137
|
-
# Add a $geoIntersects or $geoWithin selection. Symbol operators must
|
138
|
-
# the examples to expand the criteria.
|
137
|
+
# Add a $geoIntersects or $geoWithin selection. Symbol operators must
|
138
|
+
# be used as shown in the examples to expand the criteria.
|
139
139
|
#
|
140
140
|
# @note The only valid geometry shapes for a $geoIntersects are:
|
141
141
|
# :intersects_line, :intersects_point, and :intersects_polygon.
|
142
142
|
#
|
143
|
-
# @note The only valid
|
143
|
+
# @note The only valid options for a $geoWithin query are the geometry
|
144
|
+
# shape :within_polygon and the operator :within_box.
|
145
|
+
#
|
146
|
+
# @note The :within_box operator for the $geoWithin query expects the
|
147
|
+
# lower left (south west) coordinate pair as the first argument and
|
148
|
+
# the upper right (north east) as the second argument.
|
149
|
+
# Important: When latitude and longitude are passed, longitude is
|
150
|
+
# expected as the first element of the coordinate pair.
|
151
|
+
# Source: https://docs.mongodb.com/manual/reference/operator/query/box/
|
144
152
|
#
|
145
153
|
# @example Add a geo intersect criterion for a line.
|
146
154
|
# query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
|
@@ -154,6 +162,9 @@ module Mongoid
|
|
154
162
|
# @example Add a geo within criterion for a polygon.
|
155
163
|
# query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
|
156
164
|
#
|
165
|
+
# @example Add a geo within criterion for a box.
|
166
|
+
# query.geo_spacial(:location.within_box => [[ 1, 10 ], [ 2, 10 ])
|
167
|
+
#
|
157
168
|
# @param [ Hash ] criterion The criterion.
|
158
169
|
#
|
159
170
|
# @return [ Selectable ] The cloned selectable.
|
@@ -174,6 +185,7 @@ module Mongoid
|
|
174
185
|
key :within_polygon, :override, "$geoWithin", "$geometry" do |value|
|
175
186
|
{ "type" => POLYGON, "coordinates" => value }
|
176
187
|
end
|
188
|
+
key :within_box, :override, "$geoWithin", "$box"
|
177
189
|
|
178
190
|
# Add the $gt criterion to the selector.
|
179
191
|
#
|
@@ -501,6 +513,11 @@ module Mongoid
|
|
501
513
|
# @example Construct a text search selector with options.
|
502
514
|
# selectable.text_search("testing", :$language => "fr")
|
503
515
|
#
|
516
|
+
# @note Per https://docs.mongodb.com/manual/reference/operator/query/text/
|
517
|
+
# it is not currently possible to supply multiple text search
|
518
|
+
# conditions in a query. Mongoid will build such a query but the
|
519
|
+
# server will return an error when trying to execute it.
|
520
|
+
#
|
504
521
|
# @param [ String, Symbol ] terms A string of terms that MongoDB parses
|
505
522
|
# and uses to query the text index.
|
506
523
|
# @param [ Hash ] opts Text search options. See MongoDB documentation
|
@@ -512,9 +529,19 @@ module Mongoid
|
|
512
529
|
def text_search(terms, opts = nil)
|
513
530
|
clone.tap do |query|
|
514
531
|
if terms
|
515
|
-
criterion = {
|
516
|
-
criterion[
|
517
|
-
query.selector
|
532
|
+
criterion = {'$text' => { '$search' => terms }}
|
533
|
+
criterion['$text'].merge!(opts) if opts
|
534
|
+
if query.selector['$text']
|
535
|
+
# Per https://docs.mongodb.com/manual/reference/operator/query/text/
|
536
|
+
# multiple $text expressions are not currently supported by
|
537
|
+
# MongoDB server, but build the query correctly instead of
|
538
|
+
# overwriting previous text search condition with the currently
|
539
|
+
# given one.
|
540
|
+
Mongoid.logger.warn('Multiple $text expressions per query are not currently supported by the server')
|
541
|
+
query.selector = {'$and' => [query.selector]}.merge(criterion)
|
542
|
+
else
|
543
|
+
query.selector = query.selector.merge(criterion)
|
544
|
+
end
|
518
545
|
end
|
519
546
|
end
|
520
547
|
end
|