mongo 1.1.5 → 1.3.0
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.
- data/README.md +15 -15
- data/Rakefile +38 -17
- data/docs/FAQ.md +4 -0
- data/docs/HISTORY.md +59 -0
- data/docs/RELEASES.md +33 -0
- data/docs/REPLICA_SETS.md +13 -16
- data/lib/mongo/collection.rb +157 -69
- data/lib/mongo/connection.rb +189 -65
- data/lib/mongo/cursor.rb +43 -29
- data/lib/mongo/db.rb +63 -43
- data/lib/mongo/exceptions.rb +4 -1
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_ext.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +1 -1
- data/lib/mongo/gridfs/grid_io.rb +89 -8
- data/lib/mongo/gridfs/grid_io_fix.rb +1 -1
- data/lib/mongo/repl_set_connection.rb +72 -20
- data/lib/mongo/test.rb +20 -0
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/core_ext.rb +11 -1
- data/lib/mongo/util/pool.rb +67 -15
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/support.rb +1 -1
- data/lib/mongo/util/uri_parser.rb +127 -13
- data/lib/mongo.rb +38 -2
- data/test/async/collection_test.rb +224 -0
- data/test/async/connection_test.rb +24 -0
- data/test/async/cursor_test.rb +162 -0
- data/test/async/worker_pool_test.rb +99 -0
- data/test/auxillary/fork_test.rb +30 -0
- data/test/auxillary/repl_set_auth_test.rb +58 -0
- data/test/auxillary/threaded_authentication_test.rb +101 -0
- data/test/bson/bson_test.rb +140 -28
- data/test/bson/byte_buffer_test.rb +18 -0
- data/test/bson/object_id_test.rb +14 -1
- data/test/bson/ordered_hash_test.rb +7 -0
- data/test/bson/timestamp_test.rb +24 -0
- data/test/collection_test.rb +104 -15
- data/test/connection_test.rb +78 -2
- data/test/conversions_test.rb +10 -11
- data/test/cursor_fail_test.rb +1 -1
- data/test/cursor_message_test.rb +1 -1
- data/test/cursor_test.rb +33 -4
- data/test/db_api_test.rb +30 -52
- data/test/db_test.rb +3 -3
- data/test/grid_file_system_test.rb +0 -1
- data/test/grid_io_test.rb +72 -1
- data/test/grid_test.rb +16 -16
- data/test/load/resque/load.rb +21 -0
- data/test/load/resque/processor.rb +26 -0
- data/test/load/thin/load.rb +24 -0
- data/test/load/unicorn/load.rb +23 -0
- data/test/load/unicorn/unicorn.rb +29 -0
- data/test/replica_sets/connect_test.rb +11 -1
- data/test/replica_sets/connection_string_test.rb +32 -0
- data/test/replica_sets/query_secondaries.rb +16 -0
- data/test/replica_sets/query_test.rb +10 -0
- data/test/replica_sets/replication_ack_test.rb +2 -0
- data/test/replica_sets/rs_test_helper.rb +9 -11
- data/test/support/hash_with_indifferent_access.rb +0 -13
- data/test/support_test.rb +0 -1
- data/test/test_helper.rb +27 -8
- data/test/tools/auth_repl_set_manager.rb +14 -0
- data/test/tools/load.rb +58 -0
- data/test/tools/repl_set_manager.rb +34 -9
- data/test/tools/sharding_manager.rb +202 -0
- data/test/tools/test.rb +3 -12
- data/test/unit/collection_test.rb +20 -24
- data/test/unit/connection_test.rb +4 -18
- data/test/unit/cursor_test.rb +16 -6
- data/test/unit/db_test.rb +10 -11
- data/test/unit/repl_set_connection_test.rb +0 -23
- data/test/unit/safe_test.rb +3 -3
- data/test/uri_test.rb +91 -0
- metadata +49 -12
- data/docs/1.0_UPGRADE.md +0 -21
data/lib/mongo/collection.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
3
|
# --
|
|
4
|
-
# Copyright (C) 2008-
|
|
4
|
+
# Copyright (C) 2008-2011 10gen Inc.
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -24,13 +24,13 @@ module Mongo
|
|
|
24
24
|
|
|
25
25
|
# Initialize a collection object.
|
|
26
26
|
#
|
|
27
|
-
# @param [DB] db a MongoDB database instance.
|
|
28
27
|
# @param [String, Symbol] name the name of the collection.
|
|
28
|
+
# @param [DB] db a MongoDB database instance.
|
|
29
29
|
#
|
|
30
|
-
# @option
|
|
30
|
+
# @option opts [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
|
|
31
31
|
# other than the default BSON::ObjectId.
|
|
32
32
|
#
|
|
33
|
-
# @option
|
|
33
|
+
# @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
|
|
34
34
|
# for insert, update, and remove method called on this Collection instance. If no
|
|
35
35
|
# value is provided, the default value set on this instance's DB will be used. This
|
|
36
36
|
# default can be overridden for any invocation of insert, update, or remove.
|
|
@@ -44,7 +44,13 @@ module Mongo
|
|
|
44
44
|
# @return [Collection]
|
|
45
45
|
#
|
|
46
46
|
# @core collections constructor_details
|
|
47
|
-
def initialize(
|
|
47
|
+
def initialize(name, db, opts={})
|
|
48
|
+
if db.is_a?(String) && name.is_a?(Mongo::DB)
|
|
49
|
+
warn "Warning: the order of parameters to initialize a collection have changed. " +
|
|
50
|
+
"Please specify the collection name first, followed by the db."
|
|
51
|
+
db, name = name, db
|
|
52
|
+
end
|
|
53
|
+
|
|
48
54
|
case name
|
|
49
55
|
when Symbol, String
|
|
50
56
|
else
|
|
@@ -63,23 +69,22 @@ module Mongo
|
|
|
63
69
|
raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
|
|
64
70
|
end
|
|
65
71
|
|
|
66
|
-
if
|
|
72
|
+
if opts.respond_to?(:create_pk) || !opts.is_a?(Hash)
|
|
67
73
|
warn "The method for specifying a primary key factory on a Collection has changed.\n" +
|
|
68
74
|
"Please specify it as an option (e.g., :pk => PkFactory)."
|
|
69
|
-
pk_factory =
|
|
75
|
+
pk_factory = opts
|
|
70
76
|
else
|
|
71
77
|
pk_factory = nil
|
|
72
78
|
end
|
|
73
79
|
|
|
74
80
|
@db, @name = db, name
|
|
75
81
|
@connection = @db.connection
|
|
76
|
-
@logger = @connection.logger
|
|
77
82
|
@cache_time = @db.cache_time
|
|
78
83
|
@cache = Hash.new(0)
|
|
79
84
|
unless pk_factory
|
|
80
|
-
@safe
|
|
85
|
+
@safe = opts.fetch(:safe, @db.safe)
|
|
81
86
|
end
|
|
82
|
-
@pk_factory = pk_factory ||
|
|
87
|
+
@pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
|
|
83
88
|
@hint = nil
|
|
84
89
|
end
|
|
85
90
|
|
|
@@ -96,7 +101,7 @@ module Mongo
|
|
|
96
101
|
# the specified sub-collection
|
|
97
102
|
def [](name)
|
|
98
103
|
name = "#{self.name}.#{name}"
|
|
99
|
-
return Collection.new(
|
|
104
|
+
return Collection.new(name, db) if !db.strict? || db.collection_names.include?(name)
|
|
100
105
|
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
|
101
106
|
end
|
|
102
107
|
|
|
@@ -134,7 +139,7 @@ module Mongo
|
|
|
134
139
|
# to Ruby 1.8).
|
|
135
140
|
#
|
|
136
141
|
# @option opts [Array, Hash] :fields field names that should be returned in the result
|
|
137
|
-
# set ("_id" will
|
|
142
|
+
# set ("_id" will be included unless explicity excluded). By limiting results to a certain subset of fields,
|
|
138
143
|
# you can cut down on network traffic and decoding time. If using a Hash, keys should be field
|
|
139
144
|
# names and values should be either 1 or 0, depending on whether you want to include or exclude
|
|
140
145
|
# the given field.
|
|
@@ -152,6 +157,8 @@ module Mongo
|
|
|
152
157
|
# the normal cursor timeout behavior of the mongod process. When +false+, the returned cursor will never timeout. Note
|
|
153
158
|
# that disabling timeout will only work when #find is invoked with a block. This is to prevent any inadvertant failure to
|
|
154
159
|
# close the cursor, as the cursor is explicitly closed when block code finishes.
|
|
160
|
+
# @option opts [Block] :transformer (nil) a block for tranforming returned documents.
|
|
161
|
+
# This is normally used by object mappers to convert each returned document to an instance of a class.
|
|
155
162
|
#
|
|
156
163
|
# @raise [ArgumentError]
|
|
157
164
|
# if timeout is set to false and find is not invoked in a block
|
|
@@ -170,6 +177,7 @@ module Mongo
|
|
|
170
177
|
snapshot = opts.delete(:snapshot)
|
|
171
178
|
batch_size = opts.delete(:batch_size)
|
|
172
179
|
timeout = (opts.delete(:timeout) == false) ? false : true
|
|
180
|
+
transformer = opts.delete(:transformer)
|
|
173
181
|
|
|
174
182
|
if timeout == false && !block_given?
|
|
175
183
|
raise ArgumentError, "Collection#find must be invoked with a block when timeout is disabled."
|
|
@@ -183,8 +191,18 @@ module Mongo
|
|
|
183
191
|
|
|
184
192
|
raise RuntimeError, "Unknown options [#{opts.inspect}]" unless opts.empty?
|
|
185
193
|
|
|
186
|
-
cursor = Cursor.new(self,
|
|
187
|
-
:
|
|
194
|
+
cursor = Cursor.new(self, {
|
|
195
|
+
:selector => selector,
|
|
196
|
+
:fields => fields,
|
|
197
|
+
:skip => skip,
|
|
198
|
+
:limit => limit,
|
|
199
|
+
:order => sort,
|
|
200
|
+
:hint => hint,
|
|
201
|
+
:snapshot => snapshot,
|
|
202
|
+
:timeout => timeout,
|
|
203
|
+
:batch_size => batch_size,
|
|
204
|
+
:transformer => transformer,
|
|
205
|
+
})
|
|
188
206
|
|
|
189
207
|
if block_given?
|
|
190
208
|
yield cursor
|
|
@@ -271,10 +289,10 @@ module Mongo
|
|
|
271
289
|
# @see DB#remove for options that can be passed to :safe.
|
|
272
290
|
#
|
|
273
291
|
# @core insert insert-instance_method
|
|
274
|
-
def insert(doc_or_docs,
|
|
292
|
+
def insert(doc_or_docs, opts={})
|
|
275
293
|
doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
|
|
276
294
|
doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
|
|
277
|
-
safe =
|
|
295
|
+
safe = opts.fetch(:safe, @safe)
|
|
278
296
|
result = insert_documents(doc_or_docs, @name, true, safe)
|
|
279
297
|
result.size > 1 ? result : result.first
|
|
280
298
|
end
|
|
@@ -310,18 +328,19 @@ module Mongo
|
|
|
310
328
|
# @core remove remove-instance_method
|
|
311
329
|
def remove(selector={}, opts={})
|
|
312
330
|
# Initial byte is 0.
|
|
313
|
-
safe = opts.
|
|
331
|
+
safe = opts.fetch(:safe, @safe)
|
|
314
332
|
message = BSON::ByteBuffer.new("\0\0\0\0")
|
|
315
333
|
BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
|
316
334
|
message.put_int(0)
|
|
317
335
|
message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
|
|
318
336
|
|
|
319
|
-
@
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
337
|
+
@connection.instrument(:remove, :database => @db.name, :collection => @name, :selector => selector) do
|
|
338
|
+
if safe
|
|
339
|
+
@connection.send_message_with_safe_check(Mongo::Constants::OP_DELETE, message, @db.name, nil, safe)
|
|
340
|
+
else
|
|
341
|
+
@connection.send_message(Mongo::Constants::OP_DELETE, message)
|
|
342
|
+
true
|
|
343
|
+
end
|
|
325
344
|
end
|
|
326
345
|
end
|
|
327
346
|
|
|
@@ -336,8 +355,8 @@ module Mongo
|
|
|
336
355
|
# a hash specifying the fields to be changed in the selected document,
|
|
337
356
|
# or (in the case of an upsert) the document to be inserted
|
|
338
357
|
#
|
|
339
|
-
# @option [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
|
|
340
|
-
# @option [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
|
|
358
|
+
# @option opts [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
|
|
359
|
+
# @option opts [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
|
|
341
360
|
# just the first matching document. Note: only works in MongoDB 1.1.3 or later.
|
|
342
361
|
# @option opts [Boolean] :safe (+false+)
|
|
343
362
|
# If true, check that the save succeeded. OperationFailure
|
|
@@ -350,22 +369,24 @@ module Mongo
|
|
|
350
369
|
# Otherwise, returns true.
|
|
351
370
|
#
|
|
352
371
|
# @core update update-instance_method
|
|
353
|
-
def update(selector, document,
|
|
372
|
+
def update(selector, document, opts={})
|
|
354
373
|
# Initial byte is 0.
|
|
355
|
-
safe =
|
|
374
|
+
safe = opts.fetch(:safe, @safe)
|
|
356
375
|
message = BSON::ByteBuffer.new("\0\0\0\0")
|
|
357
376
|
BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
|
358
377
|
update_options = 0
|
|
359
|
-
update_options += 1 if
|
|
360
|
-
update_options += 2 if
|
|
378
|
+
update_options += 1 if opts[:upsert]
|
|
379
|
+
update_options += 2 if opts[:multi]
|
|
361
380
|
message.put_int(update_options)
|
|
362
381
|
message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
|
|
363
382
|
message.put_binary(BSON::BSON_CODER.serialize(document, false, true).to_s)
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
383
|
+
|
|
384
|
+
@connection.instrument(:update, :database => @db.name, :collection => @name, :selector => selector, :document => document) do
|
|
385
|
+
if safe
|
|
386
|
+
@connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name, nil, safe)
|
|
387
|
+
else
|
|
388
|
+
@connection.send_message(Mongo::Constants::OP_UPDATE, message, nil)
|
|
389
|
+
end
|
|
369
390
|
end
|
|
370
391
|
end
|
|
371
392
|
|
|
@@ -415,6 +436,7 @@ module Mongo
|
|
|
415
436
|
opts[:dropDups] = opts.delete(:drop_dups) if opts[:drop_dups]
|
|
416
437
|
field_spec = parse_index_spec(spec)
|
|
417
438
|
name = opts.delete(:name) || generate_index_name(field_spec)
|
|
439
|
+
name = name.to_s if name
|
|
418
440
|
|
|
419
441
|
generate_indexes(field_spec, name, opts)
|
|
420
442
|
name
|
|
@@ -437,18 +459,15 @@ module Mongo
|
|
|
437
459
|
#
|
|
438
460
|
# @return [String] the name of the index.
|
|
439
461
|
def ensure_index(spec, opts={})
|
|
440
|
-
valid = BSON::OrderedHash.new
|
|
441
462
|
now = Time.now.utc.to_i
|
|
442
463
|
field_spec = parse_index_spec(spec)
|
|
443
464
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
timeout = @cache[cache_key] || 0
|
|
447
|
-
valid[key] = value if timeout <= now
|
|
448
|
-
end
|
|
465
|
+
name = opts.delete(:name) || generate_index_name(field_spec)
|
|
466
|
+
name = name.to_s if name
|
|
449
467
|
|
|
450
|
-
name
|
|
451
|
-
|
|
468
|
+
if !@cache[name] || @cache[name] <= now
|
|
469
|
+
generate_indexes(field_spec, name, opts)
|
|
470
|
+
end
|
|
452
471
|
|
|
453
472
|
# Reset the cache here in case there are any errors inserting. Best to be safe.
|
|
454
473
|
@cache[name] = now + @cache_time
|
|
@@ -461,7 +480,7 @@ module Mongo
|
|
|
461
480
|
#
|
|
462
481
|
# @core indexes
|
|
463
482
|
def drop_index(name)
|
|
464
|
-
@cache[name] = nil
|
|
483
|
+
@cache[name.to_s] = nil
|
|
465
484
|
@db.drop_index(@name, name)
|
|
466
485
|
end
|
|
467
486
|
|
|
@@ -503,7 +522,7 @@ module Mongo
|
|
|
503
522
|
@db.command(cmd)['value']
|
|
504
523
|
end
|
|
505
524
|
|
|
506
|
-
# Perform a map
|
|
525
|
+
# Perform a map-reduce operation on the current collection.
|
|
507
526
|
#
|
|
508
527
|
# @param [String, BSON::Code] map a map function, written in JavaScript.
|
|
509
528
|
# @param [String, BSON::Code] reduce a reduce function, written in JavaScript.
|
|
@@ -515,13 +534,20 @@ module Mongo
|
|
|
515
534
|
# @option opts [Integer] :limit (nil) if passing a query, number of objects to return from the collection.
|
|
516
535
|
# @option opts [String, BSON::Code] :finalize (nil) a javascript function to apply to the result set after the
|
|
517
536
|
# map/reduce operation has finished.
|
|
518
|
-
# @option opts [String] :out (nil)
|
|
519
|
-
#
|
|
537
|
+
# @option opts [String] :out (nil) a valid output type. In versions of MongoDB prior to v1.7.6,
|
|
538
|
+
# this option takes the name of a collection for the output results. In versions 1.7.6 and later,
|
|
539
|
+
# this option specifies the output type. See the core docs for available output types.
|
|
540
|
+
# @option opts [Boolean] :keeptemp (false) if true, the generated collection will be persisted. The defualt
|
|
541
|
+
# is false. Note that this option has no effect is versions of MongoDB > v1.7.6.
|
|
520
542
|
# @option opts [Boolean ] :verbose (false) if true, provides statistics on job execution time.
|
|
521
543
|
# @option opts [Boolean] :raw (false) if true, return the raw result object from the map_reduce command, and not
|
|
522
|
-
# the instantiated collection that's returned by default.
|
|
544
|
+
# the instantiated collection that's returned by default. Note if a collection name isn't returned in the
|
|
545
|
+
# map-reduce output (as, for example, when using :out => {:inline => 1}), then you must specify this option
|
|
546
|
+
# or an ArgumentError will be raised.
|
|
523
547
|
#
|
|
524
|
-
# @return [Collection] a
|
|
548
|
+
# @return [Collection, Hash] a Mongo::Collection object or a Hash with the map-reduce command's results.
|
|
549
|
+
#
|
|
550
|
+
# @raise ArgumentError if you specify {:out => {:inline => true}} but don't specify :raw => true.
|
|
525
551
|
#
|
|
526
552
|
# @see http://www.mongodb.org/display/DOCS/MapReduce Offical MongoDB map/reduce documentation.
|
|
527
553
|
#
|
|
@@ -544,25 +570,39 @@ module Mongo
|
|
|
544
570
|
|
|
545
571
|
if raw
|
|
546
572
|
result
|
|
547
|
-
|
|
573
|
+
elsif result["result"]
|
|
548
574
|
@db[result["result"]]
|
|
575
|
+
else
|
|
576
|
+
raise ArgumentError, "Could not instantiate collection from result. If you specified " +
|
|
577
|
+
"{:out => {:inline => true}}, then you must also specify :raw => true to get the results."
|
|
549
578
|
end
|
|
550
579
|
end
|
|
551
580
|
alias :mapreduce :map_reduce
|
|
552
581
|
|
|
553
582
|
# Perform a group aggregation.
|
|
554
583
|
#
|
|
555
|
-
# @param [
|
|
556
|
-
#
|
|
557
|
-
#
|
|
558
|
-
# @
|
|
559
|
-
# @
|
|
560
|
-
# @
|
|
561
|
-
#
|
|
562
|
-
#
|
|
563
|
-
#
|
|
564
|
-
# @
|
|
565
|
-
|
|
584
|
+
# @param [Hash] opts the options for this group operation. The minimum required are :initial
|
|
585
|
+
# and :reduce.
|
|
586
|
+
#
|
|
587
|
+
# @option opts [Array, String, Symbol] :key (nil) Either the name of a field or a list of fields to group by (optional).
|
|
588
|
+
# @option opts [String, BSON::Code] :keyf (nil) A JavaScript function to be used to generate the grouping keys (optional).
|
|
589
|
+
# @option opts [String, BSON::Code] :cond ({}) A document specifying a query for filtering the documents over
|
|
590
|
+
# which the aggregation is run (optional).
|
|
591
|
+
# @option opts [Hash] :initial the initial value of the aggregation counter object (required).
|
|
592
|
+
# @option opts [String, BSON::Code] :reduce (nil) a JavaScript aggregation function (required).
|
|
593
|
+
# @option opts [String, BSON::Code] :finalize (nil) a JavaScript function that receives and modifies
|
|
594
|
+
# each of the resultant grouped objects. Available only when group is run with command
|
|
595
|
+
# set to true.
|
|
596
|
+
#
|
|
597
|
+
# @return [Array] the command response consisting of grouped items.
|
|
598
|
+
def group(opts, condition={}, initial={}, reduce=nil, finalize=nil)
|
|
599
|
+
if opts.is_a?(Hash)
|
|
600
|
+
return new_group(opts)
|
|
601
|
+
else
|
|
602
|
+
warn "Collection#group no longer take a list of parameters. This usage is deprecated." +
|
|
603
|
+
"Check out the new API at http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method"
|
|
604
|
+
end
|
|
605
|
+
|
|
566
606
|
reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
|
|
567
607
|
|
|
568
608
|
group_command = {
|
|
@@ -574,14 +614,19 @@ module Mongo
|
|
|
574
614
|
}
|
|
575
615
|
}
|
|
576
616
|
|
|
577
|
-
|
|
578
|
-
|
|
617
|
+
if opts.is_a?(Symbol)
|
|
618
|
+
raise MongoArgumentError, "Group takes either an array of fields to group by or a JavaScript function" +
|
|
619
|
+
"in the form of a String or BSON::Code."
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
unless opts.nil?
|
|
623
|
+
if opts.is_a? Array
|
|
579
624
|
key_type = "key"
|
|
580
625
|
key_value = {}
|
|
581
|
-
|
|
626
|
+
opts.each { |k| key_value[k] = 1 }
|
|
582
627
|
else
|
|
583
628
|
key_type = "$keyf"
|
|
584
|
-
key_value =
|
|
629
|
+
key_value = opts.is_a?(BSON::Code) ? opts : BSON::Code.new(opts)
|
|
585
630
|
end
|
|
586
631
|
|
|
587
632
|
group_command["group"][key_type] = key_value
|
|
@@ -601,6 +646,48 @@ module Mongo
|
|
|
601
646
|
end
|
|
602
647
|
end
|
|
603
648
|
|
|
649
|
+
private
|
|
650
|
+
|
|
651
|
+
def new_group(opts={})
|
|
652
|
+
reduce = opts[:reduce]
|
|
653
|
+
finalize = opts[:finalize]
|
|
654
|
+
cond = opts.fetch(:cond, {})
|
|
655
|
+
initial = opts[:initial]
|
|
656
|
+
|
|
657
|
+
if !(reduce && initial)
|
|
658
|
+
raise MongoArgumentError, "Group requires at minimum values for initial and reduce."
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
cmd = {
|
|
662
|
+
"group" => {
|
|
663
|
+
"ns" => @name,
|
|
664
|
+
"$reduce" => reduce.to_bson_code,
|
|
665
|
+
"cond" => cond,
|
|
666
|
+
"initial" => initial
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if finalize
|
|
671
|
+
cmd['group']['finalize'] = finalize.to_bson_code
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
if key = opts[:key]
|
|
675
|
+
if key.is_a?(String) || key.is_a?(Symbol)
|
|
676
|
+
key = [key]
|
|
677
|
+
end
|
|
678
|
+
key_value = {}
|
|
679
|
+
key.each { |k| key_value[k] = 1 }
|
|
680
|
+
cmd["group"]["key"] = key_value
|
|
681
|
+
elsif keyf = opts[:keyf]
|
|
682
|
+
cmd["group"]["$keyf"] = keyf.to_bson_code
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
result = @db.command(cmd)
|
|
686
|
+
result["retval"]
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
public
|
|
690
|
+
|
|
604
691
|
# Return a list of distinct values for +key+ across all
|
|
605
692
|
# documents in the collection. The key may use dot notation
|
|
606
693
|
# to reach into an embedded object.
|
|
@@ -776,11 +863,12 @@ module Mongo
|
|
|
776
863
|
end
|
|
777
864
|
raise InvalidOperation, "Exceded maximum insert size of 16,000,000 bytes" if message.size > 16_000_000
|
|
778
865
|
|
|
779
|
-
@
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
866
|
+
@connection.instrument(:insert, :database => @db.name, :collection => collection_name, :documents => documents) do
|
|
867
|
+
if safe
|
|
868
|
+
@connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name, nil, safe)
|
|
869
|
+
else
|
|
870
|
+
@connection.send_message(Mongo::Constants::OP_INSERT, message, nil)
|
|
871
|
+
end
|
|
784
872
|
end
|
|
785
873
|
documents.collect { |o| o[:_id] || o['_id'] }
|
|
786
874
|
end
|