@@ -661,6 +661,208 @@ indexes at all. Consider the following situations:
661661 cannot use an index. *However*, the regular expression with anchors
662662 to the beginning of a string *can* use an index.
663663
664+ .. _read-operations-cursors:
665+
666+ Cursors
667+ -------
668+
669+ The :method:`find() <db.collection.find()>` method returns a
670+ :term:`cursor` to the results; however, in the :program:`mongo` shell,
671+ if the returned cursor is not assigned to a variable, then the cursor
672+ is automatically iterated up to 20 times [#setShellBatchSize]_ to print
673+ up to the first 20 documents that match the query, as in the following
674+ example:
675+
676+ .. code-block:: javascript
677+
678+ db.inventory.find( { type: 'food' } );
679+
680+ When you assign the :method:`find() <db.collection.find()>` to a
681+ variable:
682+
683+ - you can type the name of the cursor variable to iterate up to 20
684+ times [#setShellBatchSize]_ and print the matching documents, as in
685+ the following example:
686+
687+ .. code-block:: javascript
688+
689+ var myCursor = db.inventory.find( { type: 'food' } );
690+
691+ myCursor
692+
693+ - you can use the cursor method :method:`next() <cursor.next()>` to
694+ access the documents, as in the following example:
695+
696+ .. code-block:: javascript
697+
698+ var myCursor = db.inventory.find( { type: 'food' } );
699+
700+ var myDocument = myCursor.hasNext() ? myCursor.next() : null;
701+
702+ if (myDocument) {
703+
704+ var myItem = myDocument.item;
705+
706+ print(tojson(myItem));
707+ }
708+
709+ To print, you can also use the ``printjson()`` method instead of
710+ ``print(tojson())``:
711+
712+ .. code-block:: javascript
713+
714+ if (myDocument) {
715+
716+ var myItem = myDocument.item;
717+
718+ printjson(myItem);
719+ }
720+
721+ - you can use the cursor method :method:`forEach() <cursor.forEach()>`
722+ to iterate the cursor and access the documents, as in the following
723+ example:
724+
725+ .. code-block:: javascript
726+
727+ var myCursor = db.inventory.find( { type: 'food' } );
728+
729+ myCursor.forEach(printjson);
730+
731+ See :ref:`JavaScript cursor methods <js-query-cursor-methods>` and your
732+ :doc:`driver </applications/drivers>` documentation for more
733+ information on cursor methods.
734+
735+ .. [#setShellBatchSize] You can use the ``DBQuery.shellBatchSize`` to
736+ change the number of iteration from the default value ``20``, as in the
737+ following example which sets the number to ``10``:
738+
739+ .. code-block:: javascript
740+
741+ DBQuery.shellBatchSize = 10
742+
743+ Iterator Index
744+ ~~~~~~~~~~~~~~
745+
746+ In the :program:`mongo` shell, you can use the ``toArray()`` method to
747+ iterate the cursor and return the documents in an array, as in the
748+ following:
749+
750+ .. code-block:: javascript
751+
752+ var myCursor = db.inventory.find( { type: 'food' } );
753+ var documentArray = myCursor.toArray();
754+ var myDocument = documentArray[3];
755+
756+ The ``toArray()`` method loads into RAM all documents returned by the
757+ cursor; the ``toArray()`` method exhausts the cursor.
758+
759+ Additionally, some :doc:`drivers </applications/drivers>` provide
760+ access to the documents by using an index on the cursor (i.e.
761+ ``cursor[index]``). This is a shortcut for first calling the
762+ ``toArray()`` method and then using an index on the resulting array.
763+
764+ Consider the following example:
765+
766+ .. code-block:: javascript
767+
768+ var myCursor = db.inventory.find( { type: 'food' } );
769+ var myDocument = myCursor[3];
770+
771+ The ``myCursor[3]`` is equivalent to the following example:
772+
773+ .. code-block:: javascript
774+
775+ myCursor.toArray() [3];
776+
777+ .. TODO link to toArray() method once the page has been added
778+
779+ Cursor Considerations
780+ ~~~~~~~~~~~~~~~~~~~~~
781+
782+ Consider the following behaviors related to cursors:
783+
784+ - By default, the server will automatically close the cursor after 10
785+ minutes of inactivity or if the cursor has been exhausted. To
786+ override this behavior, you can specify the ``noTimeout`` :wiki:`wire
787+ protocol flag <Mongo Wire Protocol>` in your query; however, you
788+ should either close the cursor manually or exhaust the cursor. In the
789+ :program:`mongo` shell, you can set the ``noTimeout`` flag
790+ [#queryOptions]_:
791+
792+ .. code-block:: javascript
793+
794+ var myCursor = db.inventory.find().addOption(DBQuery.Option.noTimeout);
795+
796+ See your :doc:`driver </applications/drivers>` documentation for
797+ information on setting the ``noTimeout`` flag.
798+
799+ - Because the cursor is not isolated during its lifetime, intervening
800+ write operations may cause a document to be returned multiple times.
801+ To handle this situation, see the information on :wiki:`snapshot mode
802+ <How to do Snapshotted Queries in the Mongo Database>`.
803+
804+ - The MongoDB server returns the query results in batches:
805+
806+ - For most queries, the *first* batch returns 101 documents or just
807+ enough documents to exceed 1 megabyte. Subsequent batch size is 4
808+ megabytes. To override the default size of the batch, see
809+ :method:`cursor.batchSize()` and :method:`cursor.limit()`.
810+
811+ - For queries that include a sort operation *without* an index, the
812+ server must load all the documents in memory to perform the sort
813+ and will return all documents in the first batch.
814+
815+ - Batch size will not exceed the :ref:`maximum BSON document size
816+ <limit-bson-document-size>`.
817+
818+ - As you iterate through the cursor and reach the end of the returned
819+ batch, if there are more results, :method:`cursor.next()` will
820+ perform a :data:`getmore operation <op>` to retrieve the next batch.
821+
822+ To see how many documents remain in the batch as you iterate the
823+ cursor, you can use the :method:`cursor.objsLeftInBatch()` method,
824+ as in the following example:
825+
826+ .. code-block:: javascript
827+
828+ var myCursor = db.inventory.find();
829+
830+ var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
831+
832+ myCursor.objsLeftInBatch();
833+
834+ - You can use the command :dbcommand:`cursorInfo` to retrieve the
835+ following information on cursors:
836+
837+ - total number of open cursors
838+
839+ - size of the client cursors in current use
840+
841+ - number of timed out cursors since the last server restart
842+
843+ Consider the following example:
844+
845+ .. code-block:: javascript
846+
847+ db.runCommand( { cursorInfo: 1 } )
848+
849+ The result from the command returns the following documentation:
850+
851+ .. code-block:: javascript
852+
853+ { "totalOpen" : <number>, "clientCursors_size" : <number>, "timedOut" : <number>, "ok" : 1 }
854+
855+ .. [#queryOptions] In the :program:`mongo` shell, the cursor flags
856+ available are:
857+
858+ - ``DBQuery.Option.tailable``
859+ - ``DBQuery.Option.slaveOk``
860+ - ``DBQuery.Option.oplogReplay``
861+ - ``DBQuery.Option.noTimeout``
862+ - ``DBQuery.Option.awaitData``
863+ - ``DBQuery.Option.exhaust``
864+ - ``DBQuery.Option.partial``
865+
664866.. _read-operations-aggregation:
665867
666868Aggregation
0 commit comments