Class: Mongoid::Contextual::Mongo
- Inherits:
-
Object
- Object
- Mongoid::Contextual::Mongo
- Extended by:
- Forwardable
- Includes:
- Enumerable, Association::EagerLoadable, Atomic, Aggregable::Mongo, Queryable
- Defined in:
- build/mongoid-8.1/lib/mongoid/contextual/mongo.rb,
build/mongoid-8.1/lib/mongoid/contextual/mongo/documents_loader.rb
Defined Under Namespace
Classes: DocumentsLoader
Constant Summary collapse
- OPTIONS =
Options constant.
[ :hint, :limit, :skip, :sort, :batch_size, :max_scan, :max_time_ms, :snapshot, :comment, :read, :cursor_type, :collation ].freeze
Constants included from Atomic
Instance Attribute Summary collapse
-
#documents_loader ⇒ Object
readonly
Returns the value of attribute documents_loader.
-
#view ⇒ Hash
readonly
Run an explain on the criteria.
- #view The Mongo collection view.(TheMongocollectionview.) ⇒ Object readonly
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
-
#count(options = {}, &block) ⇒ Integer
Get the number of documents matching the query.
-
#delete ⇒ nil
(also: #delete_all)
Delete all documents in the database that match the selector.
-
#destroy ⇒ nil
(also: #destroy_all)
Destroy all documents in the database that match the selector.
-
#distinct(field) ⇒ Array<Object>
Get the distinct values in the db for the provided field.
-
#each(&block) ⇒ Enumerator
Iterate over the context.
-
#estimated_count(options = {}) ⇒ Integer
Get the estimated number of documents matching the query.
-
#exists?(id_or_conditions = :none) ⇒ true | false
Do any documents exist for the context.
-
#fifth ⇒ Document | nil
Get the fifth document in the database for the criteria’s selector.
-
#fifth! ⇒ Document
Get the fifth document in the database for the criteria’s selector or raise an error if none is found.
-
#find_first ⇒ Object
private
Return the first result without applying sort.
-
#find_one_and_delete ⇒ Document
Execute the find and modify command, used for MongoDB’s $findAndModify.
-
#find_one_and_replace(replacement, options = {}) ⇒ Document
Execute the find and modify command, used for MongoDB’s $findAndModify.
-
#find_one_and_update(update, options = {}) ⇒ Document
Execute the find and modify command, used for MongoDB’s $findAndModify.
-
#first(limit = nil) ⇒ Document | nil
(also: #one)
Get the first document in the database for the criteria’s selector.
-
#first! ⇒ Document
Get the first document in the database for the criteria’s selector or raise an error if none is found.
-
#fourth ⇒ Document | nil
Get the fourth document in the database for the criteria’s selector.
-
#fourth! ⇒ Document
Get the fourth document in the database for the criteria’s selector or raise an error if none is found.
- #geo_near(coordinates) ⇒ GeoNear deprecated Deprecated.
-
#initialize(criteria) ⇒ Mongo
constructor
Create the new Mongo context.
-
#last(limit = nil) ⇒ Document | nil
Get the last document in the database for the criteria’s selector.
-
#last! ⇒ Document
Get the last document in the database for the criteria’s selector or raise an error if none is found.
-
#length ⇒ Integer
(also: #size)
Returns the number of documents in the database matching the query selector.
-
#limit(value) ⇒ Mongo
Limits the number of documents that are returned from the database.
-
#load_async ⇒ Object
private
Schedule a task to load documents for the context.
-
#map_reduce(map, reduce) ⇒ MapReduce
Initiate a map/reduce operation from the context.
-
#pick(*fields) ⇒ Object | Array<Object>
Pick the single field values from the database.
-
#pluck(*fields) ⇒ Array<Object> | Array<Array<Object>>
Pluck the field value(s) from the database.
-
#second ⇒ Document | nil
Get the second document in the database for the criteria’s selector.
-
#second! ⇒ Document
Get the second document in the database for the criteria’s selector or raise an error if none is found.
-
#second_to_last ⇒ Document | nil
Get the second to last document in the database for the criteria’s selector.
-
#second_to_last! ⇒ Document
Get the second to last document in the database for the criteria’s selector or raise an error if none is found.
-
#skip(value) ⇒ Mongo
Skips the provided number of documents.
-
#sort(values = nil, &block) ⇒ Mongo
Sorts the documents by the provided spec.
-
#take(limit = nil) ⇒ Document | Array<Document>
Take the given number of documents from the database.
-
#take! ⇒ Document
Take one document from the database and raise an error if there are none.
-
#tally(field) ⇒ Hash
Get a hash of counts for the values of a single field.
-
#third ⇒ Document | nil
Get the third document in the database for the criteria’s selector.
-
#third! ⇒ Document
Get the third document in the database for the criteria’s selector or raise an error if none is found.
-
#third_to_last ⇒ Document | nil
Get the third to last document in the database for the criteria’s selector.
-
#third_to_last! ⇒ Document
Get the third to last document in the database for the criteria’s selector or raise an error if none is found.
-
#update(attributes = nil, opts = {}) ⇒ nil | false
Update the first matching document atomically.
-
#update_all(attributes = nil, opts = {}) ⇒ nil | false
Update all the matching documents atomically.
Methods included from Queryable
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.
287 288 289 290 291 292 293 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 287 def initialize(criteria) @criteria, @klass = criteria, criteria.klass @collection = @klass.collection criteria.send(:merge_type_selection) @view = collection.find(criteria.selector, session: _session) end |
Instance Attribute Details
#documents_loader ⇒ Object (readonly)
Returns the value of attribute documents_loader.
51 52 53 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 51 def documents_loader @documents_loader end |
#view ⇒ Hash (readonly)
Run an explain on the criteria.
39 40 41 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 39 def view @view end |
#view The Mongo collection view.(TheMongocollectionview.) ⇒ Object (readonly)
39 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 39 attr_reader :view |
Instance Method Details
#count(options = {}, &block) ⇒ Integer
Get the number of documents matching the query.
70 71 72 73 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 70 def count( = {}, &block) return super(&block) if block_given? view.count_documents() end |
#delete ⇒ nil Also known as: delete_all
Delete all documents in the database that match the selector.
100 101 102 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 100 def delete view.delete_many.deleted_count end |
#destroy ⇒ nil Also known as: destroy_all
Destroy all documents in the database that match the selector.
111 112 113 114 115 116 117 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 111 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.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 128 def distinct(field) name = if Mongoid.legacy_pluck_distinct klass.database_field_name(field) else klass.cleanse_localized_field_names(field) end view.distinct(name).map do |value| if Mongoid.legacy_pluck_distinct value.class.demongoize(value) else is_translation = "#{name}_translations" == field.to_s recursive_demongoize(name, value, is_translation) end end end |
#each(&block) ⇒ Enumerator
Iterate over the context. If provided a block, yield to a Mongoid document for each, otherwise return an enum.
154 155 156 157 158 159 160 161 162 163 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 154 def each(&block) if block_given? documents_for_iteration.each do |doc| yield_document(doc, &block) end 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.
87 88 89 90 91 92 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 87 def estimated_count( = {}) unless self.criteria.selector.empty? raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass) end view.estimated_document_count() end |
#exists?(id_or_conditions = :none) ⇒ true | false
We don’t use count here since Mongo does not use counted b-tree indexes.
Do any documents exist for the context.
184 185 186 187 188 189 190 191 192 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 184 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 |
#fifth ⇒ Document | nil
Get the fifth document in the database for the criteria’s selector.
725 726 727 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 725 def fifth retrieve_nth(4) end |
#fifth! ⇒ Document
Get the fifth document in the database for the criteria’s selector or raise an error if none is found.
739 740 741 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 739 def fifth! fifth || raise_document_not_found_error end |
#find_first ⇒ Object
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
250 251 252 253 254 255 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 250 def find_first if raw_doc = view.first doc = Factory.from_db(klass, raw_doc, criteria) eager_load([doc]).first end end |
#find_one_and_delete ⇒ Document
Execute the find and modify command, used for MongoDB’s $findAndModify. This deletes the found document.
241 242 243 244 245 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 241 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.
228 229 230 231 232 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 228 def find_one_and_replace(replacement, = {}) if doc = view.find_one_and_replace(replacement, ) 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.
208 209 210 211 212 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 208 def find_one_and_update(update, = {}) if doc = view.find_one_and_update(update, ) Factory.from_db(klass, doc) end end |
#first(limit = nil) ⇒ Document | nil Also known as: one
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.
Get the first document in the database for the criteria’s selector.
576 577 578 579 580 581 582 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 576 def first(limit = nil) if limit.nil? retrieve_nth(0) else retrieve_nth_with_limit(0, limit) end end |
#first! ⇒ Document
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.
Get the first document in the database for the criteria’s selector or raise an error if none is found.
601 602 603 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 601 def first! first || raise_document_not_found_error end |
#fourth ⇒ Document | nil
Get the fourth document in the database for the criteria’s selector.
701 702 703 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 701 def fourth retrieve_nth(3) end |
#fourth! ⇒ Document
Get the fourth document in the database for the criteria’s selector or raise an error if none is found.
715 716 717 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 715 def fourth! fourth || raise_document_not_found_error end |
#geo_near(coordinates) ⇒ GeoNear
Execute a $geoNear command against the database.
276 277 278 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 276 def geo_near(coordinates) GeoNear.new(collection, criteria, coordinates) end |
#last(limit = nil) ⇒ Document | nil
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.
Get the last document in the database for the criteria’s selector.
619 620 621 622 623 624 625 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 619 def last(limit = nil) if limit.nil? retrieve_nth_to_last(0) else retrieve_nth_to_last_with_limit(0, limit) end end |
#last! ⇒ Document
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.
Get the last document in the database for the criteria’s selector or raise an error if none is found.
643 644 645 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 643 def last! last || raise_document_not_found_error end |
#length ⇒ Integer Also known as: size
Returns the number of documents in the database matching the query selector.
304 305 306 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 304 def length self.count end |
#limit(value) ⇒ Mongo
Limits the number of documents that are returned from the database.
317 318 319 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 317 def limit(value) @view = view.limit(value) and self end |
#load_async ⇒ Object
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.
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.
802 803 804 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 802 def load_async @documents_loader ||= DocumentsLoader.new(view, klass, criteria) end |
#map_reduce(map, reduce) ⇒ MapReduce
Initiate a map/reduce operation from the context.
330 331 332 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 330 def map_reduce(map, reduce) MapReduce.new(collection, criteria, map, reduce) end |
#pick(*fields) ⇒ Object | Array<Object>
Pick the single field values from the database.
387 388 389 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 387 def pick(*fields) limit(1).pluck(*fields).first end |
#pluck(*fields) ⇒ Array<Object> | Array<Array<Object>>
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.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 350 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) if Mongoid.legacy_pluck_distinct hash[db_fn] = true else hash[klass.cleanse_localized_field_names(f)] = true end hash end view.projection(normalized_select).reduce([]) do |plucked, doc| values = normalized_field_names.map do |n| if Mongoid.legacy_pluck_distinct n.include?('.') ? doc[n.partition('.')[0]] : doc[n] else extract_value(doc, n) end end plucked << (values.size == 1 ? values.first : values) end end |
#second ⇒ Document | nil
Get the second document in the database for the criteria’s selector.
653 654 655 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 653 def second retrieve_nth(1) end |
#second! ⇒ Document
Get the second document in the database for the criteria’s selector or raise an error if none is found.
667 668 669 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 667 def second! second || raise_document_not_found_error end |
#second_to_last ⇒ Document | nil
Get the second to last document in the database for the criteria’s selector.
is found.
751 752 753 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 751 def second_to_last retrieve_nth_to_last(1) end |
#second_to_last! ⇒ Document
Get the second to last document in the database for the criteria’s selector or raise an error if none is found.
765 766 767 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 765 def second_to_last! second_to_last || raise_document_not_found_error end |
#skip(value) ⇒ Mongo
Skips the provided number of documents.
506 507 508 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 506 def skip(value) @view = view.skip(value) and self end |
#sort(values = nil, &block) ⇒ Mongo
Sorts the documents by the provided spec.
519 520 521 522 523 524 525 526 527 528 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 519 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(limit = nil) ⇒ Document | Array<Document>
Take the given number of documents from the database.
400 401 402 403 404 405 406 407 408 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 400 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! ⇒ Document
Take one document from the database and raise an error if there are none.
419 420 421 422 423 424 425 426 427 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 419 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 |
#tally(field) ⇒ Hash
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 }
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 466 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 |
#third ⇒ Document | nil
Get the third document in the database for the criteria’s selector.
677 678 679 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 677 def third retrieve_nth(2) end |
#third! ⇒ Document
Get the third document in the database for the criteria’s selector or raise an error if none is found.
691 692 693 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 691 def third! third || raise_document_not_found_error end |
#third_to_last ⇒ Document | nil
Get the third to last document in the database for the criteria’s selector.
is found.
777 778 779 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 777 def third_to_last retrieve_nth_to_last(2) end |
#third_to_last! ⇒ Document
Get the third to last document in the database for the criteria’s selector or raise an error if none is found.
791 792 793 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 791 def third_to_last! third_to_last || raise_document_not_found_error end |
#update(attributes = nil, opts = {}) ⇒ nil | false
Update the first matching document atomically.
542 543 544 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 542 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.
558 559 560 |
# File 'build/mongoid-8.1/lib/mongoid/contextual/mongo.rb', line 558 def update_all(attributes = nil, opts = {}) update_documents(attributes, :update_many, opts) end |