Module: Mongo::Collection::View::Iterable
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
::Mongo::CursorHost
|
|
| Defined in: | lib/mongo/collection/view/iterable.rb |
Overview
Defines iteration related behavior for collection views, including cursor instantiation.
Instance Attribute Summary
-
#prefer_cached_cursor? ⇒ Boolean
readonly
private
If the caching cursor is closed and was not fully iterated, the documents we have in it are not the complete result set and we have no way of completing that iteration.
- #use_query_cache? ⇒ Boolean readonly private
::Mongo::CursorHost - Included
| #cursor | Returns the cursor associated with this view, if any. |
| #timeout_mode | |
Instance Method Summary
-
#close_query ⇒ nil
(also: #kill_cursors)
Cleans up resources associated with this query.
-
#each {|Each| ... } ⇒ Enumerator
Iterate through documents returned by a query with this
::Mongo::Collection::View. -
#kill_cursors
Alias for #close_query.
- #cache_options private
- #cached_cursor private
- #compute_limit_for_cached_query private
- #initial_query_op(session) private
-
#maybe_set_tailable_options(spec)
private
Add tailable cusror options to the command specifiction if needed.
-
#new_cursor_for_iteration
private
Start a new cursor for use when iterating (via #each).
- #oplog_replay ⇒ true | false | nil private
- #select_cursor(session) private
- #send_initial_query(server, context, operation: nil) private
::Mongo::CursorHost - Included
| #validate_timeout_mode! | Ensure the timeout mode is appropriate for other options that have been given. |
Instance Attribute Details
#prefer_cached_cursor? ⇒ Boolean (readonly, private)
If the caching cursor is closed and was not fully iterated, the documents we have in it are not the complete result set and we have no way of completing that iteration. Therefore, discard that cursor and start iteration again.
# File 'lib/mongo/collection/view/iterable.rb', line 191
def prefer_cached_cursor? use_query_cache? && cached_cursor && (cached_cursor.fully_iterated? || !cached_cursor.closed?) end
#use_query_cache? ⇒ Boolean (readonly, private)
# File 'lib/mongo/collection/view/iterable.rb', line 183
def use_query_cache? QueryCache.enabled? && !collection.system_collection? end
Instance Method Details
#cache_options (private)
# File 'lib/mongo/collection/view/iterable.rb', line 114
def # NB: this hash is passed as keyword argument and must have symbol # keys. { namespace: collection.namespace, selector: selector, skip: skip, sort: sort, limit: limit, projection: projection, collation: collation, read_concern: read_concern, read_preference: read_preference, } end
#cached_cursor (private)
# File 'lib/mongo/collection/view/iterable.rb', line 110
def cached_cursor QueryCache.get(**) end
#close_query ⇒ nil
Also known as: #kill_cursors
This method propagates any errors that occur when closing the server-side cursor.
Cleans up resources associated with this query.
If there is a server cursor associated with this query, it is closed by sending a KillCursors command to the server.
# File 'lib/mongo/collection/view/iterable.rb', line 72
def close_query return unless @cursor @cursor.close end
#compute_limit_for_cached_query (private)
# File 'lib/mongo/collection/view/iterable.rb', line 209
def compute_limit_for_cached_query return nil unless use_query_cache? && respond_to?(:limit) # If a query with a limit is performed, the query cache will # re-use results from an earlier query with the same or larger # limit, and then impose the lower limit during iteration. QueryCache.normalized_limit(limit) end
#each {|Each| ... } ⇒ Enumerator
Iterate through documents returned by a query with this ::Mongo::Collection::View.
# File 'lib/mongo/collection/view/iterable.rb', line 41
def each(&block) @cursor = prefer_cached_cursor? ? cached_cursor : new_cursor_for_iteration return @cursor.to_enum unless block_given? limit_for_cached_query = compute_limit_for_cached_query # TODO: rather than pulling the entire (limited) result set into # memory, this should tell the cursor about the limit and then let # the cursor limit the iteration as necessary. cursor_to_iterate = if limit_for_cached_query @cursor.to_a[0...limit_for_cached_query] else @cursor end cursor_to_iterate.each(&block) end
#initial_query_op(session) (private)
# File 'lib/mongo/collection/view/iterable.rb', line 130
def initial_query_op(session) spec = { coll_name: collection.name, filter: filter, projection: projection, db_name: database.name, session: session, collation: collation, sort: sort, skip: skip, let: [:let], limit: limit, allow_disk_use: [:allow_disk_use], allow_partial_results: [:allow_partial_results], read: read, read_concern: [:read_concern] || read_concern, batch_size: batch_size, hint: [:hint], max_scan: [:max_scan], max_value: [:max_value], min_value: [:min_value], no_cursor_timeout: [:no_cursor_timeout], return_key: [:return_key], show_disk_loc: [:show_disk_loc], comment: [:comment], oplog_replay: oplog_replay } if spec[:oplog_replay] collection.client.log_warn('The :oplog_replay option is deprecated and ignored by MongoDB 4.4 and later') end (spec) if explained? spec[:explain] = [:explain] Operation::Explain.new(spec) else Operation::Find.new(spec) end end
#kill_cursors
Alias for #close_query.
# File 'lib/mongo/collection/view/iterable.rb', line 77
alias kill_cursors close_query
#maybe_set_tailable_options(spec) (private)
Add tailable cusror options to the command specifiction if needed.
# File 'lib/mongo/collection/view/iterable.rb', line 221
def (spec) case cursor_type when :tailable spec[:tailable] = true when :tailable_await spec[:tailable] = true spec[:await_data] = true end end
#new_cursor_for_iteration (private)
Start a new cursor for use when iterating (via #each).
# File 'lib/mongo/collection/view/iterable.rb', line 198
def new_cursor_for_iteration session = client.get_session(@options) select_cursor(session).tap do |cursor| if use_query_cache? # No need to store the cursor in the query cache if there is # already a cached cursor stored at this key. QueryCache.set(cursor, **) end end end
#oplog_replay ⇒ true | false | nil (private)
# File 'lib/mongo/collection/view/iterable.rb', line 233
def oplog_replay v = [:oplog_replay] v.nil? ? collection.[:oplog_replay] : v end
#select_cursor(session) (private)
# File 'lib/mongo/collection/view/iterable.rb', line 81
def select_cursor(session) context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts, view: self ) op = initial_query_op(session) tracer.trace_operation(op, context) do if respond_to?(:write?, true) && write? retry_enabled = collection.client.[:retry_writes] != false with_overload_retry(context: context, retry_enabled: retry_enabled) do server = server_selector.select_server(cluster, nil, session, write_aggregation: true) result = send_initial_query(server, context, operation: op) if use_query_cache? CachingCursor.new(view, result, server, session: session, context: context) else Cursor.new(view, result, server, session: session, context: context) end end else read_with_retry_cursor(session, server_selector, view, context: context) do |server| send_initial_query(server, context, operation: op) end end end end
#send_initial_query(server, context, operation: nil) (private)
# File 'lib/mongo/collection/view/iterable.rb', line 172
def send_initial_query(server, context, operation: nil) operation ||= initial_query_op(context.session) if server.load_balancer? # Connection will be checked in when cursor is drained. connection = server.pool.check_out(context: context) operation.execute_with_connection(connection, context: context) else operation.execute(server, context: context) end end