mongo 0.18.2 → 0.18.3
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.rdoc +37 -28
- data/Rakefile +19 -0
- data/bin/objectid_benchmark.rb +23 -0
- data/examples/admin.rb +7 -6
- data/examples/capped.rb +3 -4
- data/examples/cursor.rb +4 -3
- data/examples/gridfs.rb +3 -2
- data/examples/index_test.rb +10 -9
- data/examples/info.rb +3 -2
- data/examples/queries.rb +3 -2
- data/examples/simple.rb +3 -2
- data/examples/strict.rb +2 -1
- data/examples/types.rb +4 -3
- data/lib/mongo.rb +29 -12
- data/lib/mongo/admin.rb +17 -2
- data/lib/mongo/collection.rb +230 -169
- data/lib/mongo/connection.rb +136 -91
- data/lib/mongo/cursor.rb +68 -40
- data/lib/mongo/db.rb +247 -123
- data/lib/mongo/{errors.rb → exceptions.rb} +6 -5
- data/lib/mongo/gridfs.rb +6 -0
- data/lib/mongo/gridfs/grid_store.rb +142 -94
- data/lib/mongo/types/binary.rb +11 -1
- data/lib/mongo/types/code.rb +6 -1
- data/lib/mongo/types/dbref.rb +7 -2
- data/lib/mongo/types/min_max_keys.rb +58 -0
- data/lib/mongo/types/objectid.rb +76 -20
- data/lib/mongo/types/regexp_of_holding.rb +5 -0
- data/lib/mongo/util/bson_ruby.rb +36 -2
- data/lib/mongo/util/byte_buffer.rb +18 -2
- data/lib/mongo/util/conversions.rb +6 -5
- data/lib/mongo/util/ordered_hash.rb +3 -1
- data/lib/mongo/util/support.rb +3 -0
- data/lib/mongo/util/xml_to_ruby.rb +7 -0
- data/test/test_bson.rb +48 -0
- data/test/test_collection.rb +13 -0
- data/test/test_connection.rb +35 -0
- data/test/test_conversions.rb +1 -1
- data/test/test_cursor.rb +37 -5
- data/test/test_db.rb +51 -2
- data/test/test_db_api.rb +4 -7
- data/test/test_grid_store.rb +10 -0
- data/test/test_objectid.rb +16 -2
- data/test/test_ordered_hash.rb +14 -0
- data/test/threading/test_threading_large_pool.rb +4 -4
- data/test/unit/db_test.rb +43 -0
- metadata +5 -7
- data/examples/benchmarks.rb +0 -42
- data/examples/blog.rb +0 -76
- data/lib/mongo/constants.rb +0 -15
- data/test/mongo-qa/_common.rb +0 -8
data/lib/mongo/admin.rb
CHANGED
@@ -16,16 +16,22 @@
|
|
16
16
|
|
17
17
|
module Mongo
|
18
18
|
|
19
|
-
#
|
20
|
-
#
|
19
|
+
# @deprecated this class is deprecated. Methods defined here will
|
20
|
+
# henceforth be available in Mongo::DB.
|
21
21
|
class Admin
|
22
22
|
|
23
23
|
def initialize(db)
|
24
|
+
warn "The Admin class has been DEPRECATED. All admin methods now exist in DB."
|
24
25
|
@db = db
|
25
26
|
end
|
26
27
|
|
27
28
|
# Return the current database profiling level.
|
29
|
+
#
|
30
|
+
# @return [Symbol] :off, :slow_only, or :all
|
31
|
+
#
|
32
|
+
# @deprecated please use DB#profiling_level instead.
|
28
33
|
def profiling_level
|
34
|
+
warn "Admin#profiling_level has been DEPRECATED. Please use DB#profiling_level instead."
|
29
35
|
oh = OrderedHash.new
|
30
36
|
oh[:profile] = -1
|
31
37
|
doc = @db.command(oh)
|
@@ -43,7 +49,10 @@ module Mongo
|
|
43
49
|
end
|
44
50
|
|
45
51
|
# Set database profiling level to :off, :slow_only, or :all.
|
52
|
+
#
|
53
|
+
# @deprecated please use DB#profiling_level= instead.
|
46
54
|
def profiling_level=(level)
|
55
|
+
warn "Admin#profiling_level= has been DEPRECATED. Please use DB#profiling_level= instead."
|
47
56
|
oh = OrderedHash.new
|
48
57
|
oh[:profile] = case level
|
49
58
|
when :off
|
@@ -60,14 +69,20 @@ module Mongo
|
|
60
69
|
end
|
61
70
|
|
62
71
|
# Returns an array containing current profiling information.
|
72
|
+
#
|
73
|
+
# @deprecated please use DB#profiling_info instead.
|
63
74
|
def profiling_info
|
75
|
+
warn "Admin#profiling_info has been DEPRECATED. Please use DB#profiling_info instead."
|
64
76
|
Cursor.new(Collection.new(@db, DB::SYSTEM_PROFILE_COLLECTION), :selector => {}).to_a
|
65
77
|
end
|
66
78
|
|
67
79
|
# Validate a named collection by raising an exception if there is a
|
68
80
|
# problem or returning an interesting hash (see especially the
|
69
81
|
# 'result' string value) if all is well.
|
82
|
+
#
|
83
|
+
# @deprecated please use DB#validate_collection instead.
|
70
84
|
def validate_collection(name)
|
85
|
+
warn "Admin#validate_collection has been DEPRECATED. Please use DB#validate_collection instead."
|
71
86
|
doc = @db.command(:validate => name)
|
72
87
|
raise "Error with validate command: #{doc.inspect}" unless @db.ok?(doc)
|
73
88
|
result = doc['result']
|
data/lib/mongo/collection.rb
CHANGED
@@ -16,11 +16,23 @@
|
|
16
16
|
|
17
17
|
module Mongo
|
18
18
|
|
19
|
-
# A named collection of
|
19
|
+
# A named collection of documents in a database.
|
20
20
|
class Collection
|
21
21
|
|
22
22
|
attr_reader :db, :name, :pk_factory, :hint
|
23
23
|
|
24
|
+
# Initialize a collection object.
|
25
|
+
#
|
26
|
+
# @param [DB] db a MongoDB database instance.
|
27
|
+
# @param [String, Symbol] name the name of the collection.
|
28
|
+
#
|
29
|
+
# @raise [InvalidName]
|
30
|
+
# if collection name is empty, contains '$', or starts or ends with '.'
|
31
|
+
#
|
32
|
+
# @raise [TypeError]
|
33
|
+
# if collection name is not a string or symbol
|
34
|
+
#
|
35
|
+
# @return [Collection]
|
24
36
|
def initialize(db, name, pk_factory=nil)
|
25
37
|
case name
|
26
38
|
when Symbol, String
|
@@ -46,21 +58,30 @@ module Mongo
|
|
46
58
|
@hint = nil
|
47
59
|
end
|
48
60
|
|
49
|
-
#
|
61
|
+
# Return a sub-collection of this collection by name. If 'users' is a collection, then
|
62
|
+
# 'users.comments' is a sub-collection of users.
|
63
|
+
#
|
64
|
+
# @param [String] name
|
65
|
+
# the collection to return
|
50
66
|
#
|
51
|
-
#
|
67
|
+
# @raise [InvalidName]
|
68
|
+
# if passed an invalid collection name
|
52
69
|
#
|
53
|
-
#
|
70
|
+
# @return [Collection]
|
71
|
+
# the specified sub-collection
|
54
72
|
def [](name)
|
55
73
|
name = "#{self.name}.#{name}"
|
56
74
|
return Collection.new(db, name) if !db.strict? || db.collection_names.include?(name)
|
57
75
|
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
58
76
|
end
|
59
77
|
|
60
|
-
# Set hint
|
61
|
-
# name, array of field names, or a hash (preferably an OrderedHash).
|
62
|
-
#
|
63
|
-
|
78
|
+
# Set a hint field for query optimizer. Hint may be a single field
|
79
|
+
# name, array of field names, or a hash (preferably an [OrderedHash]).
|
80
|
+
# If using MongoDB > 1.1, you probably don't ever need to set a hint.
|
81
|
+
#
|
82
|
+
# @param [String, Array, OrderedHash] hint a single field, an array of
|
83
|
+
# fields, or a hash specifying fields
|
84
|
+
def hint=(hint=nil)
|
64
85
|
@hint = normalize_hint_fields(hint)
|
65
86
|
self
|
66
87
|
end
|
@@ -70,7 +91,7 @@ module Mongo
|
|
70
91
|
# The +selector+ argument is a prototype document that all results must
|
71
92
|
# match. For example:
|
72
93
|
#
|
73
|
-
#
|
94
|
+
# collection.find({"hello" => "world"})
|
74
95
|
#
|
75
96
|
# only matches documents that have a key "hello" with value "world".
|
76
97
|
# Matches can have other keys *in addition* to "hello".
|
@@ -80,51 +101,49 @@ module Mongo
|
|
80
101
|
# evaluated cursors will be closed. If given no block +find+ returns a
|
81
102
|
# cursor.
|
82
103
|
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
# :
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# :
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
# :
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
|
109
|
-
|
110
|
-
def find(selector={}, options={})
|
111
|
-
fields = options.delete(:fields)
|
104
|
+
# @param [Hash] selector
|
105
|
+
# a document specifying elements which must be present for a
|
106
|
+
# document to be included in the result set.
|
107
|
+
#
|
108
|
+
# @option opts [Array] :fields field names that should be returned in the result
|
109
|
+
# set ("_id" will always be included). By limiting results to a certain subset of fields,
|
110
|
+
# you can cut down on network traffic and decoding time.
|
111
|
+
# @option opts [Integer] :skip number of documents to skip from the beginning of the result set
|
112
|
+
# @option opts [Integer] :limit maximum number of documents to return
|
113
|
+
# @option opts [Array] :sort an array of [key, direction] pairs to sort by. Direction should
|
114
|
+
# be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)
|
115
|
+
# @option opts [String, Array, OrderedHash] :hint hint for query optimizer, usually not necessary if using MongoDB > 1.1
|
116
|
+
# @option opts [Boolean] :snapshot ('false') if true, snapshot mode will be used for this query.
|
117
|
+
# Snapshot mode assures no duplicates are returned, or objects missed, which were preset at both the start and
|
118
|
+
# end of the query's execution. For details see http://www.mongodb.org/display/DOCS/How+to+do+Snapshotting+in+the+Mongo+Database
|
119
|
+
# @option opts [Boolean] :timeout ('true') when +true+, the returned cursor will be subject to
|
120
|
+
# the normal cursor timeout behavior of the mongod process. When +false+, the returned cursor will never timeout. Note
|
121
|
+
# that disabling timeout will only work when #find is invoked with a block. This is to prevent any inadvertant failure to
|
122
|
+
# close the cursor, as the cursor is explicitly closed when block code finishes.
|
123
|
+
#
|
124
|
+
# @raise [ArgumentError]
|
125
|
+
# if timeout is set to false and find is not invoked in a block
|
126
|
+
#
|
127
|
+
# @raise [RuntimeError]
|
128
|
+
# if given unknown options
|
129
|
+
def find(selector={}, opts={})
|
130
|
+
fields = opts.delete(:fields)
|
112
131
|
fields = ["_id"] if fields && fields.empty?
|
113
|
-
skip =
|
114
|
-
limit =
|
115
|
-
sort =
|
116
|
-
hint =
|
117
|
-
snapshot =
|
118
|
-
if
|
132
|
+
skip = opts.delete(:skip) || skip || 0
|
133
|
+
limit = opts.delete(:limit) || 0
|
134
|
+
sort = opts.delete(:sort)
|
135
|
+
hint = opts.delete(:hint)
|
136
|
+
snapshot = opts.delete(:snapshot)
|
137
|
+
if opts[:timeout] == false && !block_given?
|
119
138
|
raise ArgumentError, "Timeout can be set to false only when #find is invoked with a block."
|
120
139
|
end
|
121
|
-
timeout = block_given? ? (
|
140
|
+
timeout = block_given? ? (opts.delete(:timeout) || true) : true
|
122
141
|
if hint
|
123
142
|
hint = normalize_hint_fields(hint)
|
124
143
|
else
|
125
144
|
hint = @hint # assumed to be normalized already
|
126
145
|
end
|
127
|
-
raise RuntimeError, "Unknown options [#{
|
146
|
+
raise RuntimeError, "Unknown options [#{opts.inspect}]" unless opts.empty?
|
128
147
|
|
129
148
|
cursor = Cursor.new(self, :selector => selector, :fields => fields, :skip => skip, :limit => limit,
|
130
149
|
:order => sort, :hint => hint, :snapshot => snapshot, :timeout => timeout)
|
@@ -137,17 +156,22 @@ module Mongo
|
|
137
156
|
end
|
138
157
|
end
|
139
158
|
|
140
|
-
#
|
159
|
+
# Return a single object from the database.
|
141
160
|
#
|
142
|
-
#
|
143
|
-
# single document
|
161
|
+
# @return [OrderedHash, Nil]
|
162
|
+
# a single document or nil if no result is found.
|
144
163
|
#
|
145
|
-
#
|
146
|
-
# present for a document to be included in the result set
|
164
|
+
# @param [Hash, ObjectID, Nil] spec_or_object_id a hash specifying elements
|
165
|
+
# which must be present for a document to be included in the result set or an
|
147
166
|
# instance of ObjectID to be used as the value for an _id query.
|
148
|
-
#
|
149
|
-
#
|
150
|
-
|
167
|
+
# If nil, an empty selector, {}, will be used.
|
168
|
+
#
|
169
|
+
# @option opts [Hash]
|
170
|
+
# any valid options that can be send to Collection#find
|
171
|
+
#
|
172
|
+
# @raise [TypeError]
|
173
|
+
# if the argument is of an improper type.
|
174
|
+
def find_one(spec_or_object_id=nil, opts={})
|
151
175
|
spec = case spec_or_object_id
|
152
176
|
when nil
|
153
177
|
{}
|
@@ -158,45 +182,45 @@ module Mongo
|
|
158
182
|
else
|
159
183
|
raise TypeError, "spec_or_object_id must be an instance of ObjectID or Hash, or nil"
|
160
184
|
end
|
161
|
-
find(spec,
|
185
|
+
find(spec, opts.merge(:limit => -1)).next_document
|
162
186
|
end
|
163
187
|
|
164
|
-
# Save a document
|
188
|
+
# Save a document to this collection.
|
165
189
|
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
190
|
+
# @param [Hash] doc
|
191
|
+
# the document to be saved. If the document already has an '_id' key,
|
192
|
+
# then an update (upsert) operation will be performed, and any existing
|
193
|
+
# document with that _id is overwritten. Otherwise an insert operation is performed.
|
170
194
|
#
|
171
|
-
#
|
195
|
+
# @return [ObjectID] the _id of the saved document.
|
172
196
|
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
# will be raised on an error.
|
176
|
-
# round-trip to the database
|
177
|
-
def save(
|
178
|
-
if
|
179
|
-
id =
|
180
|
-
update({:_id => id},
|
197
|
+
# @option opts [Boolean] :safe (+false+)
|
198
|
+
# If true, check that the save succeeded. OperationFailure
|
199
|
+
# will be raised on an error. Note that a safe check requires an extra
|
200
|
+
# round-trip to the database.
|
201
|
+
def save(doc, options={})
|
202
|
+
if doc.has_key?(:_id) || doc.has_key?('_id')
|
203
|
+
id = doc[:_id] || doc['_id']
|
204
|
+
update({:_id => id}, doc, :upsert => true, :safe => options.delete(:safe))
|
181
205
|
id
|
182
206
|
else
|
183
|
-
insert(
|
207
|
+
insert(doc, :safe => options.delete(:safe))
|
184
208
|
end
|
185
209
|
end
|
186
210
|
|
187
|
-
# Insert
|
211
|
+
# Insert one or more documents into the collection.
|
188
212
|
#
|
189
|
-
#
|
190
|
-
# document
|
191
|
-
# may have been modified by the database's PK factory, if it has one.
|
213
|
+
# @param [Hash, Array] doc_or_docs
|
214
|
+
# a document (as a hash) or array of documents to be inserted.
|
192
215
|
#
|
193
|
-
#
|
194
|
-
# inserted
|
216
|
+
# @return [ObjectID, Array]
|
217
|
+
# the _id of the inserted document or a list of _ids of all inserted documents.
|
218
|
+
# Note: the object may have been modified by the database's PK factory, if it has one.
|
195
219
|
#
|
196
|
-
#
|
197
|
-
#
|
198
|
-
# will be raised on an error.
|
199
|
-
# round-trip to the database
|
220
|
+
# @option opts [Boolean] :safe (+false+)
|
221
|
+
# If true, check that the save succeeded. OperationFailure
|
222
|
+
# will be raised on an error. Note that a safe check requires an extra
|
223
|
+
# round-trip to the database.
|
200
224
|
def insert(doc_or_docs, options={})
|
201
225
|
doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
|
202
226
|
doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
|
@@ -205,52 +229,72 @@ module Mongo
|
|
205
229
|
end
|
206
230
|
alias_method :<<, :insert
|
207
231
|
|
208
|
-
# Remove all
|
209
|
-
# If +selector+ is specified, only matching documents will be removed.
|
232
|
+
# Remove all documents from this collection.
|
210
233
|
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
# @collection.remove({})
|
234
|
+
# @param [Hash] selector
|
235
|
+
# If specified, only matching documents will be removed.
|
214
236
|
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
|
218
|
-
|
219
|
-
|
237
|
+
# @option opts [Boolean] :safe [false] run the operation in safe mode, which
|
238
|
+
# will call :getlasterror on the database and report any assertions.
|
239
|
+
#
|
240
|
+
# @example remove all documents from the 'users' collection:
|
241
|
+
# users.remove
|
242
|
+
# users.remove({})
|
243
|
+
#
|
244
|
+
# @example remove only documents that have expired:
|
245
|
+
# users.remove({:expire => {"$lte" => Time.now}})
|
246
|
+
#
|
247
|
+
# @return [True]
|
248
|
+
#
|
249
|
+
# @raise [Mongo::OperationFailure] an exception will be raised iff safe mode is enabled
|
250
|
+
# and the operation fails.
|
251
|
+
def remove(selector={}, opts={})
|
252
|
+
# Initial byte is 0.
|
253
|
+
message = ByteBuffer.new([0, 0, 0, 0])
|
220
254
|
BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
221
255
|
message.put_int(0)
|
222
|
-
message.put_array(BSON.serialize(selector, false).
|
223
|
-
|
224
|
-
|
256
|
+
message.put_array(BSON.serialize(selector, false).to_a)
|
257
|
+
|
258
|
+
if opts[:safe]
|
259
|
+
@connection.send_message_with_safe_check(Mongo::Constants::OP_DELETE, message,
|
260
|
+
"db.#{@db.name}.remove(#{selector.inspect})")
|
261
|
+
# the return value of send_message_with_safe_check isn't actually meaningful --
|
262
|
+
# only the fact that it didn't raise an error is -- so just return true
|
263
|
+
true
|
264
|
+
else
|
265
|
+
@connection.send_message(Mongo::Constants::OP_DELETE, message,
|
266
|
+
"db.#{@db.name}.remove(#{selector.inspect})")
|
267
|
+
end
|
225
268
|
end
|
226
269
|
|
227
270
|
# Update a single document in this collection.
|
228
271
|
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# to
|
233
|
-
#
|
234
|
-
#
|
235
|
-
# be
|
236
|
-
#
|
237
|
-
#
|
238
|
-
# :upsert
|
239
|
-
# :multi
|
240
|
-
#
|
241
|
-
#
|
242
|
-
#
|
243
|
-
#
|
272
|
+
# @param [Hash] selector
|
273
|
+
# a hash specifying elements which must be present for a document to be updated. Note:
|
274
|
+
# the update command currently updates only the first document matching the
|
275
|
+
# given selector. If you want all matching documents to be updated, be sure
|
276
|
+
# to specify :multi => true.
|
277
|
+
# @param [Hash] document
|
278
|
+
# a hash specifying the fields to be changed in the selected document,
|
279
|
+
# or (in the case of an upsert) the document to be inserted
|
280
|
+
#
|
281
|
+
# @option [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
|
282
|
+
# @option [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
|
283
|
+
# just the first matching document. Note: only works in MongoDB 1.1.3 or later.
|
284
|
+
# @option opts [Boolean] :safe (+false+)
|
285
|
+
# If true, check that the save succeeded. OperationFailure
|
286
|
+
# will be raised on an error. Note that a safe check requires an extra
|
287
|
+
# round-trip to the database.
|
244
288
|
def update(selector, document, options={})
|
245
|
-
|
246
|
-
message.
|
289
|
+
# Initial byte is 0.
|
290
|
+
message = ByteBuffer.new([0, 0, 0, 0])
|
247
291
|
BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
248
292
|
update_options = 0
|
249
293
|
update_options += 1 if options[:upsert]
|
250
294
|
update_options += 2 if options[:multi]
|
251
295
|
message.put_int(update_options)
|
252
|
-
message.put_array(BSON.serialize(selector, false).
|
253
|
-
message.put_array(BSON.serialize(document, false).
|
296
|
+
message.put_array(BSON.serialize(selector, false).to_a)
|
297
|
+
message.put_array(BSON.serialize(document, false).to_a)
|
254
298
|
if options[:safe]
|
255
299
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name,
|
256
300
|
"db.#{@name}.update(#{selector.inspect}, #{document.inspect})")
|
@@ -260,12 +304,15 @@ module Mongo
|
|
260
304
|
end
|
261
305
|
end
|
262
306
|
|
263
|
-
# Create a new index.
|
264
|
-
#
|
265
|
-
#
|
266
|
-
#
|
267
|
-
#
|
268
|
-
#
|
307
|
+
# Create a new index.
|
308
|
+
#
|
309
|
+
# @param [String, Array] field_or_spec
|
310
|
+
# should be either a single field name or an array of
|
311
|
+
# [field name, direction] pairs. Directions should be specified as Mongo::ASCENDING or Mongo::DESCENDING.
|
312
|
+
#
|
313
|
+
# @param [Boolean] unique if true, this index will enforce a uniqueness constraint.
|
314
|
+
#
|
315
|
+
# @return [String] the name of the index created.
|
269
316
|
def create_index(field_or_spec, unique=false)
|
270
317
|
field_h = OrderedHash.new
|
271
318
|
if field_or_spec.is_a?(String) || field_or_spec.is_a?(Symbol)
|
@@ -283,15 +330,19 @@ module Mongo
|
|
283
330
|
name
|
284
331
|
end
|
285
332
|
|
286
|
-
# Drop index
|
333
|
+
# Drop a specified index.
|
334
|
+
#
|
335
|
+
# @param [String] name
|
287
336
|
def drop_index(name)
|
288
337
|
@db.drop_index(@name, name)
|
289
338
|
end
|
290
339
|
|
291
340
|
# Drop all indexes.
|
292
341
|
def drop_indexes
|
293
|
-
|
342
|
+
|
343
|
+
# Note: calling drop_indexes with no args will drop them all.
|
294
344
|
@db.drop_index(@name, '*')
|
345
|
+
|
295
346
|
end
|
296
347
|
|
297
348
|
# Drop the entire collection. USE WITH CAUTION.
|
@@ -299,26 +350,26 @@ module Mongo
|
|
299
350
|
@db.drop_collection(@name)
|
300
351
|
end
|
301
352
|
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
312
|
-
# :
|
313
|
-
#
|
314
|
-
# :
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
#
|
321
|
-
def map_reduce(map, reduce,
|
353
|
+
# Perform a map/reduce operation on the current collection.
|
354
|
+
#
|
355
|
+
# @param [String, Code] map a map function, written in JavaScript.
|
356
|
+
# @param [String, Code] reduce a reduce function, written in JavaScript.
|
357
|
+
#
|
358
|
+
# @option opts [Hash] :query ({}) a query selector document, like what's passed to #find, to limit
|
359
|
+
# the operation to a subset of the collection.
|
360
|
+
# @option opts [Array] :sort ([]) an array of [key, direction] pairs to sort by. Direction should
|
361
|
+
# be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)
|
362
|
+
# @option opts [Integer] :limit (nil) if passing a query, number of objects to return from the collection.
|
363
|
+
# @option opts [String, Code] :finalize (nil) a javascript function to apply to the result set after the
|
364
|
+
# map/reduce operation has finished.
|
365
|
+
# @option opts [String] :out (nil) the name of the output collection. If specified, the collection will not be treated as temporary.
|
366
|
+
# @option opts [Boolean] :keeptemp (false) if true, the generated collection will be persisted. default is false.
|
367
|
+
# @option opts [Boolean ] :verbose (false) if true, provides statistics on job execution time.
|
368
|
+
#
|
369
|
+
# @return [Collection] a collection containing the results of the operation.
|
370
|
+
#
|
371
|
+
# @see http://www.mongodb.org/display/DOCS/MapReduce Offical MongoDB map/reduce documentation.
|
372
|
+
def map_reduce(map, reduce, opts={})
|
322
373
|
map = Code.new(map) unless map.is_a?(Code)
|
323
374
|
reduce = Code.new(reduce) unless reduce.is_a?(Code)
|
324
375
|
|
@@ -326,7 +377,7 @@ module Mongo
|
|
326
377
|
hash['mapreduce'] = self.name
|
327
378
|
hash['map'] = map
|
328
379
|
hash['reduce'] = reduce
|
329
|
-
hash.merge!
|
380
|
+
hash.merge! opts
|
330
381
|
|
331
382
|
result = @db.command(hash)
|
332
383
|
unless result["ok"] == 1
|
@@ -336,20 +387,20 @@ module Mongo
|
|
336
387
|
end
|
337
388
|
alias :mapreduce :map_reduce
|
338
389
|
|
339
|
-
#
|
340
|
-
# Returns an array of grouped items.
|
390
|
+
# Perform a group aggregation.
|
341
391
|
#
|
342
|
-
# :key
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
#
|
392
|
+
# @param [Array, String, Code, Nil] :key either 1) an array of fields to group by,
|
393
|
+
# 2) a javascript function to generate the key object, or 3) nil.
|
394
|
+
# @param [Hash] condition an optional document specifying a query to limit the documents over which group is run.
|
395
|
+
# @param [Hash] initial initial value of the aggregation counter object
|
396
|
+
# @param [String, Code] reduce aggregation function, in JavaScript
|
397
|
+
# @param [String, Code] finalize :: optional. a JavaScript function that receives and modifies
|
348
398
|
# each of the resultant grouped objects. Available only when group is run
|
349
399
|
# with command set to true.
|
350
|
-
#
|
351
|
-
#
|
352
|
-
#
|
400
|
+
# @param [Boolean] command if true, run the group as a command instead of in an
|
401
|
+
# eval. Note: Running group as eval has been DEPRECATED.
|
402
|
+
#
|
403
|
+
# @return [Array] the grouped items.
|
353
404
|
def group(key, condition, initial, reduce, command=false, finalize=nil)
|
354
405
|
|
355
406
|
if command
|
@@ -443,9 +494,14 @@ EOS
|
|
443
494
|
end
|
444
495
|
end
|
445
496
|
|
446
|
-
#
|
497
|
+
# Return a list of distinct values for +key+ across all
|
447
498
|
# documents in the collection. The key may use dot notation
|
448
499
|
# to reach into an embedded object.
|
500
|
+
#
|
501
|
+
# @param [String, Symbol, OrderedHash] key or hash to group by.
|
502
|
+
# @param [Hash] query a selector for limiting the result set over which to group.
|
503
|
+
#
|
504
|
+
# @example Saving zip codes and ages and returning distinct results.
|
449
505
|
# @collection.save({:zip => 10010, :name => {:age => 27}})
|
450
506
|
# @collection.save({:zip => 94108, :name => {:age => 24}})
|
451
507
|
# @collection.save({:zip => 10010, :name => {:age => 27}})
|
@@ -457,10 +513,12 @@ EOS
|
|
457
513
|
# @collection.distinct("name.age")
|
458
514
|
# [27, 24]
|
459
515
|
#
|
460
|
-
# You may also pass a document selector as the second parameter
|
461
|
-
# to limit the documents over which distinct is run:
|
516
|
+
# # You may also pass a document selector as the second parameter
|
517
|
+
# # to limit the documents over which distinct is run:
|
462
518
|
# @collection.distinct("name.age", {"name.age" => {"$gt" => 24}})
|
463
519
|
# [27]
|
520
|
+
#
|
521
|
+
# @return [Array] an array of distinct values.
|
464
522
|
def distinct(key, query=nil)
|
465
523
|
raise MongoArgumentError unless [String, Symbol].include?(key.class)
|
466
524
|
command = OrderedHash.new
|
@@ -473,11 +531,12 @@ EOS
|
|
473
531
|
|
474
532
|
# Rename this collection.
|
475
533
|
#
|
476
|
-
# If operating in auth mode, client must be authorized as an admin to
|
477
|
-
# perform this operation.
|
478
|
-
#
|
534
|
+
# Note: If operating in auth mode, the client must be authorized as an admin to
|
535
|
+
# perform this operation.
|
536
|
+
#
|
537
|
+
# @param [String ] new_name the new name for this collection
|
479
538
|
#
|
480
|
-
#
|
539
|
+
# @raise [InvalidName] if +new_name+ is an invalid collection name.
|
481
540
|
def rename(new_name)
|
482
541
|
case new_name
|
483
542
|
when Symbol, String
|
@@ -500,23 +559,25 @@ EOS
|
|
500
559
|
@db.rename_collection(@name, new_name)
|
501
560
|
end
|
502
561
|
|
503
|
-
# Get information on the indexes for
|
504
|
-
#
|
505
|
-
#
|
506
|
-
# pairs specifying the index (as passed to Collection#create_index).
|
562
|
+
# Get information on the indexes for this collection.
|
563
|
+
#
|
564
|
+
# @return [Hash] a hash where the keys are index names.
|
507
565
|
def index_information
|
508
566
|
@db.index_information(@name)
|
509
567
|
end
|
510
568
|
|
511
569
|
# Return a hash containing options that apply to this collection.
|
512
|
-
#
|
513
|
-
#
|
570
|
+
# For all possible keys and values, see DB#create_collection.
|
571
|
+
#
|
572
|
+
# @return [Hash] options that apply to this collection.
|
514
573
|
def options
|
515
574
|
@db.collections_info(@name).next_document['options']
|
516
575
|
end
|
517
576
|
|
518
577
|
# Get the number of documents in this collection.
|
519
|
-
|
578
|
+
#
|
579
|
+
# @return [Integer]
|
580
|
+
def count
|
520
581
|
find().count()
|
521
582
|
end
|
522
583
|
|
@@ -545,10 +606,10 @@ EOS
|
|
545
606
|
# Takes an array of +documents+, an optional +collection_name+, and a
|
546
607
|
# +check_keys+ setting.
|
547
608
|
def insert_documents(documents, collection_name=@name, check_keys=true, safe=false)
|
548
|
-
|
549
|
-
message.
|
609
|
+
# Initial byte is 0.
|
610
|
+
message = ByteBuffer.new([0, 0, 0, 0])
|
550
611
|
BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{collection_name}")
|
551
|
-
documents.each { |doc| message.put_array(BSON.serialize(doc, check_keys).
|
612
|
+
documents.each { |doc| message.put_array(BSON.serialize(doc, check_keys).to_a) }
|
552
613
|
if safe
|
553
614
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name,
|
554
615
|
"db.#{collection_name}.insert(#{documents.inspect})")
|