class Mongo::Cursor
Client-side representation of an iterator over a query result set on the server.
A Cursor
is not created directly by a user. Rather,
CollectionView
creates a Cursor
in an Enumerable
module method.
@example Get an array of 5 users named Emily.
users.find({:name => 'Emily'}).limit(5).to_a
@example Call a block on each user doc.
users.find.each { |doc| puts doc }
@note The Cursor
API is semipublic. @api semipublic
Attributes
@return [ Collection::View ] view The collection view.
Public Class Methods
Finalize the cursor for garbage collection. Schedules this cursor to be included in a killCursors operation executed by the Cluster's CursorReaper.
@example Finalize the cursor.
Cursor.finalize(id, cluster, op, server)
@param [ Integer ] cursor_id The cursor's id. @param [ Mongo::Cluster ] cluster The cluster associated with this cursor and its server. @param [ Hash ] op_spec The killCursors operation specification. @param [ Mongo::Server ] server The server to send the killCursors operation to.
@return [ Proc ] The Finalizer.
@since 2.3.0
# File lib/mongo/cursor.rb, line 91 def self.finalize(cursor_id, cluster, op_spec, server, session) proc do cluster.schedule_kill_cursor(cursor_id, op_spec, server) session.end_session if session && session.implicit? end end
Creates a Cursor
object.
@example Instantiate the cursor.
Mongo::Cursor.new(view, response, server)
@param [ CollectionView ] view The CollectionView
defining the
query. @param [ Operation::Result ]
result The result of the first execution. @param [ Server ] server The server this cursor is locked to.
@param [ Hash ] options The cursor options.
@option options [ true, false ] :disable_retry Whether to disable retrying on
error when sending getmores.
@since 2.0.0
# File lib/mongo/cursor.rb, line 59 def initialize(view, result, server, options = {}) @view = view @server = server @initial_result = result @remaining = limit if limited? @cursor_id = result.cursor_id @coll_name = nil @options = options @session = @options[:session] register ObjectSpace.define_finalizer(self, self.class.finalize(result.cursor_id, cluster, kill_cursors_op_spec, server, @session)) end
Public Instance Methods
Get the batch size.
@example Get the batch size.
cursor.batch_size
@return [ Integer ] The batch size.
@since 2.2.0
# File lib/mongo/cursor.rb, line 136 def batch_size @view.batch_size && @view.batch_size > 0 ? @view.batch_size : limit end
Is the cursor closed?
@example Is the cursor closed?
cursor.closed?
@return [ true, false ] If the cursor is closed.
@since 2.2.0
# File lib/mongo/cursor.rb, line 148 def closed? !more? end
Get the parsed collection name.
@example Get the parsed collection name.
cursor.coll_name
@return [ String ] The collection name.
@since 2.2.0
# File lib/mongo/cursor.rb, line 160 def collection_name @coll_name || collection.name end
Iterate through documents returned from the query.
@example Iterate over the documents in the cursor.
cursor.each do |doc| ... end
@return [ Enumerator ] The enumerator.
@since 2.0.0
# File lib/mongo/cursor.rb, line 120 def each process(@initial_result).each { |doc| yield doc } while more? return kill_cursors if exhausted? get_more.each { |doc| yield doc } end end
Get the cursor id.
@example Get the cursor id.
cursor.id
@note A cursor id of 0 means the cursor was closed on the server.
@return [ Integer ] The cursor id.
@since 2.2.0
# File lib/mongo/cursor.rb, line 174 def id @cursor_id end
Get a human-readable string representation of Cursor
.
@example Inspect the cursor.
cursor.inspect
@return [ String ] A string representation of a Cursor
instance.
@since 2.0.0
# File lib/mongo/cursor.rb, line 106 def inspect "#<Mongo::Cursor:0x#{object_id} @view=#{@view.inspect}>" end
Get the number of documents to return. Used on 3.0 and lower server versions.
@example Get the number to return.
cursor.to_return
@return [ Integer ] The number of documents to return.
@since 2.2.0
# File lib/mongo/cursor.rb, line 187 def to_return use_limit? ? @remaining : (batch_size || 0) end
Private Instance Methods
# File lib/mongo/cursor.rb, line 225 def end_session @session.end_session if @session && @session.implicit? end
# File lib/mongo/cursor.rb, line 193 def exhausted? limited? ? @remaining <= 0 : false end
# File lib/mongo/cursor.rb, line 197 def get_more if @options[:disable_retry] process(get_more_operation.execute(@server)) else read_with_retry do process(get_more_operation.execute(@server)) end end end
# File lib/mongo/cursor.rb, line 207 def get_more_operation if @server.features.find_command_enabled? Operation::Commands::GetMore.new(Builder::GetMoreCommand.new(self, @session).specification) else Operation::Read::GetMore.new(Builder::OpGetMore.new(self).specification) end end
# File lib/mongo/cursor.rb, line 215 def kill_cursors unregister read_with_one_retry do kill_cursors_operation.execute(@server) end ensure end_session @cursor_id = 0 end
# File lib/mongo/cursor.rb, line 237 def kill_cursors_op_spec if @server.features.find_command_enabled? Builder::KillCursorsCommand.new(self).specification else Builder::OpKillCursors.new(self).specification end end
# File lib/mongo/cursor.rb, line 229 def kill_cursors_operation if @server.features.find_command_enabled? Operation::Commands::Command.new(kill_cursors_op_spec) else Operation::KillCursors.new(kill_cursors_op_spec) end end
# File lib/mongo/cursor.rb, line 266 def limit @view.send(:limit) end
# File lib/mongo/cursor.rb, line 245 def limited? limit ? limit > 0 : false end
# File lib/mongo/cursor.rb, line 249 def more? @cursor_id != 0 end
# File lib/mongo/cursor.rb, line 253 def process(result) @remaining -= result.returned_count if limited? @coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace unregister if result.cursor_id == 0 @cursor_id = result.cursor_id end_session if !more? result.documents end
# File lib/mongo/cursor.rb, line 270 def register cluster.register_cursor(@cursor_id) end
# File lib/mongo/cursor.rb, line 274 def unregister cluster.unregister_cursor(@cursor_id) end
# File lib/mongo/cursor.rb, line 262 def use_limit? limited? && batch_size >= @remaining end