123456789_123456789_123456789_123456789_123456789_

Module: Mongo::Collection::View::Iterable

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Included In:
Defined in: lib/mongo/collection/view/iterable.rb

Overview

Defines iteration related behavior for collection views, including cursor instantiation.

Since:

  • 2.0.0

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#cursornil | Cursor (readonly)

This method is for internal use only.

Returns the cursor associated with this view, if any.

Returns:

  • (nil | Cursor)

    The cursor, if any.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 33

attr_reader :cursor

#use_query_cache?Boolean (readonly, private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 203

def use_query_cache?
  QueryCache.enabled? && !collection.system_collection?
end

Instance Method Details

#cache_options (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 136

def cache_options
  # 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)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 132

def cached_cursor
  QueryCache.get(**cache_options)
end

#close_querynil Also known as: #kill_cursors

Note:

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.

Returns:

  • (nil)

    Always nil.

Raises:

Since:

  • 2.1.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 106

def close_query
  if @cursor
    @cursor.close
  end
end

#each {|Each| ... } ⇒ Enumerator

Iterate through documents returned by a query with this View.

Examples:

Iterate through the result of the view.

view.each do |document|
  p document
end

Yield Parameters:

  • Each (Hash)

    matching document.

Returns:

  • (Enumerator)

    The enumerator.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 47

def each
  # 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.
  # The case of the caching cursor not being closed and not having
  # been fully iterated isn't tested - see RUBY-2773.
  @cursor = if use_query_cache? && cached_cursor && (
    cached_cursor.fully_iterated? || !cached_cursor.closed?
  )
    cached_cursor
  else
    session = client.send(: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, **cache_options)
      end
    end
  end

  if use_query_cache?
    # 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.
    limit_for_cached_query = respond_to?(:limit) ? QueryCache.normalized_limit(limit) : nil
  end

  if block_given?
    # Ruby versions 2.5 and older do not support arr[0..nil] syntax, so
    # this must be a separate conditional.
    cursor_to_iterate = if limit_for_cached_query
      @cursor.to_a[0...limit_for_cached_query]
    else
      @cursor
    end

    cursor_to_iterate.each do |doc|
      yield doc
    end
  else
    @cursor.to_enum
  end
end

#initial_query_op(session) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 152

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: options[:let],
    limit: limit,
    allow_disk_use: options[:allow_disk_use],
    allow_partial_results: options[:allow_partial_results],
    read: read,
    read_concern: options[:read_concern] || read_concern,
    batch_size: batch_size,
    hint: options[:hint],
    max_scan: options[:max_scan],
    max_time_ms: options[:max_time_ms],
    max_value: options[:max_value],
    min_value: options[:min_value],
    no_cursor_timeout: options[:no_cursor_timeout],
    return_key: options[:return_key],
    show_disk_loc: options[:show_disk_loc],
    comment: options[:comment],
    oplog_replay: if (v = options[:oplog_replay]).nil?
      collection.options[:oplog_replay]
    else
      v
    end,
  }

  if spec[:oplog_replay]
    collection.client.log_warn("The :oplog_replay option is deprecated and ignored by MongoDB 4.4 and later")
  end

  maybe_set_tailable_options(spec)

  if explained?
    spec[:explain] = options[:explain]
    Operation::Explain.new(spec)
  else
    Operation::Find.new(spec)
  end
end

#kill_cursors

Alias for #close_query.

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 111

alias :kill_cursors :close_query

#maybe_set_tailable_options(spec) (private)

Add tailable cusror options to the command specifiction if needed.

Parameters:

  • spec (Hash)

    The command specification.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 210

def maybe_set_tailable_options(spec)
  case cursor_type
  when :tailable
    spec[:tailable] = true
  when :tailable_await
    spec[:tailable] = true
    spec[:await_data] = true
  end
end

#select_cursor(session) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 115

def select_cursor(session)
  if respond_to?(:write?, true) && write?
    server = server_selector.select_server(cluster, nil, session, write_aggregation: true)
    result = send_initial_query(server, session)

    if use_query_cache?
      CachingCursor.new(view, result, server, session: session)
    else
      Cursor.new(view, result, server, session: session)
    end
  else
    read_with_retry_cursor(session, server_selector, view) do |server|
      send_initial_query(server, session)
    end
  end
end

#send_initial_query(server, session = nil) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/collection/view/iterable.rb', line 199

def send_initial_query(server, session = nil)
  initial_query_op(session).execute(server, context: Operation::Context.new(client: client, session: session))
end