Class: Mongoid::Contextual::Mongo

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable, Association::EagerLoadable, Atomic, Aggregable::Mongo, Queryable
Defined in:
build/mongoid-master/lib/mongoid/contextual/mongo.rb

Constant Summary collapse

OPTIONS =

Options constant.

Since:

  • 5.0.0

[ :hint,
  :limit,
  :skip,
  :sort,
  :batch_size,
  :max_scan,
  :max_time_ms,
  :snapshot,
  :comment,
  :read,
  :cursor_type,
  :collation
].freeze

Constants included from Atomic

Atomic::UPDATES

Instance Attribute Summary collapse

Attributes included from Queryable

#collection, #collection The collection to query against., #criteria, #criteria The criteria for the context., #klass, #klass The klass for the criteria.

Instance Method Summary collapse

Methods included from Queryable

#blank?

Methods included from Association::EagerLoadable

#eager_load, #eager_loadable?, #preload

Methods included from Atomic

#add_atomic_pull, #add_atomic_unset, #atomic_array_add_to_sets, #atomic_array_pulls, #atomic_array_pushes, #atomic_attribute_name, #atomic_delete_modifier, #atomic_insert_modifier, #atomic_path, #atomic_paths, #atomic_position, #atomic_pulls, #atomic_pushes, #atomic_sets, #atomic_unsets, #atomic_updates, #delayed_atomic_pulls, #delayed_atomic_sets, #delayed_atomic_unsets, #flag_as_destroyed, #flagged_destroys, #process_flagged_destroys

Methods included from Aggregable::Mongo

#aggregates, #avg, #max, #min, #sum

Constructor Details

#initialize(criteria) ⇒ Mongo

Create the new Mongo context. This delegates operations to the underlying driver.

Examples:

Create the new context.

Mongo.new(criteria)

Parameters:

Since:

  • 3.0.0



364
365
366
367
368
369
370
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 364

def initialize(criteria)
  @criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
  @collection = @klass.collection
  criteria.send(:merge_type_selection)
  @view = collection.find(criteria.selector, session: _session)
  apply_options
end

Instance Attribute Details

#viewObject (readonly)

Returns the value of attribute view.



39
40
41
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 39

def view
  @view
end

#view The Mongo collection view.(TheMongocollectionview.) ⇒ Object (readonly)



39
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 39

attr_reader :view

Instance Method Details

#cached?true, false

Is the context cached?

Examples:

Is the context cached?

context.cached?

Returns:

  • (true, false)

    If the context is cached.

Since:

  • 3.0.0



49
50
51
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 49

def cached?
  !!@cache
end

#count(options = {}, &block) ⇒ Integer

Get the number of documents matching the query.

Examples:

Get the number of matching documents.

context.count

Get the count of documents with the provided options.

context.count(limit: 1)

Get the count for where the provided block is true.

context.count do |doc|
  doc.likes > 1
end

Parameters:

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

    The options, such as skip and limit to be factored into the count.

Returns:

  • (Integer)

    The number of matches.

Since:

  • 3.0.0



72
73
74
75
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 72

def count(options = {}, &block)
  return super(&block) if block_given?
  try_cache(:count) { view.count_documents(options) }
end

#deletenil Also known as: delete_all

Delete all documents in the database that match the selector.

Examples:

Delete all the documents.

context.delete

Returns:

  • (nil)

    Nil.

Since:

  • 3.0.0



104
105
106
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 104

def delete
  view.delete_many.deleted_count
end

#destroynil Also known as: destroy_all

Destroy all documents in the database that match the selector.

Examples:

Destroy all the documents.

context.destroy

Returns:

  • (nil)

    Nil.

Since:

  • 3.0.0



117
118
119
120
121
122
123
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 117

def destroy
  each.inject(0) do |count, doc|
    doc.destroy
    count += 1 if acknowledged_write?
    count
  end
end

#distinct(field) ⇒ Array<Object>

Get the distinct values in the db for the provided field.

Examples:

Get the distinct values.

context.distinct(:name)

Parameters:

  • field (String, Symbol)

    The name of the field.

Returns:

  • (Array<Object>)

    The distinct values for the field.

Since:

  • 3.0.0



136
137
138
139
140
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 136

def distinct(field)
  view.distinct(klass.database_field_name(field)).map do |value|
    value.class.demongoize(value)
  end
end

#each(&block) ⇒ Enumerator

Iterate over the context. If provided a block, yield to a Mongoid document for each, otherwise return an enum.

Examples:

Iterate over the context.

context.each do |doc|
  puts doc.name
end

Returns:

  • (Enumerator)

    The enumerator.

Since:

  • 3.0.0



153
154
155
156
157
158
159
160
161
162
163
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 153

def each(&block)
  if block_given?
    documents_for_iteration.each do |doc|
      yield_document(doc, &block)
    end
    @cache_loaded = true
    self
  else
    to_enum
  end
end

#estimated_count(options = {}) ⇒ Integer

Get the estimated number of documents matching the query.

Unlike count, estimated_count does not take a block because it is not traditionally defined (with a block) on Enumarable like count is.

Examples:

Get the estimated number of matching documents.

context.estimated_count

Parameters:

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

    The options, such as maxTimeMS to be factored into the count.

Returns:

  • (Integer)

    The number of matches.



89
90
91
92
93
94
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 89

def estimated_count(options = {})
  unless self.criteria.selector.empty?
    raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
  end
  try_cache(:estimated_count) { view.estimated_document_count(options) }
end

#exists?true, false

Note:

We don't use count here since Mongo does not use counted b-tree indexes, unless a count is already cached then that is used to determine the value.

Do any documents exist for the context.

Examples:

Do any documents exist for the context.

context.exists?

Returns:

  • (true, false)

    If the count is more than zero.

Since:

  • 3.0.0



177
178
179
180
181
182
183
184
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 177

def exists?
  return !documents.empty? if cached? && cache_loaded?
  return @count > 0 if instance_variable_defined?(:@count)

  try_cache(:exists) do
    !!(view.projection(_id: 1).limit(1).first)
  end
end

#explainHash

Run an explain on the criteria.

Examples:

Explain the criteria.

Band.where(name: "Depeche Mode").explain

Returns:

  • (Hash)

    The explain result.

Since:

  • 3.0.0



194
195
196
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 194

def explain
  view.explain
end

#find_firstObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the first result without applying sort

Since:

  • 4.0.2



299
300
301
302
303
304
305
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 299

def find_first
  return documents.first if cached? && cache_loaded?
  if raw_doc = view.first
    doc = Factory.from_db(klass, raw_doc, criteria)
    eager_load([doc]).first
  end
end

#find_one_and_deleteDocument

Execute the find and modify command, used for MongoDB's $findAndModify. This deletes the found document.

Examples:

Execute the command.

context.find_one_and_delete

Returns:

  • (Document)

    The result of the command.

Since:

  • 5.0.0



251
252
253
254
255
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 251

def find_one_and_delete
  if doc = view.find_one_and_delete
    Factory.from_db(klass, doc)
  end
end

#find_one_and_replace(replacement, options = {}) ⇒ Document

Execute the find and modify command, used for MongoDB's $findAndModify.

Examples:

Execute the command.

context.find_one_and_update({ likes: 1 })

Parameters:

  • replacement (Hash)

    The replacement.

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

    The command options.

Options Hash (options):

  • :return_document (:before, :after)

    Return the updated document from before or after update.

  • :upsert (true, false)

    Create the document if it doesn't exist.

Returns:

  • (Document)

    The result of the command.

Since:

  • 5.0.0



236
237
238
239
240
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 236

def find_one_and_replace(replacement, options = {})
  if doc = view.find_one_and_replace(replacement, options)
    Factory.from_db(klass, doc)
  end
end

#find_one_and_update(update, options = {}) ⇒ Document

Execute the find and modify command, used for MongoDB's $findAndModify.

Examples:

Execute the command.

context.find_one_and_update({ "$inc" => { likes: 1 }})

Parameters:

  • update (Hash)

    The updates.

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

    The command options.

Options Hash (options):

  • :return_document (:before, :after)

    Return the updated document from before or after update.

  • :upsert (true, false)

    Create the document if it doesn't exist.

Returns:

  • (Document)

    The result of the command.

Since:

  • 5.0.0



214
215
216
217
218
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 214

def find_one_and_update(update, options = {})
  if doc = view.find_one_and_update(update, options)
    Factory.from_db(klass, doc)
  end
end

#first(opts = {}) ⇒ Document Also known as: one

Note:

Automatically adding a sort on _id when no other sort is defined on the criteria has the potential to cause bad performance issues. If you experience unexpected poor performance when using #first or #last and have no sort defined on the criteria, use the option { id_sort: :none }. Be aware that #first/#last won't guarantee order in this case.

Get the first document in the database for the criteria's selector.

Examples:

Get the first document.

context.first

Parameters:

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

    The options for the query returning the first document.

Options Hash (opts):

  • :id_sort (:none)

    Don't apply a sort on _id if no other sort is defined on the criteria.

Returns:

Since:

  • 3.0.0



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 276

def first(opts = {})
  return documents.first if cached? && cache_loaded?
  try_cache(:first) do
    if sort = view.sort || ({ _id: 1 } unless opts[:id_sort] == :none)
      if raw_doc = view.sort(sort).limit(1).first
        doc = Factory.from_db(klass, raw_doc, criteria)
        eager_load([doc]).first
      end
    else
      if raw_doc = view.limit(1).first
        doc = Factory.from_db(klass, raw_doc, criteria)
        eager_load([doc]).first
      end
    end
  end
end

#geo_near(coordinates) ⇒ GeoNear

Deprecated.

Execute a $geoNear command against the database.

Examples:

Find documents close to 10, 10.

context.geo_near([ 10, 10 ])

Find with spherical distance.

context.geo_near([ 10, 10 ]).spherical

Find with a max distance.

context.geo_near([ 10, 10 ]).max_distance(0.5)

Provide a distance multiplier.

context.geo_near([ 10, 10 ]).distance_multiplier(1133)

Parameters:

  • coordinates (Array<Float>)

    The coordinates.

Returns:

  • (GeoNear)

    The GeoNear command.

Since:

  • 3.1.0



328
329
330
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 328

def geo_near(coordinates)
  GeoNear.new(collection, criteria, coordinates)
end

#last(opts = {}) ⇒ Object

Note:

Automatically adding a sort on _id when no other sort is defined on the criteria has the potential to cause bad performance issues. If you experience unexpected poor performance when using #first or #last and have no sort defined on the criteria, use the option { id_sort: :none }. Be aware that #first/#last won't guarantee order in this case.

Get the last document in the database for the criteria's selector.

Examples:

Get the last document.

context.last

Parameters:

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

    The options for the query returning the first document.

Options Hash (opts):

  • :id_sort (:none)

    Don't apply a sort on _id if no other sort is defined on the criteria.

Since:

  • 3.0.0



391
392
393
394
395
396
397
398
399
400
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 391

def last(opts = {})
  try_cache(:last) do
    with_inverse_sorting(opts) do
      if raw_doc = view.limit(1).first
        doc = Factory.from_db(klass, raw_doc, criteria)
        eager_load([doc]).first
      end
    end
  end
end

#lengthInteger Also known as: size

Get's the number of documents matching the query selector.

Examples:

Get the length.

context.length

Returns:

  • (Integer)

    The number of documents.

Since:

  • 3.0.0



410
411
412
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 410

def length
  @length ||= self.count
end

#limit(value) ⇒ Mongo

Limits the number of documents that are returned from the database.

Examples:

Limit the documents.

context.limit(20)

Parameters:

  • value (Integer)

    The number of documents to return.

Returns:

  • (Mongo)

    The context.

Since:

  • 3.0.0



425
426
427
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 425

def limit(value)
  @view = view.limit(value) and self
end

#map(field = nil, &block) ⇒ Array

Invoke the block for each element of Contextual. Create a new array containing the values returned by the block.

If the symbol field name is passed instead of the block, additional optimizations would be used.

Examples:

Map by some field.

context.map(:field1)

Map with block.

context.map(&:field1)

Parameters:

  • field (Symbol) (defaults to: nil)

    The field name.

Returns:

  • (Array)

    The result of mapping.



347
348
349
350
351
352
353
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 347

def map(field = nil, &block)
  if block_given?
    super(&block)
  else
    criteria.pluck(field)
  end
end

#map_reduce(map, reduce) ⇒ MapReduce

Initiate a map/reduce operation from the context.

Examples:

Initiate a map/reduce.

context.map_reduce(map, reduce)

Parameters:

  • map (String)

    The map js function.

  • reduce (String)

    The reduce js function.

Returns:

  • (MapReduce)

    The map/reduce lazy wrapper.

Since:

  • 3.0.0



440
441
442
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 440

def map_reduce(map, reduce)
  MapReduce.new(collection, criteria, map, reduce)
end

#pluck(*fields) ⇒ Array<Object, Array>

Note:

This method will return the raw db values - it performs no custom serialization.

Pluck the single field values from the database. Will return duplicates if they exist and only works for top level fields.

Examples:

Pluck a field.

context.pluck(:_id)

Parameters:

  • fields (String, Symbol, Array)

    Fields to pluck.

Returns:

  • (Array<Object, Array>)

    The plucked values.

Since:

  • 3.1.0



458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 458

def pluck(*fields)
  normalized_select = fields.inject({}) do |hash, f|
    hash[klass.database_field_name(f)] = 1
    hash
  end

  view.projection(normalized_select).reduce([]) do |plucked, doc|
    values = normalized_select.keys.map do |n|
      n =~ /\./ ? doc[n.partition('.')[0]] : doc[n]
    end
    plucked << (values.size == 1 ? values.first : values)
  end
end

#skip(value) ⇒ Mongo

Skips the provided number of documents.

Examples:

Skip the documents.

context.skip(20)

Parameters:

  • value (Integer)

    The number of documents to skip.

Returns:

  • (Mongo)

    The context.

Since:

  • 3.0.0



482
483
484
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 482

def skip(value)
  @view = view.skip(value) and self
end

#sort(values = nil, &block) ⇒ Mongo

Sorts the documents by the provided spec.

Examples:

Sort the documents.

context.sort(name: -1, title: 1)

Parameters:

  • values (Hash) (defaults to: nil)

    The sorting values as field/direction(1/-1) pairs.

Returns:

  • (Mongo)

    The context.

Since:

  • 3.0.0



497
498
499
500
501
502
503
504
505
506
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 497

def sort(values = nil, &block)
  if block_given?
    super(&block)
  else
    # update the criteria
    @criteria = criteria.order_by(values)
    apply_option(:sort)
    self
  end
end

#update(attributes = nil, opts = {}) ⇒ nil, false

Update the first matching document atomically.

Examples:

Update the first matching document.

context.update({ "$set" => { name: "Smiths" }})

Parameters:

  • attributes (Hash) (defaults to: nil)

    The new attributes for the document.

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

    The update operation options.

Options Hash (opts):

  • :array_filters (Array)

    A set of filters specifying to which array elements an update should apply.

Returns:

  • (nil, false)

    False if no attributes were provided.

Since:

  • 3.0.0



522
523
524
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 522

def update(attributes = nil, opts = {})
  update_documents(attributes, :update_one, opts)
end

#update_all(attributes = nil, opts = {}) ⇒ nil, false

Update all the matching documents atomically.

Examples:

Update all the matching documents.

context.update_all({ "$set" => { name: "Smiths" }})

Parameters:

  • attributes (Hash) (defaults to: nil)

    The new attributes for each document.

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

    The update operation options.

Options Hash (opts):

  • :array_filters (Array)

    A set of filters specifying to which array elements an update should apply.

Returns:

  • (nil, false)

    False if no attributes were provided.

Since:

  • 3.0.0



540
541
542
# File 'build/mongoid-master/lib/mongoid/contextual/mongo.rb', line 540

def update_all(attributes = nil, opts = {})
  update_documents(attributes, :update_many, opts)
end