Class: Mongoid::Contextual::Memory
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
self,
::Mongoid::Positional ,
Queryable ,
::Mongoid::Association::EagerLoadable ,
Aggregable::Memory ,
Enumerable
|
|
Inherits: | Object |
Defined in: | lib/mongoid/contextual/memory.rb |
Overview
Context object used for performing bulk query and persistence operations on documents which have been loaded into application memory. The method interface of this class is consistent with Mongoid::Contextual::Mongo.
Class Method Summary
-
.new(criteria) ⇒ Memory
constructor
Create the new in memory context.
Instance Attribute Summary
- #documents readonly
- #matching The in memory documents that match the selector.(The in memory documents that match the selector.) readonly
- #path readonly
- #path The atomic path.(The atomic path.) readonly
- #root readonly
- #root The root document.(The root document.) readonly
- #selector readonly
- #selector The root document selector.(The root document selector.) readonly
-
#limiting ⇒ Integer
rw
private
Internal use only
Internal use only
Get the limiting value.
-
#limiting=(value) ⇒ Integer
rw
private
Internal use only
Internal use only
::Set
the limiting value. -
#skipping ⇒ Integer
rw
private
Internal use only
Internal use only
Get the skipping value.
-
#skipping=(value) ⇒ Integer
rw
private
Internal use only
Internal use only
::Set
the skipping value.
Queryable
- Included
#blank? | Is the enumerable of matching documents empty? |
#collection, #collection The collection to query against., #criteria, #criteria The criteria for the context., | |
#empty? | Alias for Queryable#blank?. |
#klass, #klass The klass for the criteria. |
::Mongoid::Association::EagerLoadable
- Included
#eager_loadable? | Indicates whether the criteria has association inclusions which should be eager loaded. |
Instance Method Summary
-
#==(other) ⇒ true | false
Check if the context is equal to the other object.
-
#delete ⇒ nil
(also: #delete_all)
Delete all documents in the database that match the selector.
-
#delete_all
Alias for #delete.
-
#destroy ⇒ nil
(also: #destroy_all)
Destroy all documents in the database that match the selector.
-
#destroy_all
Alias for #destroy.
-
#distinct(field) ⇒ Array<Object>
Get the distinct values in the db for the provided field.
-
#each ⇒ Enumerator
Iterate over the context.
-
#exists?(id_or_conditions = :none) ⇒ true | false
Do any documents exist for the context.
-
#fifth ⇒ Document
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(limit = nil)
Alias for #first.
-
#first(limit = nil) ⇒ Document
(also: #one, #find_first)
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
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.
-
#inc(incs) ⇒ Enumerator
Increment a value on all documents.
-
#last(limit = nil) ⇒ Document
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)
Get the length of matching documents in the context.
-
#limit(value) ⇒ Memory
Limits the number of documents that are returned.
-
#one(limit = nil)
Alias for #first.
-
#pick(*fields) ⇒ Object | Array<Object>
Pick the field values in memory.
-
#pluck(*fields) ⇒ Array<Object> | Array<Array<Object>>
Pluck the field values in memory.
-
#second ⇒ Document
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
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.
-
#size
Alias for #length.
-
#skip(value) ⇒ Memory
Skips the provided number of documents.
-
#sort(values) ⇒ Memory
Sorts the documents by the provided spec.
-
#take(limit = nil) ⇒ Document
Take the given number of documents from the database.
-
#take! ⇒ Document
Take the given number of documents from the database or raise an error if none are found.
-
#tally(field) ⇒ Hash
Tally the field values in memory.
-
#third ⇒ Document
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
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) ⇒ nil | false
Update the first matching document atomically.
-
#update_all(attributes = nil) ⇒ nil | false
Update all the matching documents atomically.
- #_session private
-
#apply_options ⇒ Memory
private
Internal use only
Internal use only
Apply criteria options.
-
#apply_sorting
private
Map the sort symbols to the correct MongoDB values.
-
#compare(a, b) ⇒ Integer
private
Internal use only
Internal use only
Compare two values, handling the cases when either value is nil.
-
#compare_operand(value) ⇒ Integer | Object
private
Get the operand value to be used in comparison.
-
#documents_for_iteration ⇒ Array<Document>
private
Internal use only
Internal use only
Get the documents the context should iterate.
-
#in_place_sort(values)
private
Sort the documents in place.
-
#pluck_from_doc(doc, *fields) ⇒ Object | Array<Object>
private
Pluck the field values from the given document.
-
#prepare_remove(doc)
private
Internal use only
Internal use only
Prepare the document for batch removal.
- #raise_document_not_found_error private
-
#retrieve_value_at_path(document, field_path) ⇒ Object | nil
private
Retrieve the value for the current document at the given field path.
-
#update_documents(attributes, docs)
private
Internal use only
Internal use only
Update the provided documents with the attributes.
::Mongoid::Positional
- Included
#positionally | Takes the provided selector and atomic operations and replaces the indexes of the embedded documents with the positional operator when needed. |
#process_operations, #process_updates, #replace_index |
::Mongoid::Association::EagerLoadable
- Included
#eager_load | Load the associations for the given documents. |
#preload | Load the associations for the given documents. |
Aggregable::Memory
- Included
#aggregates | Get all the aggregate values for the provided field. |
#avg | Get the average value of the provided field. |
#max | Get the max value of the provided field. |
#min | Get the min value of the provided field. |
#sum | Get the sum value of the provided field. |
#aggregate_by | Aggregate by the provided field and method. |
Constructor Details
.new(criteria) ⇒ Memory
Create the new in memory context.
# File 'lib/mongoid/contextual/memory.rb', line 173
def initialize(criteria) @criteria, @klass = criteria, criteria.klass @documents = criteria.documents.select do |doc| @root ||= doc._root @collection ||= root.collection doc._matches?(criteria.selector) end apply_sorting end
Instance Attribute Details
#documents (readonly)
[ GitHub ]#limiting ⇒ Integer (rw, private)
Get the limiting value.
# File 'lib/mongoid/contextual/memory.rb', line 566
def limiting defined?(@limiting) ? @limiting : nil end
#limiting=(value) ⇒ Integer (rw, private)
::Set
the limiting value.
# File 'lib/mongoid/contextual/memory.rb', line 579
def limiting=(value) @limiting = value end
#matching The in memory documents that match the selector.(The in memory documents that match the selector.) (readonly)
[ GitHub ]#path (readonly)
[ GitHub ]#path The atomic path.(The atomic path.) (readonly)
[ GitHub ]#root (readonly)
[ GitHub ]#root The root document.(The root document.) (readonly)
[ GitHub ]#selector (readonly)
[ GitHub ]#selector The root document selector.(The root document selector.) (readonly)
[ GitHub ]#skipping ⇒ Integer (rw, private)
Get the skipping value.
# File 'lib/mongoid/contextual/memory.rb', line 590
def skipping defined?(@skipping) ? @skipping : nil end
#skipping=(value) ⇒ Integer (rw, private)
::Set
the skipping value.
# File 'lib/mongoid/contextual/memory.rb', line 603
def skipping=(value) @skipping = value end
Instance Method Details
#==(other) ⇒ true
| false
Check if the context is equal to the other object.
# File 'lib/mongoid/contextual/memory.rb', line 35
def ==(other) return false unless other.respond_to?(:entries) entries == other.entries end
#_session (private)
[ GitHub ]# File 'lib/mongoid/contextual/memory.rb', line 682
def _session @criteria.send(:_session) end
#apply_options ⇒ Memory
(private)
Apply criteria options.
#apply_sorting (private)
Map the sort symbols to the correct MongoDB values.
# File 'lib/mongoid/contextual/memory.rb', line 624
def apply_sorting if spec = criteria. [:sort] in_place_sort(spec) end end
#compare(a, b) ⇒ Integer (private)
Compare two values, handling the cases when either value is nil.
# File 'lib/mongoid/contextual/memory.rb', line 642
def compare(a, b) return 0 if a.nil? && b.nil? return 1 if a.nil? return -1 if b.nil? compare_operand(a) <=> compare_operand(b) end
#compare_operand(value) ⇒ Integer | Object
(private)
Get the operand value to be used in comparison. Adds capability to sort boolean values.
# File 'lib/mongoid/contextual/memory.rb', line 695
def compare_operand(value) case value when TrueClass then 1 when FalseClass then 0 else value end end
#delete ⇒ nil
Also known as: #delete_all
Delete all documents in the database that match the selector.
# File 'lib/mongoid/contextual/memory.rb', line 46
def delete deleted = count removed = map do |doc| prepare_remove(doc) doc.send(:as_attributes) end unless removed.empty? collection.find(selector).update_one( positionally(selector, "$pullAll" => { path => removed }), session: _session ) end deleted end
#delete_all
Alias for #delete.
# File 'lib/mongoid/contextual/memory.rb', line 60
alias :delete_all :delete
#destroy ⇒ nil
Also known as: #destroy_all
Destroy all documents in the database that match the selector.
#destroy_all
Alias for #destroy.
# File 'lib/mongoid/contextual/memory.rb', line 76
alias :destroy_all :destroy
#distinct(field) ⇒ Array<Object
>
Get the distinct values in the db for the provided field.
# File 'lib/mongoid/contextual/memory.rb', line 86
def distinct(field) pluck(field).uniq end
#documents_for_iteration ⇒ Array<Document> (private)
Get the documents the context should iterate. This follows 3 rules:
#each ⇒ Enumerator
Iterate over the context. If provided a block, yield to a ::Mongoid
document for each, otherwise return an enum.
# File 'lib/mongoid/contextual/memory.rb', line 99
def each if block_given? documents_for_iteration.each do |doc| yield(doc) end self else to_enum end end
#exists?(id_or_conditions = :none) ⇒ true
| false
Do any documents exist for the context.
#fifth ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 468
def fifth! fifth || raise_document_not_found_error end
#find_first(limit = nil)
Alias for #first.
# File 'lib/mongoid/contextual/memory.rb', line 151
alias :find_first :first
#first(limit = nil) ⇒ Document Also known as: #one, #find_first
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.
# File 'lib/mongoid/contextual/memory.rb', line 163
def first! first || raise_document_not_found_error end
#fourth ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 444
def fourth! fourth || raise_document_not_found_error end
#in_place_sort(values) (private)
Sort the documents in place.
#inc(incs) ⇒ Enumerator
Increment a value on all documents.
# File 'lib/mongoid/contextual/memory.rb', line 192
def inc(incs) each do |document| document.inc(incs) end end
#last(limit = nil) ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 224
def last! last || raise_document_not_found_error end
#length ⇒ Integer Also known as: #size
Get the length of matching documents in the context.
# File 'lib/mongoid/contextual/memory.rb', line 234
def length documents.length end
#limit(value) ⇒ Memory
Limits the number of documents that are returned.
# File 'lib/mongoid/contextual/memory.rb', line 247
def limit(value) self.limiting = value self end
#one(limit = nil)
Alias for #first.
# File 'lib/mongoid/contextual/memory.rb', line 150
alias :one :first
#pick(*fields) ⇒ Object
| Array<Object
>
Pick the field values in memory.
# File 'lib/mongoid/contextual/memory.rb', line 274
def pick(*fields) if doc = documents.first pluck_from_doc(doc, *fields) end end
#pluck(*fields) ⇒ Array<Object
> | Array<Array<Object
>>
Pluck the field values in memory.
# File 'lib/mongoid/contextual/memory.rb', line 260
def pluck(*fields) documents.map do |doc| pluck_from_doc(doc, *fields) end end
#pluck_from_doc(doc, *fields) ⇒ Object
| Array<Object
> (private)
Pluck the field values from the given document.
# File 'lib/mongoid/contextual/memory.rb', line 766
def pluck_from_doc(doc, *fields) if fields.length == 1 retrieve_value_at_path(doc, fields.first) else fields.map do |field| retrieve_value_at_path(doc, field) end end end
#prepare_remove(doc) (private)
Prepare the document for batch removal.
#raise_document_not_found_error (private)
# File 'lib/mongoid/contextual/memory.rb', line 776
def raise_document_not_found_error raise Errors::DocumentNotFound.new(klass, nil, nil) end
#retrieve_value_at_path(document, field_path) ⇒ Object
| nil
(private)
Retrieve the value for the current document at the given field path.
For example, if I have the following models:
User has_many Accounts
address is a hash on Account
u = User.new(accounts: [ Account.new(address: { street: "W 50th" }) ])
retrieve_value_at_path(u, "user.accounts.address.street")
# => [ "W 50th" ]
Note that the result is in an array since accounts is an array. If it was nested in two arrays the result would be in a 2D array.
# File 'lib/mongoid/contextual/memory.rb', line 723
def retrieve_value_at_path(document, field_path) return if field_path.blank? || !document segment, remaining = field_path.to_s.split('.', 2) curr = if document.is_a?(Document) # Retrieves field for segment to check localization. Only does one # iteration since there's no dots res = if remaining field = document.class.traverse_association_tree(segment) # If this is a localized field, and there are remaining, get the # _translations hash so that we can get the specified translation in # the remaining if field&.localized? document.send("#{segment}_translations") end end meth = klass.aliased_associations[segment] || segment res.nil? ? document.try(meth) : res elsif document.is_a?(Hash) # TODO: Remove the indifferent access when implementing MONGOID-5410. document.key?(segment.to_s) ? document[segment.to_s] : document[segment.to_sym] else nil end return curr unless remaining if curr.is_a?(Array) # compact is used for consistency with server behavior. curr.map { |d| retrieve_value_at_path(d, remaining) }.compact else retrieve_value_at_path(curr, remaining) end end
#second ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 396
def second! second || raise_document_not_found_error end
#second_to_last ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 492
def second_to_last! second_to_last || raise_document_not_found_error end
#size
Alias for #length.
# File 'lib/mongoid/contextual/memory.rb', line 237
alias :size :length
#skip(value) ⇒ Memory
Skips the provided number of documents.
# File 'lib/mongoid/contextual/memory.rb', line 334
def skip(value) self.skipping = value self end
#sort(values) ⇒ Memory
Sorts the documents by the provided spec.
# File 'lib/mongoid/contextual/memory.rb', line 348
def sort(values) in_place_sort(values) and self end
#take(limit = nil) ⇒ Document
Take the given number of documents from the database.
#take! ⇒ Document
Take the given number of documents from the database or raise an error if none are found.
# File 'lib/mongoid/contextual/memory.rb', line 322
def take! take || raise_document_not_found_error end
#tally(field) ⇒ Hash
Tally the field values in memory.
# File 'lib/mongoid/contextual/memory.rb', line 288
def tally(field) return documents.each_with_object({}) do |d, acc| v = retrieve_value_at_path(d, field) acc[v] ||= 0 acc[v] += 1 end end
#third ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 420
def third! third || raise_document_not_found_error end
#third_to_last ⇒ Document
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.
# File 'lib/mongoid/contextual/memory.rb', line 516
def third_to_last! third_to_last || raise_document_not_found_error end
#update(attributes = nil) ⇒ nil
| false
Update the first matching document atomically.
# File 'lib/mongoid/contextual/memory.rb', line 360
def update(attributes = nil) update_documents(attributes, [ first ]) end
#update_all(attributes = nil) ⇒ nil
| false
Update all the matching documents atomically.
# File 'lib/mongoid/contextual/memory.rb', line 372
def update_all(attributes = nil) update_documents(attributes, entries) end
#update_documents(attributes, docs) (private)
Update the provided documents with the attributes.
# File 'lib/mongoid/contextual/memory.rb', line 547
def update_documents(attributes, docs) return false if !attributes || docs.empty? updates = { "$set" => {}} docs.each do |doc| @selector ||= root.atomic_selector doc.write_attributes(attributes) updates["$set"].merge!(doc.atomic_updates["$set"] || {}) doc.move_changes end collection.find(selector).update_one(updates, session: _session) unless updates["$set"].empty? end