mongo 2.16.0 → 2.17.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +1 -1
- data/lib/mongo/auth/aws/request.rb +0 -1
- data/lib/mongo/client.rb +4 -0
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +26 -14
- data/lib/mongo/collection/view/aggregation.rb +62 -17
- data/lib/mongo/collection/view/builder/aggregation.rb +11 -13
- data/lib/mongo/collection/view/builder/map_reduce.rb +8 -5
- data/lib/mongo/collection/view/change_stream.rb +7 -3
- data/lib/mongo/collection/view/iterable.rb +2 -3
- data/lib/mongo/collection/view/map_reduce.rb +16 -1
- data/lib/mongo/collection/view/readable.rb +24 -1
- data/lib/mongo/collection/view/writable.rb +23 -0
- data/lib/mongo/collection.rb +21 -1
- data/lib/mongo/cursor/kill_spec.rb +19 -2
- data/lib/mongo/cursor.rb +5 -5
- data/lib/mongo/database/view.rb +4 -2
- data/lib/mongo/database.rb +6 -6
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/find/builder/command.rb +1 -0
- data/lib/mongo/operation/result.rb +6 -0
- data/lib/mongo/operation/shared/executable.rb +4 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +18 -2
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/server/description/features.rb +3 -1
- data/lib/mongo/server/push_monitor.rb +4 -1
- data/lib/mongo/server_selector/base.rb +26 -4
- data/lib/mongo/session.rb +19 -0
- data/lib/mongo/socket/ocsp_cache.rb +2 -3
- data/lib/mongo/socket.rb +1 -5
- data/lib/mongo/utils.rb +0 -6
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/read_preference_spec.rb +16 -12
- data/spec/lite_spec_helper.rb +7 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +22 -15
- data/spec/mongo/collection/view/aggregation_spec.rb +71 -95
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +30 -1
- data/spec/mongo/cursor_spec.rb +3 -2
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +24 -1
- data/spec/mongo/server/monitor/connection_spec.rb +22 -0
- data/spec/mongo/server/push_monitor_spec.rb +101 -0
- data/spec/mongo/server_selector_spec.rb +136 -15
- data/spec/mongo/socket/ssl_spec.rb +26 -58
- data/spec/mongo/utils_spec.rb +0 -14
- data/spec/runners/auth.rb +1 -1
- data/spec/runners/change_streams/spec.rb +1 -1
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +1 -1
- data/spec/runners/connection_string.rb +1 -1
- data/spec/runners/crud/spec.rb +1 -3
- data/spec/runners/crud/verifier.rb +1 -2
- data/spec/runners/gridfs.rb +1 -1
- data/spec/runners/read_write_concern_document.rb +1 -1
- data/spec/runners/sdam.rb +1 -1
- data/spec/runners/server_selection.rb +1 -1
- data/spec/runners/server_selection_rtt.rb +1 -1
- data/spec/runners/unified/assertions.rb +3 -1
- data/spec/runners/unified/crud_operations.rb +77 -23
- data/spec/runners/unified/ddl_operations.rb +29 -1
- data/spec/runners/unified/entity_map.rb +3 -3
- data/spec/runners/unified/support_operations.rb +6 -1
- data/spec/runners/unified/test.rb +15 -3
- data/spec/runners/unified/test_group.rb +1 -1
- data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
- data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
- data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
- data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
- data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
- data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
- data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
- data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
- data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
- data/spec/spec_tests/seed_list_discovery_spec.rb +1 -1
- data/spec/spec_tests/sessions_unified_spec.rb +13 -0
- data/spec/support/utils.rb +31 -0
- data.tar.gz.sig +0 -0
- metadata +1127 -1090
- metadata.gz.sig +1 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a38f748fe8350d12ecfd23a30e794b65addcfbf8f5303504f5f85999e2c2b0d
|
4
|
+
data.tar.gz: 876f431a9bfc558ecad0006a32b6ed90b6a94d05ac553a52fbc8b5d3b2b80a55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 256181a9c42fee1b029c899ab56a1a1f5b5283d4071913fc5777ad185f5349a00dc1fa36ac60b9b203a15f1d0857511c551f417f78864a04899e973e8da14b96
|
7
|
+
data.tar.gz: 1272cc35779781fe390276007c831e653b64087e1f34b0459e12d8dfea7099dd39be4e06cef347e36fa7222064ba2f267a5be4a48120d6017f4424876123195b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -153,7 +153,6 @@ module Mongo
|
|
153
153
|
'x-mongodb-gs2-cb-flag' => 'n',
|
154
154
|
'x-mongodb-server-nonce' => Base64.encode64(server_nonce).gsub("\n", ''),
|
155
155
|
}
|
156
|
-
# Hash#compact is available as of Ruby 2.4
|
157
156
|
if session_token
|
158
157
|
headers['x-amz-security-token'] = session_token
|
159
158
|
end
|
data/lib/mongo/client.rb
CHANGED
@@ -887,6 +887,7 @@ module Mongo
|
|
887
887
|
#
|
888
888
|
# See https://docs.mongodb.com/manual/reference/command/listDatabases/
|
889
889
|
# for more information and usage.
|
890
|
+
# @option opts [ Session ] :session The session to use.
|
890
891
|
#
|
891
892
|
# @return [ Array<String> ] The names of the databases.
|
892
893
|
#
|
@@ -910,6 +911,7 @@ module Mongo
|
|
910
911
|
#
|
911
912
|
# See https://docs.mongodb.com/manual/reference/command/listDatabases/
|
912
913
|
# for more information and usage.
|
914
|
+
# @option opts [ Session ] :session The session to use.
|
913
915
|
#
|
914
916
|
# @return [ Array<Hash> ] The info for each database.
|
915
917
|
#
|
@@ -930,6 +932,8 @@ module Mongo
|
|
930
932
|
# @param [ Hash ] filter The filter criteria for getting a list of databases.
|
931
933
|
# @param [ Hash ] opts The command options.
|
932
934
|
#
|
935
|
+
# @option opts [ Session ] :session The session to use.
|
936
|
+
#
|
933
937
|
# @return [ Array<Mongo::Database> ] The list of database objects.
|
934
938
|
#
|
935
939
|
# @since 2.5.0
|
@@ -44,6 +44,7 @@ module Mongo
|
|
44
44
|
@to_kill = {}
|
45
45
|
@active_cursor_ids = Set.new
|
46
46
|
@mutex = Mutex.new
|
47
|
+
@kill_spec_queue = Queue.new
|
47
48
|
end
|
48
49
|
|
49
50
|
attr_reader :cluster
|
@@ -51,17 +52,10 @@ module Mongo
|
|
51
52
|
# Schedule a kill cursors operation to be eventually executed.
|
52
53
|
#
|
53
54
|
# @param [ Cursor::KillSpec ] kill_spec The kill specification.
|
54
|
-
# @param [ Mongo::Server ] server The server to send the kill cursors
|
55
|
-
# operation to.
|
56
55
|
#
|
57
56
|
# @api private
|
58
|
-
def schedule_kill_cursor(kill_spec
|
59
|
-
@
|
60
|
-
if @active_cursor_ids.include?(kill_spec.cursor_id)
|
61
|
-
@to_kill[server.address.seed] ||= Set.new
|
62
|
-
@to_kill[server.address.seed] << kill_spec
|
63
|
-
end
|
64
|
-
end
|
57
|
+
def schedule_kill_cursor(kill_spec)
|
58
|
+
@kill_spec_queue << kill_spec
|
65
59
|
end
|
66
60
|
|
67
61
|
# Register a cursor id as active.
|
@@ -110,6 +104,24 @@ module Mongo
|
|
110
104
|
end
|
111
105
|
end
|
112
106
|
|
107
|
+
# Read and decode scheduled kill cursors operations.
|
108
|
+
#
|
109
|
+
# This method mutates instance variables without locking, so is is not
|
110
|
+
# thread safe. Generally, it should not be called itself, this is a helper
|
111
|
+
# for `kill_cursor` method.
|
112
|
+
#
|
113
|
+
# @api private
|
114
|
+
def read_scheduled_kill_specs
|
115
|
+
while kill_spec = @kill_spec_queue.pop(true)
|
116
|
+
if @active_cursor_ids.include?(kill_spec.cursor_id)
|
117
|
+
@to_kill[kill_spec.server_address] ||= Set.new
|
118
|
+
@to_kill[kill_spec.server_address] << kill_spec
|
119
|
+
end
|
120
|
+
end
|
121
|
+
rescue ThreadError
|
122
|
+
# Empty queue, nothing to do.
|
123
|
+
end
|
124
|
+
|
113
125
|
# Execute all pending kill cursors operations.
|
114
126
|
#
|
115
127
|
# @example Execute pending kill cursors operations.
|
@@ -122,14 +134,14 @@ module Mongo
|
|
122
134
|
# TODO optimize this to batch kill cursor operations for the same
|
123
135
|
# server/database/collection instead of killing each cursor
|
124
136
|
# individually.
|
125
|
-
|
126
137
|
loop do
|
127
|
-
|
138
|
+
server_address = nil
|
128
139
|
|
129
140
|
kill_spec = @mutex.synchronize do
|
141
|
+
read_scheduled_kill_specs
|
130
142
|
# Find a server that has any cursors scheduled for destruction.
|
131
|
-
|
132
|
-
@to_kill.detect { |
|
143
|
+
server_address, specs =
|
144
|
+
@to_kill.detect { |_, specs| specs.any? }
|
133
145
|
|
134
146
|
if specs.nil?
|
135
147
|
# All servers have empty specs, nothing to do.
|
@@ -168,7 +180,7 @@ module Mongo
|
|
168
180
|
op = Operation::KillCursors.new(spec)
|
169
181
|
|
170
182
|
server = cluster.servers.detect do |server|
|
171
|
-
server.address
|
183
|
+
server.address == server_address
|
172
184
|
end
|
173
185
|
|
174
186
|
unless server
|
@@ -73,6 +73,25 @@ module Mongo
|
|
73
73
|
# @param [ Array<Hash> ] pipeline The pipeline of operations.
|
74
74
|
# @param [ Hash ] options The aggregation options.
|
75
75
|
#
|
76
|
+
# @option options [ true, false ] :allow_disk_use Set to true if disk
|
77
|
+
# usage is allowed during the aggregation.
|
78
|
+
# @option options [ Integer ] :batch_size The number of documents to return
|
79
|
+
# per batch.
|
80
|
+
# @option options [ true, false ] :bypass_document_validation Whether or
|
81
|
+
# not to skip document level validation.
|
82
|
+
# @option options [ Hash ] :collation The collation to use.
|
83
|
+
# @option options [ String ] :comment Associate a comment with the aggregation.
|
84
|
+
# @option options [ String ] :hint The index to use for the aggregation.
|
85
|
+
# @option options [ Hash ] :let Mapping of variables to use in the pipeline.
|
86
|
+
# See the server documentation for details.
|
87
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
88
|
+
# milliseconds to allow the aggregation to run.
|
89
|
+
# @option options [ true, false ] :use_cursor Indicates whether the command
|
90
|
+
# will request that the server provide results using a cursor. Note that
|
91
|
+
# as of server version 3.6, aggregations always provide results using a
|
92
|
+
# cursor and this option is therefore not valid.
|
93
|
+
# @option options [ Session ] :session The session to use.
|
94
|
+
#
|
76
95
|
# @since 2.0.0
|
77
96
|
def initialize(view, pipeline, options = {})
|
78
97
|
@view = view
|
@@ -108,37 +127,63 @@ module Mongo
|
|
108
127
|
@view.send(:server_selector)
|
109
128
|
end
|
110
129
|
|
111
|
-
def aggregate_spec(session)
|
112
|
-
Builder::Aggregation.new(
|
130
|
+
def aggregate_spec(server, session, read_preference)
|
131
|
+
Builder::Aggregation.new(
|
132
|
+
pipeline,
|
133
|
+
view,
|
134
|
+
options.merge(session: session, read_preference: read_preference)
|
135
|
+
).specification
|
113
136
|
end
|
114
137
|
|
115
138
|
def new(options)
|
116
139
|
Aggregation.new(view, pipeline, options)
|
117
140
|
end
|
118
141
|
|
119
|
-
def initial_query_op(session)
|
120
|
-
Operation::Aggregate.new(aggregate_spec(session))
|
142
|
+
def initial_query_op(server, session, read_preference)
|
143
|
+
Operation::Aggregate.new(aggregate_spec(server, session, read_preference))
|
121
144
|
end
|
122
145
|
|
123
|
-
|
124
|
-
|
125
|
-
|
146
|
+
# Return effective read preference for the operation.
|
147
|
+
#
|
148
|
+
# If the pipeline contains $merge or $out, and read preference specified
|
149
|
+
# by user is secondary or secondary_preferred, and selected server is below
|
150
|
+
# 5.0, than this method returns primary read preference, because the
|
151
|
+
# aggregation will be routed to primary. Otherwise return the original
|
152
|
+
# read preference.
|
153
|
+
#
|
154
|
+
# See https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#read-preferences-and-server-selection
|
155
|
+
#
|
156
|
+
# @param [ Server ] server The server on which the operation
|
157
|
+
# should be executed.
|
158
|
+
# @return [ Hash | nil ] read preference hash that should be sent with
|
159
|
+
# this command.
|
160
|
+
def effective_read_preference(server)
|
161
|
+
return unless view.read_preference
|
162
|
+
return view.read_preference unless write?
|
163
|
+
return view.read_preference unless [:secondary, :secondary_preferred].include?(view.read_preference[:mode])
|
164
|
+
|
165
|
+
primary_read_preference = {mode: :primary}
|
166
|
+
if server.primary?
|
167
|
+
log_warn("Routing the Aggregation operation to the primary server")
|
168
|
+
primary_read_preference
|
169
|
+
elsif server.mongos? && !server.features.merge_out_on_secondary_enabled?
|
170
|
+
log_warn("Routing the Aggregation operation to the primary server")
|
171
|
+
primary_read_preference
|
126
172
|
else
|
127
|
-
|
128
|
-
description.standalone? || description.mongos? || description.primary? || description.load_balancer?
|
173
|
+
view.read_preference
|
129
174
|
end
|
130
|
-
end
|
131
175
|
|
132
|
-
def secondary_ok?
|
133
|
-
!write?
|
134
176
|
end
|
135
177
|
|
136
178
|
def send_initial_query(server, session)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
179
|
+
initial_query_op(
|
180
|
+
server,
|
181
|
+
session,
|
182
|
+
effective_read_preference(server)
|
183
|
+
).execute(
|
184
|
+
server,
|
185
|
+
context: Operation::Context.new(client: client, session: session)
|
186
|
+
)
|
142
187
|
end
|
143
188
|
|
144
189
|
# Skip, sort, limit, projection are specified as pipeline stages
|
@@ -30,16 +30,17 @@ module Mongo
|
|
30
30
|
#
|
31
31
|
# @since 2.2.0
|
32
32
|
MAPPINGS = BSON::Document.new(
|
33
|
-
:
|
34
|
-
:
|
33
|
+
allow_disk_use: 'allowDiskUse',
|
34
|
+
bypass_document_validation: 'bypassDocumentValidation',
|
35
|
+
explain: 'explain',
|
36
|
+
collation: 'collation',
|
37
|
+
comment: 'comment',
|
38
|
+
hint: 'hint',
|
39
|
+
let: 'let',
|
35
40
|
# This is intentional; max_await_time_ms is an alias for maxTimeMS
|
36
41
|
# used on getMore commands for change streams.
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:bypass_document_validation => 'bypassDocumentValidation',
|
40
|
-
:collation => 'collation',
|
41
|
-
:hint => 'hint',
|
42
|
-
:comment => 'comment'
|
42
|
+
max_await_time_ms: 'maxTimeMS',
|
43
|
+
max_time_ms: 'maxTimeMS',
|
43
44
|
).freeze
|
44
45
|
|
45
46
|
def_delegators :@view, :collection, :database, :read, :write_concern
|
@@ -55,12 +56,9 @@ module Mongo
|
|
55
56
|
|
56
57
|
# Initialize the builder.
|
57
58
|
#
|
58
|
-
# @example Initialize the builder.
|
59
|
-
# Aggregation.new(map, reduce, view, options)
|
60
|
-
#
|
61
59
|
# @param [ Array<Hash> ] pipeline The aggregation pipeline.
|
62
60
|
# @param [ Collection::View ] view The collection view.
|
63
|
-
# @param [ Hash ] options The map/reduce options.
|
61
|
+
# @param [ Hash ] options The map/reduce and read preference options.
|
64
62
|
#
|
65
63
|
# @since 2.2.0
|
66
64
|
def initialize(pipeline, view, options)
|
@@ -81,7 +79,7 @@ module Mongo
|
|
81
79
|
spec = {
|
82
80
|
selector: aggregation_command,
|
83
81
|
db_name: database.name,
|
84
|
-
read: view.read_preference,
|
82
|
+
read: @options[:read_preference] || view.read_preference,
|
85
83
|
session: @options[:session],
|
86
84
|
collation: @options[:collation],
|
87
85
|
}
|
@@ -114,12 +114,15 @@ module Mongo
|
|
114
114
|
collection.read_concern)
|
115
115
|
end
|
116
116
|
command.update(view_options)
|
117
|
-
command.update(
|
117
|
+
command.update(options.slice(:collation))
|
118
|
+
|
118
119
|
# Read preference isn't simply passed in the command payload
|
119
|
-
# (it may need to be converted to wire protocol flags)
|
120
|
-
#
|
121
|
-
#
|
122
|
-
|
120
|
+
# (it may need to be converted to wire protocol flags).
|
121
|
+
# Ideally it should be removed here, however due to Mongoid 7
|
122
|
+
# using this method and requiring :read to be returned from it,
|
123
|
+
# we cannot do this just yet - see RUBY-2932.
|
124
|
+
#command.delete(:read)
|
125
|
+
|
123
126
|
command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
|
124
127
|
command
|
125
128
|
end
|
@@ -298,8 +298,8 @@ module Mongo
|
|
298
298
|
[{ '$changeStream' => change_doc }] + @change_stream_filters
|
299
299
|
end
|
300
300
|
|
301
|
-
def aggregate_spec(session)
|
302
|
-
super(session).tap do |spec|
|
301
|
+
def aggregate_spec(server, session, read_preference)
|
302
|
+
super(server, session, read_preference).tap do |spec|
|
303
303
|
spec[:selector][:aggregate] = 1 unless for_collection?
|
304
304
|
end
|
305
305
|
end
|
@@ -349,7 +349,11 @@ module Mongo
|
|
349
349
|
end
|
350
350
|
|
351
351
|
def send_initial_query(server, session)
|
352
|
-
initial_query_op(
|
352
|
+
initial_query_op(server, session, view.read_preference)
|
353
|
+
.execute(
|
354
|
+
server,
|
355
|
+
context: Operation::Context.new(client: client, session: session)
|
356
|
+
)
|
353
357
|
end
|
354
358
|
|
355
359
|
def time_to_bson_timestamp(time)
|
@@ -114,11 +114,9 @@ module Mongo
|
|
114
114
|
|
115
115
|
def select_cursor(session)
|
116
116
|
if respond_to?(:write?, true) && write?
|
117
|
-
server = server_selector.select_server(cluster, nil, session)
|
117
|
+
server = server_selector.select_server(cluster, nil, session, write_aggregation: true)
|
118
118
|
result = send_initial_query(server, session)
|
119
119
|
|
120
|
-
# RUBY-2367: This will be updated to allow the query cache to
|
121
|
-
# cache cursors with multi-batch results.
|
122
120
|
if use_query_cache?
|
123
121
|
CachingCursor.new(view, result, server, session: session)
|
124
122
|
else
|
@@ -161,6 +159,7 @@ module Mongo
|
|
161
159
|
collation: collation,
|
162
160
|
sort: sort,
|
163
161
|
skip: skip,
|
162
|
+
let: options[:let],
|
164
163
|
limit: limit,
|
165
164
|
allow_disk_use: options[:allow_disk_use],
|
166
165
|
read: read,
|
@@ -115,6 +115,8 @@ module Mongo
|
|
115
115
|
@map_function = map.dup.freeze
|
116
116
|
@reduce_function = reduce.dup.freeze
|
117
117
|
@options = BSON::Document.new(options).freeze
|
118
|
+
|
119
|
+
client.log_warn('The map_reduce operation is deprecated, please use the aggregation pipeline instead')
|
118
120
|
end
|
119
121
|
|
120
122
|
# Set or get the jsMode flag for the operation.
|
@@ -248,7 +250,20 @@ module Mongo
|
|
248
250
|
end
|
249
251
|
|
250
252
|
def initial_query_op(session)
|
251
|
-
|
253
|
+
spec = map_reduce_spec(session)
|
254
|
+
# Read preference isn't simply passed in the command payload
|
255
|
+
# (it may need to be converted to wire protocol flags).
|
256
|
+
# Passing it in command payload produces errors on at least
|
257
|
+
# 5.0 mongoses.
|
258
|
+
# In the future map_reduce_command should remove :read
|
259
|
+
# from its return value, however we cannot do this right now
|
260
|
+
# due to Mongoid 7 relying on :read being returned as part of
|
261
|
+
# the command - see RUBY-2932.
|
262
|
+
# Delete :read here for now because it cannot be sent to mongos this way.
|
263
|
+
spec = spec.dup
|
264
|
+
spec[:selector] = spec[:selector].dup
|
265
|
+
spec[:selector].delete(:read)
|
266
|
+
Operation::MapReduce.new(spec)
|
252
267
|
end
|
253
268
|
|
254
269
|
def valid_server?(server)
|
@@ -34,6 +34,25 @@ module Mongo
|
|
34
34
|
# @param [ Array<Hash> ] pipeline The aggregation pipeline.
|
35
35
|
# @param [ Hash ] options The aggregation options.
|
36
36
|
#
|
37
|
+
# @option options [ true, false ] :allow_disk_use Set to true if disk
|
38
|
+
# usage is allowed during the aggregation.
|
39
|
+
# @option options [ Integer ] :batch_size The number of documents to return
|
40
|
+
# per batch.
|
41
|
+
# @option options [ true, false ] :bypass_document_validation Whether or
|
42
|
+
# not to skip document level validation.
|
43
|
+
# @option options [ Hash ] :collation The collation to use.
|
44
|
+
# @option options [ String ] :comment Associate a comment with the aggregation.
|
45
|
+
# @option options [ String ] :hint The index to use for the aggregation.
|
46
|
+
# @option options [ Hash ] :let Mapping of variables to use in the pipeline.
|
47
|
+
# See the server documentation for details.
|
48
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
49
|
+
# milliseconds to allow the aggregation to run.
|
50
|
+
# @option options [ true, false ] :use_cursor Indicates whether the command
|
51
|
+
# will request that the server provide results using a cursor. Note that
|
52
|
+
# as of server version 3.6, aggregations always provide results using a
|
53
|
+
# cursor and this option is therefore not valid.
|
54
|
+
# @option options [ Session ] :session The session to use.
|
55
|
+
#
|
37
56
|
# @return [ Aggregation ] The aggregation object.
|
38
57
|
#
|
39
58
|
# @since 2.0.0
|
@@ -242,7 +261,11 @@ module Mongo
|
|
242
261
|
{'$collStats' => {'count' => {}}},
|
243
262
|
{'$group' => {'_id' => 1, 'n' => {'$sum' => '$count'}}},
|
244
263
|
]
|
245
|
-
spec = Builder::Aggregation.new(
|
264
|
+
spec = Builder::Aggregation.new(
|
265
|
+
pipeline,
|
266
|
+
self,
|
267
|
+
options.merge(session: session)
|
268
|
+
).specification
|
246
269
|
result = Operation::Aggregate.new(spec).execute(server, context: context)
|
247
270
|
result.documents.first.fetch('n')
|
248
271
|
else
|
@@ -48,6 +48,8 @@ module Mongo
|
|
48
48
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
49
49
|
# @option opts [ Hash ] :write_concern The write concern options.
|
50
50
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
51
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
52
|
+
# See the server documentation for details.
|
51
53
|
#
|
52
54
|
# @return [ BSON::Document, nil ] The document, if found.
|
53
55
|
#
|
@@ -75,6 +77,7 @@ module Mongo
|
|
75
77
|
bypassDocumentValidation: opts[:bypass_document_validation],
|
76
78
|
hint: opts[:hint],
|
77
79
|
collation: opts[:collation] || opts['collation'] || collation,
|
80
|
+
let: opts[:let]
|
78
81
|
}.compact
|
79
82
|
|
80
83
|
write_with_retry(session, write_concern) do |server, txn_num|
|
@@ -109,6 +112,8 @@ module Mongo
|
|
109
112
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
110
113
|
# @option opts [ Hash ] :write_concern The write concern options.
|
111
114
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
115
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
116
|
+
# See the server documentation for details.
|
112
117
|
#
|
113
118
|
# @return [ BSON::Document ] The document.
|
114
119
|
#
|
@@ -142,6 +147,8 @@ module Mongo
|
|
142
147
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
143
148
|
# @option opts [ Hash ] :write_concern The write concern options.
|
144
149
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
150
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
151
|
+
# See the server documentation for details.
|
145
152
|
#
|
146
153
|
# @return [ BSON::Document ] The document.
|
147
154
|
#
|
@@ -172,6 +179,7 @@ module Mongo
|
|
172
179
|
bypassDocumentValidation: opts[:bypass_document_validation],
|
173
180
|
hint: opts[:hint],
|
174
181
|
collation: opts[:collation] || opts['collation'] || collation,
|
182
|
+
let: opts[:let],
|
175
183
|
}.compact
|
176
184
|
|
177
185
|
write_with_retry(session, write_concern) do |server, txn_num|
|
@@ -200,6 +208,8 @@ module Mongo
|
|
200
208
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
201
209
|
# @option opts [ Hash ] :write_concern The write concern options.
|
202
210
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
211
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
212
|
+
# See the server documentation for details.
|
203
213
|
#
|
204
214
|
# @return [ Result ] The response from the database.
|
205
215
|
#
|
@@ -232,6 +242,7 @@ module Mongo
|
|
232
242
|
write_concern: write_concern,
|
233
243
|
bypass_document_validation: !!opts[:bypass_document_validation],
|
234
244
|
session: session,
|
245
|
+
let: opts[:let],
|
235
246
|
).execute(server, context: Operation::Context.new(client: client, session: session))
|
236
247
|
end
|
237
248
|
end
|
@@ -250,6 +261,8 @@ module Mongo
|
|
250
261
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
251
262
|
# @option opts [ Hash ] :write_concern The write concern options.
|
252
263
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
264
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
265
|
+
# See the server documentation for details.
|
253
266
|
#
|
254
267
|
# @return [ Result ] The response from the database.
|
255
268
|
#
|
@@ -283,6 +296,7 @@ module Mongo
|
|
283
296
|
bypass_document_validation: !!opts[:bypass_document_validation],
|
284
297
|
session: session,
|
285
298
|
txn_num: txn_num,
|
299
|
+
let: opts[:let],
|
286
300
|
).execute(server, context: Operation::Context.new(client: client, session: session))
|
287
301
|
end
|
288
302
|
end
|
@@ -306,6 +320,8 @@ module Mongo
|
|
306
320
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
307
321
|
# @option opts [ Hash ] :write_concern The write concern options.
|
308
322
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
323
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
324
|
+
# See the server documentation for details.
|
309
325
|
#
|
310
326
|
# @return [ Result ] The response from the database.
|
311
327
|
#
|
@@ -343,6 +359,7 @@ module Mongo
|
|
343
359
|
bypass_document_validation: !!opts[:bypass_document_validation],
|
344
360
|
session: session,
|
345
361
|
txn_num: txn_num,
|
362
|
+
let: opts[:let]
|
346
363
|
).execute(server, context: Operation::Context.new(client: client, session: session))
|
347
364
|
end
|
348
365
|
end
|
@@ -368,6 +385,8 @@ module Mongo
|
|
368
385
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
369
386
|
# @option opts [ Hash ] :write_concern The write concern options.
|
370
387
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
388
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
389
|
+
# See the server documentation for details.
|
371
390
|
#
|
372
391
|
# @return [ Result ] The response from the database.
|
373
392
|
#
|
@@ -405,6 +424,7 @@ module Mongo
|
|
405
424
|
write_concern: write_concern,
|
406
425
|
bypass_document_validation: !!opts[:bypass_document_validation],
|
407
426
|
session: session,
|
427
|
+
let: opts[:let],
|
408
428
|
).execute(server, context: Operation::Context.new(client: client, session: session))
|
409
429
|
end
|
410
430
|
end
|
@@ -430,6 +450,8 @@ module Mongo
|
|
430
450
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
431
451
|
# @option opts [ Hash ] :write_concern The write concern options.
|
432
452
|
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
453
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
454
|
+
# See the server documentation for details.
|
433
455
|
#
|
434
456
|
# @return [ Result ] The response from the database.
|
435
457
|
#
|
@@ -467,6 +489,7 @@ module Mongo
|
|
467
489
|
bypass_document_validation: !!opts[:bypass_document_validation],
|
468
490
|
session: session,
|
469
491
|
txn_num: txn_num,
|
492
|
+
let: opts[:let],
|
470
493
|
).execute(server, context: Operation::Context.new(client: client, session: session))
|
471
494
|
end
|
472
495
|
end
|
data/lib/mongo/collection.rb
CHANGED
@@ -253,7 +253,7 @@ module Mongo
|
|
253
253
|
options = Hash[self.options.reject do |key, value|
|
254
254
|
%w(read read_preference read_concern).include?(key.to_s)
|
255
255
|
end]
|
256
|
-
options.update(
|
256
|
+
options.update(opts.slice(*TIME_SERIES_OPTIONS.keys))
|
257
257
|
# Converting Ruby spelled time series options to server style.
|
258
258
|
TIME_SERIES_OPTIONS.each do |ruby_key, server_key|
|
259
259
|
if options.key?(ruby_key)
|
@@ -361,6 +361,8 @@ module Mongo
|
|
361
361
|
# @option options [ Integer ] :skip The number of docs to skip before returning results.
|
362
362
|
# @option options [ Hash ] :sort The key and direction pairs by which the result set
|
363
363
|
# will be sorted.
|
364
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
365
|
+
# See the server documentation for details.
|
364
366
|
#
|
365
367
|
# @return [ CollectionView ] The collection view.
|
366
368
|
#
|
@@ -386,6 +388,8 @@ module Mongo
|
|
386
388
|
# @option options [ Hash ] :collation The collation to use.
|
387
389
|
# @option options [ String ] :comment Associate a comment with the aggregation.
|
388
390
|
# @option options [ String ] :hint The index to use for the aggregation.
|
391
|
+
# @option options [ Hash ] :let Mapping of variables to use in the pipeline.
|
392
|
+
# See the server documentation for details.
|
389
393
|
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
390
394
|
# milliseconds to allow the aggregation to run.
|
391
395
|
# @option options [ true, false ] :use_cursor Indicates whether the command
|
@@ -666,6 +670,8 @@ module Mongo
|
|
666
670
|
# @option options [ Session ] :session The session to use.
|
667
671
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
668
672
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
673
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
674
|
+
# See the server documentation for details.
|
669
675
|
#
|
670
676
|
# @return [ Result ] The response from the database.
|
671
677
|
#
|
@@ -686,6 +692,8 @@ module Mongo
|
|
686
692
|
# @option options [ Session ] :session The session to use.
|
687
693
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
688
694
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
695
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
696
|
+
# See the server documentation for details.
|
689
697
|
#
|
690
698
|
# @return [ Result ] The response from the database.
|
691
699
|
#
|
@@ -734,6 +742,8 @@ module Mongo
|
|
734
742
|
# @option options [ Session ] :session The session to use.
|
735
743
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
736
744
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
745
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
746
|
+
# See the server documentation for details.
|
737
747
|
#
|
738
748
|
# @return [ Result ] The response from the database.
|
739
749
|
#
|
@@ -761,6 +771,8 @@ module Mongo
|
|
761
771
|
# @option options [ Session ] :session The session to use.
|
762
772
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
763
773
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
774
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
775
|
+
# See the server documentation for details.
|
764
776
|
#
|
765
777
|
# @return [ Result ] The response from the database.
|
766
778
|
#
|
@@ -788,6 +800,8 @@ module Mongo
|
|
788
800
|
# @option options [ Session ] :session The session to use.
|
789
801
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
790
802
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
803
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
804
|
+
# See the server documentation for details.
|
791
805
|
#
|
792
806
|
# @return [ Result ] The response from the database.
|
793
807
|
#
|
@@ -816,6 +830,8 @@ module Mongo
|
|
816
830
|
# @option options [ Session ] :session The session to use.
|
817
831
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
818
832
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
833
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
834
|
+
# See the server documentation for details.
|
819
835
|
#
|
820
836
|
# @return [ BSON::Document, nil ] The document, if found.
|
821
837
|
#
|
@@ -854,6 +870,8 @@ module Mongo
|
|
854
870
|
# @option options [ Session ] :session The session to use.
|
855
871
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
856
872
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
873
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
874
|
+
# See the server documentation for details.
|
857
875
|
#
|
858
876
|
# @return [ BSON::Document ] The document.
|
859
877
|
#
|
@@ -890,6 +908,8 @@ module Mongo
|
|
890
908
|
# @option options [ Session ] :session The session to use.
|
891
909
|
# @option options [ Hash | String ] :hint The index to use for this operation.
|
892
910
|
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
|
911
|
+
# @option options [ Hash ] :let Mapping of variables to use in the command.
|
912
|
+
# See the server documentation for details.
|
893
913
|
#
|
894
914
|
# @return [ BSON::Document ] The document.
|
895
915
|
#
|