Cursor to iterate over a set of documents
After calling MongoDB::Collection.find()
to query the collection for data, a Cursor object is returned. With this cursor it is possible to iterate over the documents returned from the server. Cursor documents can also be returned from specific calls to MongoDB::Database.run-command()
. These documents must be converted to Cursor objects. See examples below.
unit class MongoDB::Cursor:auth<github:MARTIMM>:ver<0.2.0>;
also does Iterable;
First example using find().
my MongoDB::Client $client .= new(:uri<mongodb://>);
my MongoDB::Database $database = $client.database('contacts');
my MongoDB::Collection $collection = $database.collection('perl_users');
$d = $database.run-command(BSON::Document.new: (count => $collection.name));
say 'some docs are available' if $d<n>;
# Get all documents from this collection
my MongoDB::Cursor $cursor = $collection.find;
while $cursor.fetch -> BSON::Document $document { $document.perl.say; }
Second example using run-command to get information about collections
$doc = $database.run-command(BSON::Document.new: (listCollections => 1));
is $doc<ok>, 1, 'list collections request ok';
my MongoDB::Cursor $c0 .= new( :$client, :cursor-doc($doc<cursor>));
while $c0.fetch -> BSON::Document $d {
…
}
In both examples .find()
, .new()
can be combined with for
because of the iterable role used on class Cursor.
…
for $collection.find -> BSON::Document $document { … }
…
Or, when you want to save the cursor in a variable first, bind it! See also this blog.
my MongoDB::Cursor $c1 := $collection.find;
for $c1 -> BSON::Document $document { … }
and
$doc = $database.run-command(BSON::Document.new: (listCollections => 1));
for MongoDB::Cursor.new(
:$client, :cursor-doc($doc<cursor>)
) -> BSON::Document $d {
…
}
or
…
my MongoDB::Cursor $c2 := new( :$client, :cursor-doc($doc<cursor>));
for $c2 -> BSON::Document $document { … }
The variables $c1
and $c2
are not reusable after the loops are finished because they are bound to a MongoDB::Cursor container and an ‘assign to an immutable variable’ exception is thrown.
Create a Cursor object using the documents returned from a server. The server will never return all the documents at once but in bundles of ten. This is modifiable. When the last one of a bundle is read, the server is asked for more if there are any left.
There are two possibilities. The first is used by MongoDB::Colection.find()
and the second is called by the user if documents arrive using MongoDB::Database.run-vommand()
.
multi submethod BUILD (
MongoDB::Uri:D :$!uri-obj!, BSON::Document:D :$server-reply!,
Int :$number-to-return = 0, :$collection
)
multi submethod BUILD (
MongoDB::ClientType:D :$client!, BSON::Document:D :$cursor-doc!,
Int :$number-to-return = 0
)
MongoDB::Uri $!uri-obj; Information about uri.
BSON::Document $server-reply; Documents returned from server.
Int $number-to-return; Number of documents requested. 0 means, get all of it.
MongoDB::Collection $collection; The collection on wich the find() was called.
MongoDB::Client $client; The client object.
BSON::Document $cursor-doc; A part of a returned document holding specific cursor data. See one of the examples above.
Get the full representation of this collection. This is a string composed of the database name and collection name separated by a dot. E.g. person.address means collection address in database person.
method full-collection-name ( --> Str )
Not to be used directly. This is used when a for loop requests for an Iterator object. See also some of the examples above.
The blog explains a bit about this.
say $cursor.does(Iterable); # True
say $cursor.iterator.does(Iterator); # True
say $cursor.iterator.pull-one; # BSON::Document(…)
So, next is possible
for $collection.find( … ) -> BSON::Document $document { … }
Or, like so
my BSON::Cursor $cursor := $collection.find( … );
for $cursor -> BSON::Document $document { … }
Fetch a document using a cursor. When no documents are left, it returns an undefined document.
method fetch ( --> BSON::Document )
This example shows how to use it in a while loop
my MongoDB::Cursor $cursor .= new( … );
while $cursor.fetch -> BSON::Document $document { … }
Invalidate cursor. Server gets a message that other documents, ready to send, can be discarded.