mongo 2.0.6 → 2.1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +2 -0
- data/lib/mongo/bulk_write.rb +1 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +87 -31
- data/lib/mongo/bulk_write/deletable.rb +8 -7
- data/lib/mongo/bulk_write/insertable.rb +4 -3
- data/lib/mongo/bulk_write/ordered_bulk_write.rb +6 -6
- data/lib/mongo/bulk_write/replacable.rb +4 -3
- data/lib/mongo/bulk_write/result.rb +138 -0
- data/lib/mongo/bulk_write/unordered_bulk_write.rb +5 -8
- data/lib/mongo/bulk_write/updatable.rb +8 -7
- data/lib/mongo/client.rb +36 -4
- data/lib/mongo/cluster.rb +39 -4
- data/lib/mongo/cluster/topology/replica_set.rb +20 -4
- data/lib/mongo/cluster/topology/sharded.rb +1 -1
- data/lib/mongo/collection.rb +282 -29
- data/lib/mongo/collection/view/aggregation.rb +32 -4
- data/lib/mongo/collection/view/iterable.rb +2 -1
- data/lib/mongo/collection/view/map_reduce.rb +3 -1
- data/lib/mongo/collection/view/readable.rb +89 -14
- data/lib/mongo/collection/view/writable.rb +11 -5
- data/lib/mongo/cursor.rb +11 -3
- data/lib/mongo/dbref.rb +113 -0
- data/lib/mongo/error.rb +6 -2
- data/lib/mongo/error/parser.rb +1 -1
- data/lib/mongo/event/description_changed.rb +1 -1
- data/lib/mongo/grid/file.rb +1 -1
- data/lib/mongo/grid/fs.rb +2 -5
- data/lib/mongo/monitoring.rb +199 -0
- data/lib/mongo/monitoring/command_log_subscriber.rb +88 -0
- data/lib/mongo/monitoring/event.rb +17 -0
- data/lib/mongo/monitoring/event/command_failed.rb +96 -0
- data/lib/mongo/monitoring/event/command_started.rb +88 -0
- data/lib/mongo/monitoring/event/command_succeeded.rb +96 -0
- data/lib/mongo/monitoring/publishable.rb +96 -0
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/operation/executable.rb +1 -1
- data/lib/mongo/operation/parallel_scan.rb +76 -0
- data/lib/mongo/operation/parallel_scan/result.rb +72 -0
- data/lib/mongo/operation/specifiable.rb +18 -0
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +2 -2
- data/lib/mongo/operation/write/bulk/bulk_update.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +13 -1
- data/lib/mongo/protocol/delete.rb +8 -13
- data/lib/mongo/protocol/get_more.rb +13 -13
- data/lib/mongo/protocol/insert.rb +8 -13
- data/lib/mongo/protocol/kill_cursors.rb +7 -11
- data/lib/mongo/protocol/query.rb +58 -20
- data/lib/mongo/protocol/reply.rb +12 -0
- data/lib/mongo/protocol/update.rb +13 -14
- data/lib/mongo/server.rb +23 -2
- data/lib/mongo/server/connectable.rb +0 -22
- data/lib/mongo/server/connection.rb +29 -0
- data/lib/mongo/server/description.rb +23 -1
- data/lib/mongo/server/monitor.rb +17 -1
- data/lib/mongo/server/monitor/connection.rb +24 -0
- data/lib/mongo/socket/ssl.rb +28 -16
- data/lib/mongo/socket/tcp.rb +1 -1
- data/lib/mongo/socket/unix.rb +1 -1
- data/lib/mongo/uri.rb +12 -5
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/auth/cr_spec.rb +9 -1
- data/spec/mongo/auth/ldap_spec.rb +9 -1
- data/spec/mongo/auth/scram_spec.rb +9 -1
- data/spec/mongo/auth/x509_spec.rb +9 -1
- data/spec/mongo/{bulk/bulk_write_spec.rb → bulk_write_spec.rb} +15 -15
- data/spec/mongo/client_spec.rb +42 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -9
- data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
- data/spec/mongo/cluster/topology/single_spec.rb +12 -4
- data/spec/mongo/cluster_spec.rb +55 -10
- data/spec/mongo/collection/view/aggregation_spec.rb +123 -1
- data/spec/mongo/collection/view/explainable_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
- data/spec/mongo/collection/view/readable_spec.rb +251 -6
- data/spec/mongo/collection/view/writable_spec.rb +4 -4
- data/spec/mongo/collection/view_spec.rb +233 -71
- data/spec/mongo/collection_spec.rb +905 -9
- data/spec/mongo/crud_spec.rb +2 -2
- data/spec/mongo/cursor_spec.rb +3 -3
- data/spec/mongo/dbref_spec.rb +149 -0
- data/spec/mongo/monitoring_spec.rb +168 -0
- data/spec/mongo/operation/map_reduce_spec.rb +1 -1
- data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -1
- data/spec/mongo/operation/write/bulk/bulk_insert_spec.rb +2 -2
- data/spec/mongo/operation/write/bulk/bulk_update_spec.rb +1 -1
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +2 -2
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/query_spec.rb +0 -29
- data/spec/mongo/server/connection_pool_spec.rb +18 -6
- data/spec/mongo/server/connection_spec.rb +12 -4
- data/spec/mongo/server/description_spec.rb +7 -3
- data/spec/mongo/server/monitor_spec.rb +30 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +11 -4
- data/spec/mongo/server_selection_spec.rb +14 -6
- data/spec/mongo/server_spec.rb +27 -8
- data/spec/mongo/socket/ssl_spec.rb +94 -8
- data/spec/mongo/uri_spec.rb +25 -9
- data/spec/spec_helper.rb +29 -20
- data/spec/support/authorization.rb +19 -4
- data/spec/support/certificates/client.pem +4 -4
- data/spec/support/crud/read.rb +9 -10
- data/spec/support/crud/write.rb +24 -20
- data/spec/support/sdam/rs/equal_electionids.yml +45 -0
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +98 -0
- data/spec/support/sdam/rs/null_election_id.yml +144 -0
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
- data/spec/support/server_discovery_and_monitoring.rb +19 -2
- data/spec/support/shared/bulk_write.rb +26 -22
- data/spec/support/shared/server_selector.rb +2 -1
- metadata +31 -7
- metadata.gz.sig +0 -0
- data/lib/mongo/error/invalid_uri_option.rb +0 -38
@@ -13,11 +13,12 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
module Mongo
|
16
|
-
|
17
16
|
module BulkWrite
|
18
17
|
|
18
|
+
# Encapsulates behaviour around an unordered bulk write operation.
|
19
|
+
#
|
20
|
+
# @since 2.0.0
|
19
21
|
class UnorderedBulkWrite
|
20
|
-
|
21
22
|
include BulkWritable
|
22
23
|
|
23
24
|
private
|
@@ -35,12 +36,8 @@ module Mongo
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def finalize
|
38
|
-
@results.
|
39
|
-
if results[:write_errors] || results[:write_concern_errors]
|
40
|
-
raise Error::BulkWriteError.new(results)
|
41
|
-
end
|
42
|
-
end
|
39
|
+
Result.new(@results).validate!
|
43
40
|
end
|
44
41
|
end
|
45
42
|
end
|
46
|
-
end
|
43
|
+
end
|
@@ -46,23 +46,24 @@ module Mongo
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def update(ops, type, server)
|
49
|
+
def update(ops, type, server, operation_id)
|
50
50
|
Operation::Write::BulkUpdate.new(
|
51
51
|
:updates => updates(ops, type),
|
52
52
|
:db_name => database.name,
|
53
53
|
:coll_name => @collection.name,
|
54
54
|
:write_concern => write_concern,
|
55
|
-
:ordered => ordered
|
55
|
+
:ordered => ordered?,
|
56
|
+
:operation_id => operation_id
|
56
57
|
).execute(server.context)
|
57
58
|
end
|
58
59
|
|
59
|
-
def update_one(op, server)
|
60
|
-
update(op[:update_one], __method__, server)
|
60
|
+
def update_one(op, server, operation_id)
|
61
|
+
update(op[:update_one], __method__, server, operation_id)
|
61
62
|
end
|
62
63
|
|
63
|
-
def update_many(op, server)
|
64
|
-
update(op[:update_many], __method__, server)
|
64
|
+
def update_many(op, server, operation_id)
|
65
|
+
update(op[:update_many], __method__, server, operation_id)
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
68
|
-
end
|
69
|
+
end
|
data/lib/mongo/client.rb
CHANGED
@@ -39,6 +39,9 @@ module Mongo
|
|
39
39
|
# Delegate command execution to the current database.
|
40
40
|
def_delegators :@database, :command
|
41
41
|
|
42
|
+
# Delegate subscription to monitoring.
|
43
|
+
def_delegators :@monitoring, :subscribe, :unsubscribe
|
44
|
+
|
42
45
|
# Determine if this client is equivalent to another object.
|
43
46
|
#
|
44
47
|
# @example Check client equality.
|
@@ -143,14 +146,18 @@ module Mongo
|
|
143
146
|
# @option options [ String ] :user The user name.
|
144
147
|
# @option options [ Hash ] :write The write concern options. Can be :w =>
|
145
148
|
# Integer, :fsync => Boolean, :j => Boolean.
|
149
|
+
# @option options [ true, false ] :monitoring Initializes a client without
|
150
|
+
# any default monitoring if false is provided.
|
146
151
|
#
|
147
152
|
# @since 2.0.0
|
148
153
|
def initialize(addresses_or_uri, options = {})
|
154
|
+
@monitoring = Monitoring.new(options)
|
149
155
|
if addresses_or_uri.is_a?(::String)
|
150
156
|
create_from_uri(addresses_or_uri, options)
|
151
157
|
else
|
152
158
|
create_from_addresses(addresses_or_uri, options)
|
153
159
|
end
|
160
|
+
yield(self) if block_given?
|
154
161
|
end
|
155
162
|
|
156
163
|
# Get an inspection of the client as a string.
|
@@ -207,11 +214,12 @@ module Mongo
|
|
207
214
|
# @since 2.0.0
|
208
215
|
def with(new_options = {})
|
209
216
|
clone.tap do |client|
|
210
|
-
|
217
|
+
opts = new_options || {}
|
218
|
+
client.options.update(opts)
|
211
219
|
Database.create(client)
|
212
220
|
# We can't use the same cluster if some options that would affect it
|
213
221
|
# have changed.
|
214
|
-
if cluster_modifying?(
|
222
|
+
if cluster_modifying?(opts)
|
215
223
|
Cluster.create(client)
|
216
224
|
end
|
217
225
|
end
|
@@ -230,6 +238,30 @@ module Mongo
|
|
230
238
|
@write_concern ||= WriteConcern.get(options[:write])
|
231
239
|
end
|
232
240
|
|
241
|
+
# Close all connections.
|
242
|
+
#
|
243
|
+
# @example Disconnect the client.
|
244
|
+
# client.close
|
245
|
+
#
|
246
|
+
# @return [ true ] Always true.
|
247
|
+
#
|
248
|
+
# @since 2.1.0
|
249
|
+
def close
|
250
|
+
@cluster.disconnect! and true
|
251
|
+
end
|
252
|
+
|
253
|
+
# Reconnect the client.
|
254
|
+
#
|
255
|
+
# @example Reconnect the client.
|
256
|
+
# client.reconnect
|
257
|
+
#
|
258
|
+
# @return [ true ] Always true.
|
259
|
+
#
|
260
|
+
# @since 2.1.0
|
261
|
+
def reconnect
|
262
|
+
@cluster.reconnect! and true
|
263
|
+
end
|
264
|
+
|
233
265
|
# Get the names of all databases.
|
234
266
|
#
|
235
267
|
# @example Get the database names.
|
@@ -258,14 +290,14 @@ module Mongo
|
|
258
290
|
|
259
291
|
def create_from_addresses(addresses, opts = {})
|
260
292
|
@options = Database::DEFAULT_OPTIONS.merge(opts).freeze
|
261
|
-
@cluster = Cluster.new(addresses, options)
|
293
|
+
@cluster = Cluster.new(addresses, @monitoring, options)
|
262
294
|
@database = Database.new(self, options[:database], options)
|
263
295
|
end
|
264
296
|
|
265
297
|
def create_from_uri(connection_string, opts = {})
|
266
298
|
uri = URI.new(connection_string)
|
267
299
|
@options = Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts)).freeze
|
268
|
-
@cluster = Cluster.new(uri.servers, options)
|
300
|
+
@cluster = Cluster.new(uri.servers, @monitoring, options)
|
269
301
|
@database = Database.new(self, options[:database], options)
|
270
302
|
end
|
271
303
|
|
data/lib/mongo/cluster.rb
CHANGED
@@ -67,7 +67,7 @@ module Mongo
|
|
67
67
|
if addition_allowed?(address)
|
68
68
|
log_debug([ "Adding #{address.to_s} to the cluster." ])
|
69
69
|
@update_lock.synchronize { @addresses.push(address) }
|
70
|
-
server = Server.new(address, self, event_listeners, options)
|
70
|
+
server = Server.new(address, self, @monitoring, event_listeners, options)
|
71
71
|
@update_lock.synchronize { @servers.push(server) }
|
72
72
|
server
|
73
73
|
end
|
@@ -76,16 +76,22 @@ module Mongo
|
|
76
76
|
|
77
77
|
# Instantiate the new cluster.
|
78
78
|
#
|
79
|
+
# @api private
|
80
|
+
#
|
79
81
|
# @example Instantiate the cluster.
|
80
|
-
# Mongo::Cluster.new(["127.0.0.1:27017"])
|
82
|
+
# Mongo::Cluster.new(["127.0.0.1:27017"], monitoring)
|
83
|
+
#
|
84
|
+
# @note Cluster should never be directly instantiated outside of a Client.
|
81
85
|
#
|
82
86
|
# @param [ Array<String> ] seeds The addresses of the configured servers.
|
87
|
+
# @param [ Monitoring ] monitoring The monitoring.
|
83
88
|
# @param [ Hash ] options The options.
|
84
89
|
#
|
85
90
|
# @since 2.0.0
|
86
|
-
def initialize(seeds, options = {})
|
91
|
+
def initialize(seeds, monitoring, options = {})
|
87
92
|
@addresses = []
|
88
93
|
@servers = []
|
94
|
+
@monitoring = monitoring
|
89
95
|
@event_listeners = Event::Listeners.new
|
90
96
|
@options = options.freeze
|
91
97
|
@topology = Topology.initial(seeds, options)
|
@@ -196,6 +202,31 @@ module Mongo
|
|
196
202
|
topology.servers(servers_list.compact).compact
|
197
203
|
end
|
198
204
|
|
205
|
+
# Disconnect all servers.
|
206
|
+
#
|
207
|
+
# @example Disconnect the cluster's servers.
|
208
|
+
# cluster.disconnect!
|
209
|
+
#
|
210
|
+
# @return [ true ] Always true.
|
211
|
+
#
|
212
|
+
# @since 2.1.0
|
213
|
+
def disconnect!
|
214
|
+
@servers.each { |server| server.disconnect! } and true
|
215
|
+
end
|
216
|
+
|
217
|
+
# Reconnect all servers.
|
218
|
+
#
|
219
|
+
# @example Reconnect the cluster's servers.
|
220
|
+
# cluster.reconnect!
|
221
|
+
#
|
222
|
+
# @return [ true ] Always true.
|
223
|
+
#
|
224
|
+
# @since 2.1.0
|
225
|
+
def reconnect!
|
226
|
+
scan!
|
227
|
+
servers.each { |server| server.reconnect! } and true
|
228
|
+
end
|
229
|
+
|
199
230
|
# Add hosts in a description to the cluster.
|
200
231
|
#
|
201
232
|
# @example Add hosts in a description to the cluster.
|
@@ -240,7 +271,11 @@ module Mongo
|
|
240
271
|
#
|
241
272
|
# @since 2.0.0
|
242
273
|
def self.create(client)
|
243
|
-
cluster = Cluster.new(
|
274
|
+
cluster = Cluster.new(
|
275
|
+
client.cluster.addresses.map(&:to_s),
|
276
|
+
client.instance_variable_get(:@monitoring).dup,
|
277
|
+
client.options
|
278
|
+
)
|
244
279
|
client.instance_variable_set(:@cluster, cluster)
|
245
280
|
end
|
246
281
|
|
@@ -60,11 +60,14 @@ module Mongo
|
|
60
60
|
# @return [ ReplicaSet ] The topology.
|
61
61
|
def elect_primary(description, servers)
|
62
62
|
if description.replica_set_name == replica_set_name
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
server.description.
|
63
|
+
unless detect_stale_primary!(description)
|
64
|
+
log_debug([ "Server #{description.address.to_s} elected as primary in #{replica_set_name}." ])
|
65
|
+
servers.each do |server|
|
66
|
+
if server.primary? && server.address != description.address
|
67
|
+
server.description.unknown!
|
68
|
+
end
|
67
69
|
end
|
70
|
+
update_max_election_id(description)
|
68
71
|
end
|
69
72
|
else
|
70
73
|
log_warn([
|
@@ -84,6 +87,7 @@ module Mongo
|
|
84
87
|
# @since 2.0.0
|
85
88
|
def initialize(options, seeds = [])
|
86
89
|
@options = options
|
90
|
+
@max_election_id = 0
|
87
91
|
end
|
88
92
|
|
89
93
|
# A replica set topology is a replica set.
|
@@ -215,6 +219,18 @@ module Mongo
|
|
215
219
|
|
216
220
|
private
|
217
221
|
|
222
|
+
def update_max_election_id(description)
|
223
|
+
if description.election_id && description.election_id > @max_election_id
|
224
|
+
@max_election_id = description.election_id
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def detect_stale_primary!(description)
|
229
|
+
if description.election_id && description.election_id < @max_election_id
|
230
|
+
description.unknown!
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
218
234
|
def has_primary?(servers)
|
219
235
|
servers.find { |s| s.primary? }
|
220
236
|
end
|
data/lib/mongo/collection.rb
CHANGED
@@ -57,6 +57,23 @@ module Mongo
|
|
57
57
|
name == other.name && database == other.database && options == other.options
|
58
58
|
end
|
59
59
|
|
60
|
+
# Instantiate a new collection.
|
61
|
+
#
|
62
|
+
# @example Instantiate a new collection.
|
63
|
+
# Mongo::Collection.new(database, 'test')
|
64
|
+
#
|
65
|
+
# @param [ Mongo::Database ] database The collection's database.
|
66
|
+
# @param [ String, Symbol ] name The collection name.
|
67
|
+
# @param [ Hash ] options The collection options.
|
68
|
+
#
|
69
|
+
# @since 2.0.0
|
70
|
+
def initialize(database, name, options = {})
|
71
|
+
raise Error::InvalidCollectionName.new unless name
|
72
|
+
@database = database
|
73
|
+
@name = name.to_s.freeze
|
74
|
+
@options = options.freeze
|
75
|
+
end
|
76
|
+
|
60
77
|
# Is the collection capped?
|
61
78
|
#
|
62
79
|
# @example Is the collection capped?
|
@@ -108,12 +125,96 @@ module Mongo
|
|
108
125
|
# collection.find
|
109
126
|
#
|
110
127
|
# @param [ Hash ] filter The filter to use in the find.
|
128
|
+
# @param [ Hash ] options The options for the find.
|
129
|
+
#
|
130
|
+
# @option options [ true, false ] :allow_partial_results Allows the query to get partial
|
131
|
+
# results if some shards are down.
|
132
|
+
# @option options [ Integer ] :batch_size The number of documents returned in each batch
|
133
|
+
# of results from MongoDB.
|
134
|
+
# @option options [ String ] :comment Associate a comment with the query.
|
135
|
+
# @option options [ :tailable, :tailable_await ] :cursor_type The type of cursor to use.
|
136
|
+
# @option options [ Integer ] :limit The max number of docs to return from the query.
|
137
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the query
|
138
|
+
# to run in milliseconds.
|
139
|
+
# @option options [ Hash ] :modifiers A document containing meta-operators modifying the
|
140
|
+
# output or behavior of a query.
|
141
|
+
# @option options [ true, false ] :no_cursor_timeout The server normally times out idle
|
142
|
+
# cursors after an inactivity period (10 minutes) to prevent excess memory use.
|
143
|
+
# Set this option to prevent that.
|
144
|
+
# @option options [ true, false ] :oplog_replay Internal replication use only - driver
|
145
|
+
# should not set.
|
146
|
+
# @option options [ Hash ] :projection The fields to include or exclude from each doc
|
147
|
+
# in the result set.
|
148
|
+
# @option options [ Integer ] :skip The number of docs to skip before returning results.
|
149
|
+
# @option options [ Hash ] :sort The key and direction pairs by which the result set
|
150
|
+
# will be sorted.
|
111
151
|
#
|
112
152
|
# @return [ CollectionView ] The collection view.
|
113
153
|
#
|
114
154
|
# @since 2.0.0
|
115
|
-
def find(filter = nil)
|
116
|
-
View.new(self, filter || {})
|
155
|
+
def find(filter = nil, options = {})
|
156
|
+
View.new(self, filter || {}, options)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Perform an aggregation on the collection.
|
160
|
+
#
|
161
|
+
# @example Perform an aggregation.
|
162
|
+
# collection.aggregate([ { "$group" => { "_id" => "$city", "tpop" => { "$sum" => "$pop" }}} ])
|
163
|
+
#
|
164
|
+
# @param [ Array<Hash> ] pipeline The aggregation pipeline.
|
165
|
+
# @param [ Hash ] options The aggregation options.
|
166
|
+
#
|
167
|
+
# @option options [ true, false ] :allow_disk_use Set to true if disk usage is allowed during
|
168
|
+
# the aggregation.
|
169
|
+
# @option options [ Integer ] :batch_size The number of documents to return per batch.
|
170
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time in milliseconds to allow the
|
171
|
+
# aggregation to run.
|
172
|
+
# @option options [ true, false ] :use_cursor Indicates whether the command will request that the server
|
173
|
+
# provide results using a cursor.
|
174
|
+
#
|
175
|
+
# @return [ Aggregation ] The aggregation object.
|
176
|
+
#
|
177
|
+
# @since 2.1.0
|
178
|
+
def aggregate(pipeline, options = {})
|
179
|
+
View.new(self, {}).aggregate(pipeline, options)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Get a count of matching documents in the collection.
|
183
|
+
#
|
184
|
+
# @example Get the count.
|
185
|
+
# collection.count(name: 1)
|
186
|
+
#
|
187
|
+
# @param [ Hash ] filter A filter for matching documents.
|
188
|
+
# @param [ Hash ] options The count options.
|
189
|
+
#
|
190
|
+
# @option options [ Hash ] :hint The index to use.
|
191
|
+
# @option options [ Integer ] :limit The maximum number of documents to count.
|
192
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command to run.
|
193
|
+
# @option options [ Integer ] :skip The number of documents to skip before counting.
|
194
|
+
#
|
195
|
+
# @return [ Integer ] The document count.
|
196
|
+
#
|
197
|
+
# @since 2.1.0
|
198
|
+
def count(filter = nil, options = {})
|
199
|
+
View.new(self, filter || {}).count(options)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Get a list of distinct values for a specific field.
|
203
|
+
#
|
204
|
+
# @example Get the distinct values.
|
205
|
+
# collection.distinct('name')
|
206
|
+
#
|
207
|
+
# @param [ Symbol, String ] field_name The name of the field.
|
208
|
+
# @param [ Hash ] filter The documents from which to retrieve the distinct values.
|
209
|
+
# @param [ Hash ] options The distinct command options.
|
210
|
+
#
|
211
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command to run.
|
212
|
+
#
|
213
|
+
# @return [ Array<Object> ] The list of distinct values.
|
214
|
+
#
|
215
|
+
# @since 2.1.0
|
216
|
+
def distinct(field_name, filter = nil, options = {})
|
217
|
+
View.new(self, filter || {}).distinct(field_name, options)
|
117
218
|
end
|
118
219
|
|
119
220
|
# Get a view of all indexes for this collection. Can be iterated or has
|
@@ -131,23 +232,6 @@ module Mongo
|
|
131
232
|
Index::View.new(self, options)
|
132
233
|
end
|
133
234
|
|
134
|
-
# Instantiate a new collection.
|
135
|
-
#
|
136
|
-
# @example Instantiate a new collection.
|
137
|
-
# Mongo::Collection.new(database, 'test')
|
138
|
-
#
|
139
|
-
# @param [ Mongo::Database ] database The collection's database.
|
140
|
-
# @param [ String, Symbol ] name The collection name.
|
141
|
-
# @param [ Hash ] options The collection options.
|
142
|
-
#
|
143
|
-
# @since 2.0.0
|
144
|
-
def initialize(database, name, options = {})
|
145
|
-
raise Error::InvalidCollectionName.new unless name
|
146
|
-
@database = database
|
147
|
-
@name = name.to_s.freeze
|
148
|
-
@options = options.freeze
|
149
|
-
end
|
150
|
-
|
151
235
|
# Get a pretty printed string inspection for the collection.
|
152
236
|
#
|
153
237
|
# @example Inspect the collection.
|
@@ -172,7 +256,13 @@ module Mongo
|
|
172
256
|
#
|
173
257
|
# @since 2.0.0
|
174
258
|
def insert_one(document, options = {})
|
175
|
-
|
259
|
+
Operation::Write::Insert.new(
|
260
|
+
:documents => [ document ],
|
261
|
+
:db_name => database.name,
|
262
|
+
:coll_name => name,
|
263
|
+
:write_concern => write_concern,
|
264
|
+
:options => options
|
265
|
+
).execute(next_primary.context)
|
176
266
|
end
|
177
267
|
|
178
268
|
# Insert the provided documents into the collection.
|
@@ -187,13 +277,8 @@ module Mongo
|
|
187
277
|
#
|
188
278
|
# @since 2.0.0
|
189
279
|
def insert_many(documents, options = {})
|
190
|
-
|
191
|
-
|
192
|
-
:db_name => database.name,
|
193
|
-
:coll_name => name,
|
194
|
-
:write_concern => write_concern,
|
195
|
-
:options => options
|
196
|
-
).execute(next_primary.context)
|
280
|
+
inserts = documents.map{ |doc| { :insert_one => doc }}
|
281
|
+
bulk_write(inserts, options)
|
197
282
|
end
|
198
283
|
|
199
284
|
# Execute a batch of bulk write operations.
|
@@ -204,13 +289,181 @@ module Mongo
|
|
204
289
|
# @param [ Array<Hash> ] operations The operations.
|
205
290
|
# @param [ Hash ] options The options.
|
206
291
|
#
|
207
|
-
# @
|
292
|
+
# @option options [ true, false ] :ordered Whether the operations
|
293
|
+
# should be executed in order.
|
294
|
+
# @option options [ Hash ] :write_concern The write concern options.
|
295
|
+
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
|
296
|
+
#
|
297
|
+
# @return [ BulkWrite::Result ] The result of the operation.
|
208
298
|
#
|
209
299
|
# @since 2.0.0
|
210
|
-
def bulk_write(operations, options)
|
300
|
+
def bulk_write(operations, options = {})
|
211
301
|
BulkWrite.get(self, operations, options).execute
|
212
302
|
end
|
213
303
|
|
304
|
+
# Remove a document from the collection.
|
305
|
+
#
|
306
|
+
# @example Remove a single document from the collection.
|
307
|
+
# collection.delete_one
|
308
|
+
#
|
309
|
+
# @param [ Hash ] filter The filter to use.
|
310
|
+
#
|
311
|
+
# @return [ Result ] The response from the database.
|
312
|
+
#
|
313
|
+
# @since 2.1.0
|
314
|
+
def delete_one(filter = nil)
|
315
|
+
find(filter).delete_one
|
316
|
+
end
|
317
|
+
|
318
|
+
# Remove documents from the collection.
|
319
|
+
#
|
320
|
+
# @example Remove multiple documents from the collection.
|
321
|
+
# collection.delete_many
|
322
|
+
#
|
323
|
+
# @param [ Hash ] filter The filter to use.
|
324
|
+
#
|
325
|
+
# @return [ Result ] The response from the database.
|
326
|
+
#
|
327
|
+
# @since 2.1.0
|
328
|
+
def delete_many(filter = nil)
|
329
|
+
find(filter).delete_many
|
330
|
+
end
|
331
|
+
|
332
|
+
# Replaces a single document in the collection with the new document.
|
333
|
+
#
|
334
|
+
# @example Replace a single document.
|
335
|
+
# collection.replace_one({ name: 'test' }, { name: 'test1' })
|
336
|
+
#
|
337
|
+
# @param [ Hash ] filter The filter to use.
|
338
|
+
# @param [ Hash ] replacement The replacement document..
|
339
|
+
# @param [ Hash ] options The options.
|
340
|
+
#
|
341
|
+
# @option options [ true, false ] :upsert Whether to upsert if the
|
342
|
+
# document doesn't exist.
|
343
|
+
#
|
344
|
+
# @return [ Result ] The response from the database.
|
345
|
+
#
|
346
|
+
# @since 2.1.0
|
347
|
+
def replace_one(filter, replacement, options = {})
|
348
|
+
find(filter).replace_one(replacement, options)
|
349
|
+
end
|
350
|
+
|
351
|
+
# Update documents in the collection.
|
352
|
+
#
|
353
|
+
# @example Update multiple documents in the collection.
|
354
|
+
# collection.update_many({ name: 'test'}, '$set' => { name: 'test1' })
|
355
|
+
#
|
356
|
+
# @param [ Hash ] filter The filter to use.
|
357
|
+
# @param [ Hash ] update The update statement.
|
358
|
+
# @param [ Hash ] options The options.
|
359
|
+
#
|
360
|
+
# @option options [ true, false ] :upsert Whether to upsert if the
|
361
|
+
# document doesn't exist.
|
362
|
+
#
|
363
|
+
# @return [ Result ] The response from the database.
|
364
|
+
#
|
365
|
+
# @since 2.1.0
|
366
|
+
def update_many(filter, update, options = {})
|
367
|
+
find(filter).update_many(update, options)
|
368
|
+
end
|
369
|
+
|
370
|
+
# Update a single document in the collection.
|
371
|
+
#
|
372
|
+
# @example Update a single document in the collection.
|
373
|
+
# collection.update_one({ name: 'test'}, '$set' => { name: 'test1'})
|
374
|
+
#
|
375
|
+
# @param [ Hash ] filter The filter to use.
|
376
|
+
# @param [ Hash ] update The update statement.
|
377
|
+
# @param [ Hash ] options The options.
|
378
|
+
#
|
379
|
+
# @option options [ true, false ] :upsert Whether to upsert if the
|
380
|
+
# document doesn't exist.
|
381
|
+
#
|
382
|
+
# @return [ Result ] The response from the database.
|
383
|
+
#
|
384
|
+
# @since 2.1.0
|
385
|
+
def update_one(filter, update, options = {})
|
386
|
+
find(filter).update_one(update, options)
|
387
|
+
end
|
388
|
+
|
389
|
+
# Finds a single document in the database via findAndModify and deletes
|
390
|
+
# it, returning the original document.
|
391
|
+
#
|
392
|
+
# @example Find one document and delete it.
|
393
|
+
# collection.find_one_and_delete(name: 'test')
|
394
|
+
#
|
395
|
+
# @param [ Hash ] filter The filter to use.
|
396
|
+
# @param [ Hash ] options The options.
|
397
|
+
#
|
398
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command
|
399
|
+
# to run in milliseconds.
|
400
|
+
# @option options [ Hash ] :projection The fields to include or exclude in the returned doc.
|
401
|
+
# @option options [ Hash ] :sort The key and direction pairs by which the result set
|
402
|
+
# will be sorted.
|
403
|
+
#
|
404
|
+
# @return [ BSON::Document, nil ] The document, if found.
|
405
|
+
#
|
406
|
+
# @since 2.1.0
|
407
|
+
def find_one_and_delete(filter, options = {})
|
408
|
+
find(filter, options).find_one_and_delete
|
409
|
+
end
|
410
|
+
|
411
|
+
# Finds a single document via findAndModify and updates it, returning the original doc unless
|
412
|
+
# otherwise specified.
|
413
|
+
#
|
414
|
+
# @example Find a document and update it, returning the original.
|
415
|
+
# collection.find_one_and_update({ name: 'test' }, { "$set" => { name: 'test1' }})
|
416
|
+
#
|
417
|
+
# @example Find a document and update it, returning the updated document.
|
418
|
+
# collection.find_one_and_update({ name: 'test' }, { "$set" => { name: 'test1' }}, :return_document => :after)
|
419
|
+
#
|
420
|
+
# @param [ Hash ] filter The filter to use.
|
421
|
+
# @param [ BSON::Document ] update The update statement.
|
422
|
+
# @param [ Hash ] options The options.
|
423
|
+
#
|
424
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command
|
425
|
+
# to run in milliseconds.
|
426
|
+
# @option options [ Hash ] :projection The fields to include or exclude in the returned doc.
|
427
|
+
# @option options [ Hash ] :sort The key and direction pairs by which the result set
|
428
|
+
# will be sorted.
|
429
|
+
# @option options [ Symbol ] :return_document Either :before or :after.
|
430
|
+
# @option options [ true, false ] :upsert Whether to upsert if the document doesn't exist.
|
431
|
+
#
|
432
|
+
# @return [ BSON::Document ] The document.
|
433
|
+
#
|
434
|
+
# @since 2.1.0
|
435
|
+
def find_one_and_update(filter, update, options = {})
|
436
|
+
find(filter, options).find_one_and_update(update, options)
|
437
|
+
end
|
438
|
+
|
439
|
+
# Finds a single document and replaces it, returning the original doc unless
|
440
|
+
# otherwise specified.
|
441
|
+
#
|
442
|
+
# @example Find a document and replace it, returning the original.
|
443
|
+
# collection.find_one_and_replace({ name: 'test' }, { name: 'test1' })
|
444
|
+
#
|
445
|
+
# @example Find a document and replace it, returning the new document.
|
446
|
+
# collection.find_one_and_replace({ name: 'test' }, { name: 'test1' }, :return_document => :after)
|
447
|
+
#
|
448
|
+
# @param [ Hash ] filter The filter to use.
|
449
|
+
# @param [ BSON::Document ] replacement The replacement document.
|
450
|
+
# @param [ Hash ] options The options.
|
451
|
+
#
|
452
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command
|
453
|
+
# to run in milliseconds.
|
454
|
+
# @option options [ Hash ] :projection The fields to include or exclude in the returned doc.
|
455
|
+
# @option options [ Hash ] :sort The key and direction pairs by which the result set
|
456
|
+
# will be sorted.
|
457
|
+
# @option options [ Symbol ] :return_document Either :before or :after.
|
458
|
+
# @option options [ true, false ] :upsert Whether to upsert if the document doesn't exist.
|
459
|
+
#
|
460
|
+
# @return [ BSON::Document ] The document.
|
461
|
+
#
|
462
|
+
# @since 2.1.0
|
463
|
+
def find_one_and_replace(filter, replacement, options = {})
|
464
|
+
find(filter, options).find_one_and_update(replacement, options)
|
465
|
+
end
|
466
|
+
|
214
467
|
# Get the fully qualified namespace of the collection.
|
215
468
|
#
|
216
469
|
# @example Get the fully qualified namespace.
|