class Mongoid::Contextual::Mongo
Context object used for performing bulk query and persistence operations on documents which are persisted in the database and have not been loaded into application memory.
Constants
- OPTIONS
Options constant.
Attributes
@attribute [r] view The Mongo
collection view.
Public Class Methods
Create the new Mongo
context. This delegates operations to the underlying driver.
@example Create the new context.
Mongo.new(criteria)
@param [ Criteria
] criteria The criteria.
# File lib/mongoid/contextual/mongo.rb, line 270 def initialize(criteria) @criteria, @klass = criteria, criteria.klass @collection = @klass.collection criteria.send(:merge_type_selection) @view = collection.find(criteria.selector, session: _session) apply_options end
Public Instance Methods
Get the number of documents matching the query.
@example Get the number of matching documents.
context.count
@example Get the count of documents with the provided options.
context.count(limit: 1)
@example Get the count for where the provided block is true.
context.count do |doc| doc.likes > 1 end
@param [ Hash ] options The options, such as skip and limit to be factored
into the count.
@return [ Integer ] The number of matches.
# File lib/mongoid/contextual/mongo.rb, line 73 def count(options = {}, &block) return super(&block) if block_given? if valid_for_count_documents? view.count_documents(options) else # TODO: Remove this when we remove the deprecated for_js API. # https://jira.mongodb.org/browse/MONGOID-5681 view.count(options) end end
Delete all documents in the database that match the selector.
@example Delete all the documents.
context.delete
@return [ nil ] Nil.
# File lib/mongoid/contextual/mongo.rb, line 114 def delete view.delete_many.deleted_count end
Destroy all documents in the database that match the selector.
@example Destroy all the documents.
context.destroy
@return [ nil ] Nil.
# File lib/mongoid/contextual/mongo.rb, line 125 def destroy each.inject(0) do |count, doc| doc.destroy count += 1 if acknowledged_write? count end end
Get the distinct values in the db for the provided field.
@example Get the distinct values.
context.distinct(:name)
@param [ String | Symbol ] field The name of the field.
@return [ Array<Object> ] The distinct values for the field.
# File lib/mongoid/contextual/mongo.rb, line 142 def distinct(field) name = klass.cleanse_localized_field_names(field) view.distinct(name).map do |value| is_translation = "#{name}_translations" == field.to_s recursive_demongoize(name, value, is_translation) end end
Iterate over the context. If provided a block, yield to a Mongoid
document for each, otherwise return an enum.
@example Iterate over the context.
context.each do |doc| puts doc.name end
@return [ Enumerator ] The enumerator.
# File lib/mongoid/contextual/mongo.rb, line 160 def each(&block) if block_given? documents_for_iteration.each do |doc| yield_document(doc, &block) end self else to_enum end end
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.
@example Get the estimated number of matching documents.
context.estimated_count
@param [ Hash ] options The options, such as maxTimeMS to be factored
into the count.
@return [ Integer ] The number of matches.
# File lib/mongoid/contextual/mongo.rb, line 97 def estimated_count(options = {}) unless self.criteria.selector.empty? if klass.default_scoping? raise Mongoid::Errors::InvalidEstimatedCountScoping.new(self.klass) else raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass) end end view.estimated_document_count(options) end
Do any documents exist for the context.
@example Do any documents exist for the context.
context.exists?
@example Do any documents exist for given _id.
context.exists?(BSON::ObjectId(...))
@example Do any documents exist for given conditions.
context.exists?(name: "...")
@note We don’t use count here since Mongo
does not use counted
b-tree indexes.
@param [ Hash | Object
| false ] id_or_conditions an _id to
search for, a hash of conditions, nil or false.
@return [ true | false ] If the count is more than zero.
Always false if passed nil or false.
# File lib/mongoid/contextual/mongo.rb, line 190 def exists?(id_or_conditions = :none) return false if self.view.limit == 0 case id_or_conditions when :none then !!(view.projection(_id: 1).limit(1).first) when nil, false then false when Hash then Mongo.new(criteria.where(id_or_conditions)).exists? else Mongo.new(criteria.where(_id: id_or_conditions)).exists? end end
Get the fifth document in the database for the criteria’s selector.
@example Get the fifth document.
context.fifth
@return [ Document
| nil ] The fifth document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 699 def fifth retrieve_nth(4) end
Get the fifth document in the database for the criteria’s selector or raise an error if none is found.
@example Get the fifth document.
context.fifth!
@return [ Document
] The fifth document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 713 def fifth! fifth || raise_document_not_found_error end
Return the first result without applying sort
@api private
# File lib/mongoid/contextual/mongo.rb, line 256 def find_first if raw_doc = view.first doc = Factory.from_db(klass, raw_doc, criteria) eager_load([doc]).first end end
Execute the find and modify command, used for MongoDB’s $findAndModify. This deletes the found document.
@example Execute the command.
context.find_one_and_delete
@return [ Document
] The result of the command.
# File lib/mongoid/contextual/mongo.rb, line 247 def find_one_and_delete if doc = view.find_one_and_delete Factory.from_db(klass, doc) end end
Execute the find and modify command, used for MongoDB’s $findAndModify.
@example Execute the command.
context.find_one_and_update({ likes: 1 })
@param [ Hash ] replacement The replacement. @param [ Hash ] options The command options.
@option options [ :before | :after ] :return_document Return the updated document
from before or after update.
@option options [ true | false ] :upsert Create the document if it doesn’t exist.
@return [ Document
] The result of the command.
# File lib/mongoid/contextual/mongo.rb, line 234 def find_one_and_replace(replacement, options = {}) if doc = view.find_one_and_replace(replacement, options) Factory.from_db(klass, doc) end end
Execute the find and modify command, used for MongoDB’s $findAndModify.
@example Execute the command.
context.find_one_and_update({ "$inc" => { likes: 1 }})
@param [ Hash ] update The updates. @param [ Hash ] options The command options.
@option options [ :before | :after ] :return_document Return the updated document
from before or after update.
@option options [ true | false ] :upsert Create the document if it doesn’t exist.
@return [ Document
] The result of the command.
# File 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
Get the first document in the database for the criteria’s selector.
@example Get the first document.
context.first
@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 #take instead. Be aware that #take won't guarantee order.
@param [ Integer ] limit The number of documents to return.
@return [ Document
| nil ] The first document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 550 def first(limit = nil) if limit.nil? retrieve_nth(0) else retrieve_nth_with_limit(0, limit) end end
Get the first document in the database for the criteria’s selector or raise an error if none is found.
@example Get the first document.
context.first!
@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 #take! instead. Be aware that #take! won't guarantee order.
@return [ Document
] The first document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 575 def first! first || raise_document_not_found_error end
Get the fourth document in the database for the criteria’s selector.
@example Get the fourth document.
context.fourth
@return [ Document
| nil ] The fourth document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 675 def fourth retrieve_nth(3) end
Get the fourth document in the database for the criteria’s selector or raise an error if none is found.
@example Get the fourth document.
context.fourth!
@return [ Document
] The fourth document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 689 def fourth! fourth || raise_document_not_found_error end
Get the last document in the database for the criteria’s selector.
@example Get the last document.
context.last
@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 #take instead. Be aware that #take won't guarantee order.
@param [ Integer ] limit The number of documents to return.
@return [ Document
| nil ] The last document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 593 def last(limit = nil) if limit.nil? retrieve_nth_to_last(0) else retrieve_nth_to_last_with_limit(0, limit) end end
Get the last document in the database for the criteria’s selector or raise an error if none is found.
@example Get the last document.
context.last!
@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 #take! instead. Be aware that #take! won't guarantee order.
@return [ Document
] The last document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 617 def last! last || raise_document_not_found_error end
Returns the number of documents in the database matching the query selector.
@example Get the length.
context.length
@return [ Integer ] The number of documents.
# File lib/mongoid/contextual/mongo.rb, line 287 def length self.count end
Limits the number of documents that are returned from the database.
@example Limit the documents.
context.limit(20)
@param [ Integer ] value The number of documents to return.
@return [ Mongo
] The context.
# File lib/mongoid/contextual/mongo.rb, line 300 def limit(value) @view = view.limit(value) and self end
Schedule a task to load documents for the context.
Depending on the Mongoid
configuration, the scheduled task can be executed immediately on the caller’s thread, or can be scheduled for an asynchronous execution.
@api private
# File lib/mongoid/contextual/mongo.rb, line 776 def load_async @documents_loader ||= DocumentsLoader.new(view, klass, criteria) end
Initiate a map/reduce operation from the context.
@example Initiate a map/reduce.
context.map_reduce(map, reduce)
@param [ String ] map The map js function. @param [ String ] reduce The reduce js function.
@return [ MapReduce
] The map/reduce lazy wrapper.
# File lib/mongoid/contextual/mongo.rb, line 313 def map_reduce(map, reduce) MapReduce.new(collection, criteria, map, reduce) end
Pick the single field values from the database.
@example Pick a field.
context.pick(:_id)
@param [ [ String | Symbol ]… ] *fields Field(s) to pick.
@return [ Object
| Array<Object> ] The picked values.
# File lib/mongoid/contextual/mongo.rb, line 361 def pick(*fields) limit(1).pluck(*fields).first end
Pluck the field value(s) from the database. Returns one result for each document found in the database for the context. The results are normalized according to their Mongoid
field types. Note that the results may include duplicates and nil values.
@example Pluck a field.
context.pluck(:_id)
@param [ [ String | Symbol ]… ] *fields Field(s) to pluck,
which may include nested fields using dot-notation.
@return [ Array<Object> | Array<Array<Object>> ] The plucked values.
If the *fields arg contains a single value, each result in the array will be a single value. Otherwise, each result in the array will be an array of values.
# File lib/mongoid/contextual/mongo.rb, line 333 def pluck(*fields) # Multiple fields can map to the same field name. For example, plucking # a field and its _translations field map to the same field in the database. # because of this, we need to keep track of the fields requested. normalized_field_names = [] normalized_select = fields.inject({}) do |hash, f| db_fn = klass.database_field_name(f) normalized_field_names.push(db_fn) hash[klass.cleanse_localized_field_names(f)] = true hash end view.projection(normalized_select).reduce([]) do |plucked, doc| values = normalized_field_names.map do |n| extract_value(doc, n) end plucked << (values.size == 1 ? values.first : values) end end
Get the second document in the database for the criteria’s selector.
@example Get the second document.
context.second
@return [ Document
| nil ] The second document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 627 def second retrieve_nth(1) end
Get the second document in the database for the criteria’s selector or raise an error if none is found.
@example Get the second document.
context.second!
@return [ Document
] The second document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 641 def second! second || raise_document_not_found_error end
Get the second to last document in the database for the criteria’s selector.
@example Get the second to last document.
context.second_to_last
@return [ Document
| nil ] The second to last document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 725 def second_to_last retrieve_nth_to_last(1) end
Get the second to last document in the database for the criteria’s selector or raise an error if none is found.
@example Get the second to last document.
context.second_to_last!
@return [ Document
] The second to last document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 739 def second_to_last! second_to_last || raise_document_not_found_error end
Skips the provided number of documents.
@example Skip the documents.
context.skip(20)
@param [ Integer ] value The number of documents to skip.
@return [ Mongo
] The context.
# File lib/mongoid/contextual/mongo.rb, line 480 def skip(value) @view = view.skip(value) and self end
Sorts the documents by the provided spec.
@example Sort the documents.
context.sort(name: -1, title: 1)
@param [ Hash ] values The sorting values as field/direction(1/-1)
pairs.
@return [ Mongo
] The context.
# File lib/mongoid/contextual/mongo.rb, line 493 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
Take the given number of documents from the database.
@example Take 10 documents
context.take(10)
@param [ Integer | nil ] limit The number of documents to return or nil.
@return [ Document
| Array<Document> ] The list of documents, or one
document if no value was given.
# File lib/mongoid/contextual/mongo.rb, line 374 def take(limit = nil) if limit limit(limit).to_a else # Do to_a first so that the Mongo#first method is not used and the # result is not sorted. limit(1).to_a.first end end
Take one document from the database and raise an error if there are none.
@example Take a document
context.take!
@return [ Document
] The document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents to take.
# File lib/mongoid/contextual/mongo.rb, line 393 def take! # Do to_a first so that the Mongo#first method is not used and the # result is not sorted. if fst = limit(1).to_a.first fst else raise Errors::DocumentNotFound.new(klass, nil, nil) end end
Get a hash of counts for the values of a single field. For example, if the following documents were in the database:
{ _id: 1, age: 21 } { _id: 2, age: 21 } { _id: 3, age: 22 } Model.tally("age")
would yield the following result:
{ 21 => 2, 22 => 1 }
When tallying a field inside an array or embeds_many association:
{ _id: 1, array: [ { x: 1 }, { x: 2 } ] } { _id: 2, array: [ { x: 1 }, { x: 2 } ] } { _id: 3, array: [ { x: 1 }, { x: 3 } ] } Model.tally("array.x")
The keys of the resulting hash are arrays:
{ [ 1, 2 ] => 2, [ 1, 3 ] => 1 }
Note that if tallying an element in an array of hashes, and the key doesn’t exist in some of the hashes, tally will not include those nil keys in the resulting hash:
{ _id: 1, array: [ { x: 1 }, { x: 2 }, { y: 3 } ] } Model.tally("array.x") # => { [ 1, 2 ] => 1 }
@param [ String | Symbol ] field The field name.
@return [ Hash ] The hash of counts.
# File lib/mongoid/contextual/mongo.rb, line 440 def tally(field) name = klass.cleanse_localized_field_names(field) fld = klass.traverse_association_tree(name) pipeline = [ { "$group" => { _id: "$#{name}", counts: { "$sum": 1 } } } ] pipeline.unshift("$match" => view.filter) unless view.filter.blank? collection.aggregate(pipeline).reduce({}) do |tallies, doc| is_translation = "#{name}_translations" == field.to_s val = doc["_id"] key = if val.is_a?(Array) val.map do |v| demongoize_with_field(fld, v, is_translation) end else demongoize_with_field(fld, val, is_translation) end # The only time where a key will already exist in the tallies hash # is when the values are stored differently in the database, but # demongoize to the same value. A good example of when this happens # is when using localized fields. While the server query won't group # together hashes that have other values in different languages, the # demongoized value is just the translation in the current locale, # which can be the same across multiple of those unequal hashes. tallies[key] ||= 0 tallies[key] += doc["counts"] tallies end end
Get the third document in the database for the criteria’s selector.
@example Get the third document.
context.third
@return [ Document
| nil ] The third document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 651 def third retrieve_nth(2) end
Get the third document in the database for the criteria’s selector or raise an error if none is found.
@example Get the third document.
context.third!
@return [ Document
] The third document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 665 def third! third || raise_document_not_found_error end
Get the third to last document in the database for the criteria’s selector.
@example Get the third to last document.
context.third_to_last
@return [ Document
| nil ] The third to last document or nil if none is found.
# File lib/mongoid/contextual/mongo.rb, line 751 def third_to_last retrieve_nth_to_last(2) end
Get the third to last document in the database for the criteria’s selector or raise an error if none is found.
@example Get the third to last document.
context.third_to_last!
@return [ Document
] The third to last document.
@raise [ Mongoid::Errors::DocumentNotFound
] raises when there are no
documents available.
# File lib/mongoid/contextual/mongo.rb, line 765 def third_to_last! third_to_last || raise_document_not_found_error end
Update the first matching document atomically.
@example Update the first matching document.
context.update({ "$set" => { name: "Smiths" }})
@param [ Hash ] attributes The new attributes for the document. @param [ Hash ] opts The update operation options.
@option opts [ Array ] :array_filters A set of filters specifying to which array elements
an update should apply.
@return [ nil | false ] False if no attributes were provided.
# File lib/mongoid/contextual/mongo.rb, line 516 def update(attributes = nil, opts = {}) update_documents(attributes, :update_one, opts) end
Update all the matching documents atomically.
@example Update all the matching documents.
context.update_all({ "$set" => { name: "Smiths" }})
@param [ Hash ] attributes The new attributes for each document. @param [ Hash ] opts The update operation options.
@option opts [ Array ] :array_filters A set of filters specifying to which array elements
an update should apply.
@return [ nil | false ] False if no attributes were provided.
# File lib/mongoid/contextual/mongo.rb, line 532 def update_all(attributes = nil, opts = {}) update_documents(attributes, :update_many, opts) end
Private Instance Methods
# File lib/mongoid/contextual/mongo.rb, line 888 def _session @criteria.send(:_session) end
# File lib/mongoid/contextual/mongo.rb, line 892 def acknowledged_write? collection.write_concern.nil? || collection.write_concern.acknowledged? end
Apply the field limitations.
@api private
@example Apply the field limitations.
context.apply_fields
# File lib/mongoid/contextual/mongo.rb, line 805 def apply_fields if spec = criteria.options[:fields] @view = view.projection(spec) end end
Apply an option.
@api private
@example Apply the skip option.
context.apply_option(:skip)
# File lib/mongoid/contextual/mongo.rb, line 833 def apply_option(name) if spec = criteria.options[name] @view = view.send(name, spec) end end
Apply the options.
@api private
@example Apply all options.
context.apply_options
# File lib/mongoid/contextual/mongo.rb, line 817 def apply_options apply_fields OPTIONS.each do |name| apply_option(name) end if criteria.options[:timeout] == false @view = view.no_cursor_timeout end end
Demongoize the value for the given field. If the field is nil or the field is a translations field, the value is demongoized using its class.
@param [ Field ] field The field to use to demongoize. @param [ Object
] value The value to demongoize. @param [ true | false ] is_translation The field we are retrieving is an
_translations field.
@return [ Object
] The demongoized value.
@api private
# File lib/mongoid/contextual/mongo.rb, line 993 def demongoize_with_field(field, value, is_translation) if field # If it's a localized field that's not a hash, don't demongoize # again, we already have the translation. If it's an _translations # field, don't demongoize, we want the full hash not just a # specific translation. # If it is a hash, and it's not a translations field, we need to # demongoize to get the correct translation. if field.localized? && (!value.is_a?(Hash) || is_translation) value.class.demongoize(value) else field.demongoize(value) end else value.class.demongoize(value) end end
Get the documents the context should iterate.
If the documents have been already preloaded by ‘Document::Loader` instance, they will be used.
@return [ Array<Document> | Mongo::Collection::View ] The docs to iterate.
@api private
# File lib/mongoid/contextual/mongo.rb, line 855 def documents_for_iteration if @documents_loader if @documents_loader.started? @documents_loader.value! else @documents_loader.unschedule @documents_loader.execute end else return view unless eager_loadable? docs = view.map do |doc| Factory.from_db(klass, doc, criteria) end eager_load(docs) end end
Extracts the value for the given field name from the given attribute hash.
@param [ Hash ] attrs The attributes hash. @param [ String ] field_name The name of the field to extract.
@param [ Object
] The value for the given field name
# File lib/mongoid/contextual/mongo.rb, line 923 def extract_value(attrs, field_name) i = 1 num_meths = field_name.count('.') + 1 curr = attrs.dup klass.traverse_association_tree(field_name) do |meth, obj, is_field| field = obj if is_field is_translation = false # If no association or field was found, check if the meth is an # _translations field. if obj.nil? & tr = meth.match(/(.*)_translations\z/)&.captures&.first is_translation = true meth = tr end # 1. If curr is an array fetch from all elements in the array. # 2. If the field is localized, and is not an _translations field # (_translations fields don't show up in the fields hash). # - If this is the end of the methods, return the translation for # the current locale. # - Otherwise, return the whole translations hash so the next method # can select the language it wants. # 3. If the meth is an _translations field, do not demongoize the # value so the full hash is returned. # 4. Otherwise, fetch and demongoize the value for the key meth. curr = if curr.is_a? Array res = fetch_and_demongoize(curr, meth, field) res.empty? ? nil : res elsif !is_translation && field&.localized? if i < num_meths curr.try(:fetch, meth, nil) else fetch_and_demongoize(curr, meth, field) end elsif is_translation curr.try(:fetch, meth, nil) else fetch_and_demongoize(curr, meth, field) end i += 1 end curr end
Fetch the element from the given hash and demongoize it using the given field. If the obj is an array, map over it and call this method on all of its elements.
@param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from. @param [ String ] meth The key to fetch from the hash. @param [ Field ] field The field to use for demongoization.
@return [ Object
] The demongoized value.
@api private
# File lib/mongoid/contextual/mongo.rb, line 907 def fetch_and_demongoize(obj, meth, field) if obj.is_a?(Array) obj.map { |doc| fetch_and_demongoize(doc, meth, field) } else res = obj.try(:fetch, meth, nil) field ? field.demongoize(res) : res.class.demongoize(res) end end
Map the inverse sort symbols to the correct MongoDB values.
@api private
# File lib/mongoid/contextual/mongo.rb, line 842 def inverse_sorting sort = view.sort || { _id: 1 } Hash[sort.map{|k, v| [k, -1*v]}] end
Process the raw documents retrieved for first
/#last.
@return [ Array<Document> | Document
] The list of documents or a
single document.
# File lib/mongoid/contextual/mongo.rb, line 1015 def process_raw_docs(raw_docs, limit) docs = raw_docs.map do |d| Factory.from_db(klass, d, criteria) end docs = eager_load(docs) limit ? docs : docs.first end
# File lib/mongoid/contextual/mongo.rb, line 1044 def raise_document_not_found_error raise Errors::DocumentNotFound.new(klass, nil, nil) end
Recursively demongoize the given value. This method recursively traverses the class tree to find the correct field to use to demongoize the value.
@param [ String ] field_name The name of the field to demongoize. @param [ Object
] value The value to demongoize. @param [ true | false ] is_translation The field we are retrieving is an
_translations field.
@return [ Object
] The demongoized value.
# File lib/mongoid/contextual/mongo.rb, line 977 def recursive_demongoize(field_name, value, is_translation) field = klass.traverse_association_tree(field_name) demongoize_with_field(field, value, is_translation) end
# File lib/mongoid/contextual/mongo.rb, line 1048 def retrieve_nth(n) retrieve_nth_with_limit(n, 1).first end
# File lib/mongoid/contextual/mongo.rb, line 1061 def retrieve_nth_to_last(n) retrieve_nth_to_last_with_limit(n, 1).first end
# File lib/mongoid/contextual/mongo.rb, line 1065 def retrieve_nth_to_last_with_limit(n, limit) v = view.sort(inverse_sorting).skip(n).limit(limit || 1) v = v.skip(n) if n > 0 raw_docs = v.to_a.reverse process_raw_docs(raw_docs, limit) end
# File lib/mongoid/contextual/mongo.rb, line 1052 def retrieve_nth_with_limit(n, limit) sort = view.sort || { _id: 1 } v = view.sort(sort).limit(limit || 1) v = v.skip(n) if n > 0 if raw_docs = v.to_a process_raw_docs(raw_docs, limit) end end
Update the documents for the provided method.
@api private
@example Update the documents.
context.update_documents(attrs)
@param [ Hash ] attributes The updates. @param [ Symbol ] method The method to use.
@return [ true | false ] If the update succeeded.
# File lib/mongoid/contextual/mongo.rb, line 793 def update_documents(attributes, method = :update_one, opts = {}) return false unless attributes view.send(method, AtomicUpdatePreparer.prepare(attributes, klass), opts) end
Queries whether the current context is valid for use with the count_documents? predicate. A context is valid if it does not include a ‘$where` operator.
@return [ true | false ] whether or not the current context
excludes a `$where` operator.
TODO: Remove this method when we remove the deprecated for_js API. jira.mongodb.org/browse/MONGOID-5681
# File lib/mongoid/contextual/mongo.rb, line 1032 def valid_for_count_documents?(hash = view.filter) # Note that `view.filter` is a BSON::Document, and all keys in a # BSON::Document are strings; we don't need to worry about symbol # representations of `$where`. hash.keys.each do |key| return false if key == '$where' return false if hash[key].is_a?(Hash) && !valid_for_count_documents?(hash[key]) end true end
Yield to the document.
@api private
@example Yield the document.
context.yield_document(doc) do |doc| ... end
@param [ Document
] document The document to yield to.
# File lib/mongoid/contextual/mongo.rb, line 882 def yield_document(document, &block) doc = document.respond_to?(:_id) ? document : Factory.from_db(klass, document, criteria) yield(doc) end