Class: Mongo::Collection

Inherits:
Object show all
Defined in:
lib/mongo/collection.rb

Overview

A named collection of documents in a database.

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Collection) initialize(db, name, options = {})

Initialize a collection object.

Parameters:

  • (DB) db

    a MongoDB database instance.

  • (String, Symbol) name

    the name of the collection.

  • (Hash) options (defaults to: {})

    a customizable set of options

Options Hash (options):

  • (:create_pk) :pk — default: BSON::ObjectId

    A primary key factory to use other than the default BSON::ObjectId.

  • (Boolean, Hash) :safe — default: false

    Set the default safe-mode options for insert, update, and remove method called on this Collection instance. If no value is provided, the default value set on this instance’s DB will be used. This default can be overridden for any invocation of insert, update, or remove.

Raises:

  • (InvalidNSName)

    if collection name is empty, contains ’$’, or starts or ends with ’.’

  • (TypeError)

    if collection name is not a string or symbol

Core docs:



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/mongo/collection.rb', line 47

def initialize(db, name, options={})
  case name
  when Symbol, String
  else
    raise TypeError, "new_name must be a string or symbol"
  end

  name = name.to_s

  if name.empty? or name.include? ".."
    raise Mongo::InvalidNSName, "collection names cannot be empty"
  end
  if name.include? "$"
    raise Mongo::InvalidNSName, "collection names must not contain '$'" unless name =~ /((^\$cmd)|(oplog\.\$main))/
  end
  if name.match(/^\./) or name.match(/\.$/)
    raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
  end

  if options.respond_to?(:create_pk) || !options.is_a?(Hash)
    warn "The method for specifying a primary key factory on a Collection has changed.\n" +
      "Please specify it as an option (e.g., :pk => PkFactory)."
    pk_factory = options
  else
    pk_factory = nil
  end

  @db, @name  = db, name
  @connection = @db.connection
  @logger     = @connection.logger
  unless pk_factory
    @safe       = options.has_key?(:safe) ? options[:safe] : @db.safe
  end
  @pk_factory = pk_factory || options[:pk] || BSON::ObjectId
  @hint = nil
end

Instance Attribute Details

- (Object) db (readonly)

Returns the value of attribute db



23
24
25
# File 'lib/mongo/collection.rb', line 23

def db
  @db
end

- (Object) hint

Returns the value of attribute hint



23
24
25
# File 'lib/mongo/collection.rb', line 23

def hint
  @hint
end

- (Object) name (readonly)

Returns the value of attribute name



23
24
25
# File 'lib/mongo/collection.rb', line 23

def name
  @name
end

- (Object) pk_factory (readonly)

Returns the value of attribute pk_factory



23
24
25
# File 'lib/mongo/collection.rb', line 23

def pk_factory
  @pk_factory
end

- (Object) safe (readonly)

Returns the value of attribute safe



23
24
25
# File 'lib/mongo/collection.rb', line 23

def safe
  @safe
end

Instance Method Details

- (Collection) [](name)

Return a sub-collection of this collection by name. If ‘users’ is a collection, then ‘users.comments’ is a sub-collection of users.

Parameters:

  • (String) name

    the collection to return

Returns:

Raises:



95
96
97
98
99
# File 'lib/mongo/collection.rb', line 95

def [](name)
  name = "#{self.name}.#{name}"
  return Collection.new(db, name) if !db.strict? || db.collection_names.include?(name)
  raise "Collection #{name} doesn't exist. Currently in strict mode."
end

- (Integer) count Also known as: size

Get the number of documents in this collection.

Returns:

  • (Integer)


687
688
689
# File 'lib/mongo/collection.rb', line 687

def count
  find().count()
end

- (String) create_index(spec, opts = {})

Create a new index.

Examples:

Creating a compound index:

@posts.create_index([['subject', Mongo::ASCENDING], ['created_at', Mongo::DESCENDING]])

Creating a geospatial index:

@restaurants.create_index([['location', Mongo::GEO2D]])

# Note that this will work only if 'location' represents x,y coordinates:
{'location': [0, 50]}
{'location': {'x' => 0, 'y' => 50}}
{'location': {'latitude' => 0, 'longitude' => 50}}

A geospatial index with alternate longitude and latitude:

@restaurants.create_index([['location', Mongo::GEO2D]], :min => 500, :max => 500)

Parameters:

  • (String, Array) spec

    should be either a single field name or an array of

    field name, direction
    pairs. Directions should be specified

    as Mongo::ASCENDING, Mongo::DESCENDING, or Mongo::GEO2D.

    Note that geospatial indexing only works with versions of MongoDB >= 1.3.3+. Keep in mind, too, that in order to geo-index a given field, that field must reference either an array or a sub-object where the first two values represent x- and y-coordinates. Examples can be seen below.

    Also note that it is permissible to create compound indexes that include a geospatial index as long as the geospatial index comes first.

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Boolean) :unique — default: false

    if true, this index will enforce a uniqueness constraint.

  • (Boolean) :background — default: false

    indicate that the index should be built in the background. This feature is only available in MongoDB >= 1.3.2.

  • (Boolean) :drop_dups — default: nil

    If creating a unique index on a collection with pre-existing records, this option will keep the first document the database indexes and drop all subsequent with duplicate values.

  • (Integer) :min — default: nil

    specify the minimum longitude and latitude for a geo index.

  • (Integer) :max — default: nil

    specify the maximum longitude and latitude for a geo index.

Returns:

  • (String)

    the name of the index created.

Core docs:



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/mongo/collection.rb', line 408

def create_index(spec, opts={})
  opts[:dropDups] = opts.delete(:drop_dups) if opts[:drop_dups]
  field_spec = BSON::OrderedHash.new
  if spec.is_a?(String) || spec.is_a?(Symbol)
    field_spec[spec.to_s] = 1
  elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
    spec.each do |f|
      if [Mongo::ASCENDING, Mongo::DESCENDING, Mongo::GEO2D].include?(f[1])
        field_spec[f[0].to_s] = f[1]
      else
        raise MongoArgumentError, "Invalid index field #{f[1].inspect}; " + 
          "should be one of Mongo::ASCENDING (1), Mongo::DESCENDING (-1) or Mongo::GEO2D ('2d')."
      end
    end
  else
    raise MongoArgumentError, "Invalid index specification #{spec.inspect}; " + 
      "should be either a string, symbol, or an array of arrays."
  end

  name = opts.delete(:name) || generate_index_name(field_spec)

  selector = {
    :name   => name,
    :ns     => "#{@db.name}.#{@name}",
    :key    => field_spec
  }
  selector.merge!(opts)

  insert_documents([selector], Mongo::DB::SYSTEM_INDEX_COLLECTION, false, false)
  response = @db.get_last_error

  if response['err']
    if response['code'] == 11000 && selector[:dropDups]
      # NOP. If the user is intentionally dropping dups, we can ignore duplicate key errors.
    else
      raise Mongo::OperationFailure, "Failed to create index #{selector.inspect} with the following error: " +
       "#{response['err']}"
    end
  end
  name
end

- (Array) distinct(key, query = nil)

Return a list of distinct values for key across all documents in the collection. The key may use dot notation to reach into an embedded object.

Examples:

Saving zip codes and ages and returning distinct results.

@collection.save({:zip => 10010, :name => {:age => 27}})
@collection.save({:zip => 94108, :name => {:age => 24}})
@collection.save({:zip => 10010, :name => {:age => 27}})
@collection.save({:zip => 99701, :name => {:age => 24}})
@collection.save({:zip => 94108, :name => {:age => 27}})

@collection.distinct(:zip)
  [10010, 94108, 99701]
@collection.distinct("name.age")
  [27, 24]

# You may also pass a document selector as the second parameter
# to limit the documents over which distinct is run:
@collection.distinct("name.age", {"name.age" => {"$gt" => 24}})
  [27]

Parameters:

  • (String, Symbol, OrderedHash) key

    or hash to group by.

  • (Hash) query (defaults to: nil)

    a selector for limiting the result set over which to group.

Returns:

  • (Array)

    an array of distinct values.

Raises:



620
621
622
623
624
625
626
627
628
# File 'lib/mongo/collection.rb', line 620

def distinct(key, query=nil)
  raise MongoArgumentError unless [String, Symbol].include?(key.class)
  command = BSON::OrderedHash.new
  command[:distinct] = @name
  command[:key]      = key.to_s
  command[:query]    = query

  @db.command(command)["values"]
end

- (Object) drop

Drop the entire collection. USE WITH CAUTION.



469
470
471
# File 'lib/mongo/collection.rb', line 469

def drop
  @db.drop_collection(@name)
end

- (Object) drop_index(name)

Drop a specified index.

Parameters:

  • (String) name

Core docs:



455
456
457
# File 'lib/mongo/collection.rb', line 455

def drop_index(name)
  @db.drop_index(@name, name)
end

- (Object) drop_indexes

Drop all indexes.

Core docs:



462
463
464
465
466
# File 'lib/mongo/collection.rb', line 462

def drop_indexes

  # Note: calling drop_indexes with no args will drop them all.
  @db.drop_index(@name, '*')
end

- (Object) find(selector = {}, opts = {})

Query the database.

The selector argument is a prototype document that all results must match. For example:

  collection.find({"hello" => "world"})

only matches documents that have a key "hello" with value "world". Matches can have other keys *in addition* to "hello".

If given an optional block find will yield a Cursor to that block, close the cursor, and then return nil. This guarantees that partially evaluated cursors will be closed. If given no block find returns a cursor.

Parameters:

  • (Hash) selector (defaults to: {})

    a document specifying elements which must be present for a document to be included in the result set. Note that in rare cases, (e.g., with $near queries), the order of keys will matter. To preserve key order on a selector, use an instance of BSON::OrderedHash (only applies to Ruby 1.8).

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Array, Hash) :fields

    field names that should be returned in the result set ("_id" will always be included). By limiting results to a certain subset of fields, you can cut down on network traffic and decoding time. If using a Hash, keys should be field names and values should be either 1 or 0, depending on whether you want to include or exclude the given field.

  • (Integer) :skip

    number of documents to skip from the beginning of the result set

  • (Integer) :limit

    maximum number of documents to return

  • (Array) :sort

    an array of [key, direction] pairs to sort by. Direction should be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)

  • (String, Array, OrderedHash) :hint

    hint for query optimizer, usually not necessary if using MongoDB > 1.1

  • (Boolean) :snapshot — default: false

    if true, snapshot mode will be used for this query. Snapshot mode assures no duplicates are returned, or objects missed, which were preset at both the start and end of the query’s execution. For details see http://www.mongodb.org/display/DOCS/How+to+do+Snapshotting+in+the+Mongo+Database

  • (Boolean) :batch_size — default: 100

    the number of documents to returned by the database per GETMORE operation. A value of 0 will let the database server decide how many results to returns. This option can be ignored for most use cases.

  • (Boolean) :timeout — default: true

    when true, the returned cursor will be subject to the normal cursor timeout behavior of the mongod process. When false, the returned cursor will never timeout. Note that disabling timeout will only work when #find is invoked with a block. This is to prevent any inadvertant failure to close the cursor, as the cursor is explicitly closed when block code finishes.

Raises:

  • (ArgumentError)

    if timeout is set to false and find is not invoked in a block

  • (RuntimeError)

    if given unknown options

Core docs:



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/mongo/collection.rb', line 161

def find(selector={}, opts={})
  fields = opts.delete(:fields)
  fields = ["_id"] if fields && fields.empty?
  skip   = opts.delete(:skip) || skip || 0
  limit  = opts.delete(:limit) || 0
  sort   = opts.delete(:sort)
  hint   = opts.delete(:hint)
  snapshot   = opts.delete(:snapshot)
  batch_size = opts.delete(:batch_size)
  timeout    = (opts.delete(:timeout) == false) ? false : true

  if timeout == false && !block_given?
    raise ArgumentError, "Collection#find must be invoked with a block when timeout is disabled."
  end

  if hint
    hint = normalize_hint_fields(hint)
  else
    hint = @hint        # assumed to be normalized already
  end

  raise RuntimeError, "Unknown options [#{opts.inspect}]" unless opts.empty?

  cursor = Cursor.new(self, :selector => selector, :fields => fields, :skip => skip, :limit => limit,
    :order => sort, :hint => hint, :snapshot => snapshot, :timeout => timeout, :batch_size => batch_size)

  if block_given?
    yield cursor
    cursor.close
    nil
  else
    cursor
  end
end

- (Hash) find_and_modify(opts = {})

Atomically update and return a document using MongoDB’s findAndModify command. (MongoDB > 1.3.0)

Parameters:

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Hash) :query — default: {}

    a query selector document for matching the desired document.

  • (Hash) :update — default: nil

    the update operation to perform on the matched document.

  • (Array, String, OrderedHash) :sort — default: {}

    specify a sort option for the query using any of the sort options available for Cursor#sort. Sort order is important if the query will be matching multiple documents since only the first matching document will be updated and returned.

  • (Boolean) :remove — default: false

    If true, removes the the returned document from the collection.

  • (Boolean) :new — default: false

    If true, returns the updated document; otherwise, returns the document prior to update.

Returns:

  • (Hash)

    the matched document.

Core docs:



488
489
490
491
492
493
494
495
# File 'lib/mongo/collection.rb', line 488

def find_and_modify(opts={})
  cmd = BSON::OrderedHash.new
  cmd[:findandmodify] = @name
  cmd.merge!(opts)
  cmd[:sort] = Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]

  @db.command(cmd)['value']
end

- (OrderedHash, Nil) find_one(spec_or_object_id = nil, opts = {})

Return a single object from the database.

Parameters:

  • (Hash, ObjectId, Nil) spec_or_object_id (defaults to: nil)

    a hash specifying elements which must be present for a document to be included in the result set or an instance of ObjectId to be used as the value for an _id query. If nil, an empty selector, {}, will be used.

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Hash) any

    valid options that can be send to Collection#find

Returns:

  • (OrderedHash, Nil)

    a single document or nil if no result is found.

Raises:

  • (TypeError)

    if the argument is of an improper type.



211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/mongo/collection.rb', line 211

def find_one(spec_or_object_id=nil, opts={})
  spec = case spec_or_object_id
         when nil
           {}
         when BSON::ObjectId
           {:_id => spec_or_object_id}
         when Hash
           spec_or_object_id
         else
           raise TypeError, "spec_or_object_id must be an instance of ObjectId or Hash, or nil"
         end
  find(spec, opts.merge(:limit => -1)).next_document
end

- (Array) group(key, condition, initial, reduce, finalize = nil)

Perform a group aggregation.

Parameters:

  • (Array, String, BSON::Code, Nil) :key

    either 1) an array of fields to group by, 2) a javascript function to generate the key object, or 3) nil.

  • (Hash) condition

    an optional document specifying a query to limit the documents over which group is run.

  • (Hash) initial

    initial value of the aggregation counter object

  • (String, BSON::Code) reduce

    aggregation function, in JavaScript

  • (String, BSON::Code) finalize (defaults to: nil)

    :: optional. a JavaScript function that receives and modifies each of the resultant grouped objects. Available only when group is run with command set to true.

Returns:

  • (Array)

    the grouped items.



556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
# File 'lib/mongo/collection.rb', line 556

def group(key, condition, initial, reduce, finalize=nil)
  reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)

  group_command = {
    "group" => {
      "ns"      => @name,
      "$reduce" => reduce,
      "cond"    => condition,
      "initial" => initial
    }
  }

  unless key.nil?
    if key.is_a? Array
      key_type = "key"
      key_value = {}
      key.each { |k| key_value[k] = 1 }
    else
      key_type  = "$keyf"
      key_value = key.is_a?(BSON::Code) ? key : BSON::Code.new(key)
    end

    group_command["group"][key_type] = key_value
  end

  finalize = BSON::Code.new(finalize) if finalize.is_a?(String)
  if finalize.is_a?(BSON::Code)
    group_command['group']['finalize'] = finalize
  end

  result = @db.command(group_command)

  if Mongo::Support.ok?(result)
    result["retval"]
  else
    raise OperationFailure, "group command failed: #{result['errmsg']}"
  end
end

- (Hash) index_information

Get information on the indexes for this collection.

Returns:

  • (Hash)

    a hash where the keys are index names.

Core docs:



665
666
667
# File 'lib/mongo/collection.rb', line 665

def index_information
  @db.index_information(@name)
end

- (ObjectId, Array) insert(doc_or_docs, options = {}) Also known as: <<

Insert one or more documents into the collection.

Parameters:

  • (Hash, Array) doc_or_docs

    a document (as a hash) or array of documents to be inserted.

  • (Hash) opts

    a customizable set of options

Returns:

  • (ObjectId, Array)

    the _id of the inserted document or a list of _ids of all inserted documents. Note: the object may have been modified by the database’s PK factory, if it has one.

See Also:

  • for options that can be passed to :safe.

Core docs:



273
274
275
276
277
278
279
# File 'lib/mongo/collection.rb', line 273

def insert(doc_or_docs, options={})
  doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
  doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
  safe = options.has_key?(:safe) ? options[:safe] : @safe
  result = insert_documents(doc_or_docs, @name, true, safe)
  result.size > 1 ? result : result.first
end

- (Collection) map_reduce(map, reduce, opts = {}) Also known as: mapreduce

Perform a map/reduce operation on the current collection.

Parameters:

  • (String, BSON::Code) map

    a map function, written in JavaScript.

  • (String, BSON::Code) reduce

    a reduce function, written in JavaScript.

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Hash) :query — default: {}

    a query selector document, like what’s passed to #find, to limit the operation to a subset of the collection.

  • (Array) :sort — default: []

    an array of [key, direction] pairs to sort by. Direction should be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)

  • (Integer) :limit — default: nil

    if passing a query, number of objects to return from the collection.

  • (String, BSON::Code) :finalize — default: nil

    a javascript function to apply to the result set after the map/reduce operation has finished.

  • (String) :out — default: nil

    the name of the output collection. If specified, the collection will not be treated as temporary.

  • (Boolean) :keeptemp — default: false

    if true, the generated collection will be persisted. default is false.

  • (Boolean) :verbose — default: false

    if true, provides statistics on job execution time.

  • (Boolean) :raw — default: false

    if true, return the raw result object from the map_reduce command, and not the instantiated collection that’s returned by default.

Returns:

  • (Collection)

    a collection containing the results of the operation.

See Also:

Core docs:



520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
# File 'lib/mongo/collection.rb', line 520

def map_reduce(map, reduce, opts={})
  map    = BSON::Code.new(map) unless map.is_a?(BSON::Code)
  reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
  raw    = opts.delete(:raw)

  hash = BSON::OrderedHash.new
  hash['mapreduce'] = self.name
  hash['map'] = map
  hash['reduce'] = reduce
  hash.merge! opts

  result = @db.command(hash)
  unless Mongo::Support.ok?(result)
    raise Mongo::OperationFailure, "map-reduce failed: #{result['errmsg']}"
  end

  if raw
    result
  else
    @db[result["result"]]
  end
end

- (Hash) options

Return a hash containing options that apply to this collection. For all possible keys and values, see DB#create_collection.

Returns:

  • (Hash)

    options that apply to this collection.



673
674
675
# File 'lib/mongo/collection.rb', line 673

def options
  @db.collections_info(@name).next_document['options']
end

- (True) remove(selector = {}, opts = {})

Remove all documents from this collection.

Examples:

remove all documents from the ‘users’ collection:

users.remove
users.remove({})

remove only documents that have expired:

users.remove({:expire => {"$lte" => Time.now}})

Parameters:

  • (Hash) selector (defaults to: {})

    If specified, only matching documents will be removed.

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Boolean, Hash) :safe — default: +false+

    run the operation in safe mode, which will run a getlasterror command on the database to report any assertion. In addition, a hash can be provided to run an fsync and/or wait for replication of the remove (>= 1.5.1). Safe options provided here will override any safe options set on this collection, its database, or the current connection. See the options for DB#get_last_error for more details.

Returns:

  • (True)

Raises:

See Also:

  • for options that can be passed to :safe.

Core docs:



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/mongo/collection.rb', line 309

def remove(selector={}, opts={})
  # Initial byte is 0.
  safe = opts.has_key?(:safe) ? opts[:safe] : @safe
  message = BSON::ByteBuffer.new("\0\0\0\0")
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
  message.put_int(0)
  message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)

  @logger.debug("MONGODB #{@db.name}['#{@name}'].remove(#{selector.inspect})") if @logger
  if safe
    @connection.send_message_with_safe_check(Mongo::Constants::OP_DELETE, message, @db.name, nil, safe)
    # the return value of send_message_with_safe_check isn't actually meaningful --
    # only the fact that it didn't raise an error is -- so just return true
    true
  else
    @connection.send_message(Mongo::Constants::OP_DELETE, message)
  end
end

- (Object) rename(new_name)

Rename this collection.

Note: If operating in auth mode, the client must be authorized as an admin to perform this operation.

Parameters:

  • (String) new_name

    the new name for this collection

Raises:



638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
# File 'lib/mongo/collection.rb', line 638

def rename(new_name)
  case new_name
  when Symbol, String
  else
    raise TypeError, "new_name must be a string or symbol"
  end

  new_name = new_name.to_s

  if new_name.empty? or new_name.include? ".."
    raise Mongo::InvalidNSName, "collection names cannot be empty"
  end
  if new_name.include? "$"
    raise Mongo::InvalidNSName, "collection names must not contain '$'"
  end
  if new_name.match(/^\./) or new_name.match(/\.$/)
    raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
  end

  @db.rename_collection(@name, new_name)
end

- (ObjectId) save(doc, opts = {})

Save a document to this collection.

Parameters:

  • (Hash) doc

    the document to be saved. If the document already has an ‘_id’ key, then an update (upsert) operation will be performed, and any existing document with that _id is overwritten. Otherwise an insert operation is performed.

  • (Hash) opts (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • (Boolean, Hash) :safe — default: +false+

    run the operation in safe mode, which run a getlasterror command on the database to report any assertion. In addition, a hash can be provided to run an fsync and/or wait for replication of the save (>= 1.5.1). See the options for DB#error.

Returns:

  • (ObjectId)

    the _id of the saved document.

Raises:

See Also:

  • for options that can be passed to :safe.


243
244
245
246
247
248
249
250
251
# File 'lib/mongo/collection.rb', line 243

def save(doc, opts={})
  if doc.has_key?(:_id) || doc.has_key?('_id')
    id = doc[:_id] || doc['_id']
    update({:_id => id}, doc, :upsert => true, :safe => opts[:safe])
    id
  else
    insert(doc, :safe => opts[:safe])
  end
end

- (Hash) stats

Return stats on the collection. Uses MongoDB’s collstats command.

Returns:



680
681
682
# File 'lib/mongo/collection.rb', line 680

def stats
  @db.command({:collstats => @name})
end

- (Object) update(selector, document, options = {})

Update a single document in this collection.

Parameters:

  • (Hash) selector

    a hash specifying elements which must be present for a document to be updated. Note: the update command currently updates only the first document matching the given selector. If you want all matching documents to be updated, be sure to specify :multi => true.

  • (Hash) document

    a hash specifying the fields to be changed in the selected document, or (in the case of an upsert) the document to be inserted

  • (Hash) [Boolean]

    a customizable set of options

  • (Hash) opts

    a customizable set of options

Core docs:



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/mongo/collection.rb', line 350

def update(selector, document, options={})
  # Initial byte is 0.
  safe = options.has_key?(:safe) ? options[:safe] : @safe
  message = BSON::ByteBuffer.new("\0\0\0\0")
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
  update_options  = 0
  update_options += 1 if options[:upsert]
  update_options += 2 if options[:multi]
  message.put_int(update_options)
  message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
  message.put_binary(BSON::BSON_CODER.serialize(document, false, true).to_s)
  @logger.debug("MONGODB #{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})") if @logger
  if safe
    @connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name, nil, safe)
  else
    @connection.send_message(Mongo::Constants::OP_UPDATE, message, nil)
  end
end