Skip to content

Commit fc75058

Browse files
author
Sam Kleinman
committed
merge: DOCS-675
2 parents 99c011e + 4ff79fa commit fc75058

File tree

3 files changed

+307
-23
lines changed

3 files changed

+307
-23
lines changed

source/applications/read.txt

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -329,27 +329,90 @@ Consider the following examples that illustrate the use of the
329329
Cursor
330330
~~~~~~
331331

332-
:method:`find() <db.collection.find()>` returns a :term:`cursor`;
333-
however, in the :program:`mongo` shell, the cursor is automatically
334-
iterated up to 20 times to print the documents referenced by the
335-
cursor. To access the documents, you must explicitly handle the
336-
cursor, as in the following example:
332+
The :method:`find() <db.collection.find()>` method returns a
333+
:term:`cursor` to the results; however, in the :program:`mongo` shell,
334+
if the returned cursor is not assigned to a variable, then the cursor
335+
is automatically iterated up to 20 times [#setShellBatchSize]_ to print
336+
up to the first 20 documents that match the query, as in the following
337+
example:
337338

338339
.. code-block:: javascript
339340

340-
var myCursor = db.bios.find( { _id: 1 } );
341+
db.bios.find( { _id: 1 } );
341342

342-
var myDocument = myCursor.hasNext() ? myCursor.next() : null;
343+
When you assign the :method:`find() <db.collection.find()>` to a
344+
variable:
343345

344-
if (myDocument) {
345-
var myName = myDocument.name;
346+
- you can type the name of the cursor variable to iterate up to 20
347+
times [#setShellBatchSize]_ and print the matching documents, as in
348+
the following example:
346349

347-
print (tojson(myName));
348-
}
350+
.. code-block:: javascript
351+
352+
var myCursor = db.bios.find( { _id: 1 } );
353+
354+
myCursor
355+
356+
- you can use the cursor method :method:`next() <cursor.next()>` to
357+
access the documents, as in the following example:
358+
359+
.. code-block:: javascript
360+
361+
var myCursor = db.bios.find( { _id: 1 } );
349362

350-
See the :method:`cursor.forEach()`, :method:`cursor.hasNext()`,
351-
:method:`cursor.next()` documentation for more information on cursor
352-
handling.
363+
var myDocument = myCursor.hasNext() ? myCursor.next() : null;
364+
365+
if (myDocument) {
366+
367+
var myName = myDocument.name;
368+
369+
print (tojson(myName));
370+
}
371+
372+
To print, you can also use the ``printjson()`` method instead of
373+
``print(tojson())``:
374+
375+
.. code-block:: javascript
376+
377+
if (myDocument) {
378+
379+
var myName = myDocument.name;
380+
381+
printjson(myName);
382+
}
383+
384+
- you can use the cursor method :method:`forEach() <cursor.forEach()>`
385+
to iterate the cursor and access the documents, as in the following
386+
example:
387+
388+
.. code-block:: javascript
389+
390+
var myCursor = db.bios.find( { _id: 1 } );
391+
392+
myCursor.forEach(printjson);
393+
394+
For more information on cursor handling, see:
395+
396+
- :method:`cursor.hasNext()`
397+
398+
- :method:`cursor.next()`
399+
400+
- :method:`cursor.forEach()`
401+
402+
- :ref:`cursors <read-operations-cursors>`
403+
404+
- :ref:`JavaScript cursor methods<js-query-cursor-methods>`
405+
406+
.. [#setShellBatchSize] You can use the ``DBQuery.shellBatchSize`` to
407+
change the number of iteration from the default value ``20``, as in the
408+
following example which sets the number to ``10`` :
409+
410+
.. code-block:: javascript
411+
412+
DBQuery.shellBatchSize = 10
413+
414+
Modify Cursor Behavior
415+
``````````````````````
353416

354417
In addition to the ``<query>`` and the ``<projection>`` arguments, the
355418
:program:`mongo` shell and the :doc:`drivers </applications/drivers>`
@@ -395,14 +458,36 @@ its behavior, such as:
395458

396459
db.bios.find().skip( 5 )
397460

398-
You may chain these cursor methods; however, the :method:`limit()
399-
<cursor.limit()>` method is always applied after the :method:`sort()
400-
<cursor.sort()>` even if you chain the methods in the reverse order:
461+
You can chain these cursor methods, as in the following examples [#dbquery-server]_:
401462

402463
.. code-block:: javascript
403464

465+
db.bios.find().sort( { name: 1 } ).limit( 5 )
404466
db.bios.find().limit( 5 ).sort( { name: 1 } )
405467

468+
See :ref:`JavaScript cursor methods <js-query-cursor-methods>` and your
469+
:doc:`driver </applications/drivers>` documentation for more
470+
information on cursor methods. See :ref:`read-operations-cursors` for
471+
more information regarding cursors.
472+
473+
.. [#dbquery-server] Regardless of the order you chain the :method:`limit()
474+
<cursor.limit()>` and the :method:`sort() <cursor.sort()>`, the
475+
request to the server has the following structure that treats the
476+
query and the :method:`sort() <cursor.sort()>` modifier as a single
477+
object:
478+
479+
.. code-block:: javascript
480+
481+
db.bios.find( { $query: {}, $orderby: { name: 1 } } ).limit( 5 )
482+
483+
This structure means that the :method:`limit() <cursor.limit()>`
484+
method is always applied after the :method:`sort() <cursor.sort()>`
485+
regardless of the order in which the client chains the two methods.
486+
487+
For other cursor modifiers that are sent with the
488+
query as a single object to the server, see the :doc:`meta query operators
489+
</reference/meta-query-operators>`.
490+
406491
.. _crud-read-findOne:
407492
.. _crud-read-find-one:
408493

source/core/document.txt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,9 @@ Consider the following options for the value of an ``_id`` field:
216216
additional index.
217217

218218
- Generate a sequence number for the documents in your collection in
219-
your application and use this value for the ``_id`` value.
220-
221-
.. TODO add the following when the tutorial is live
222-
223-
see the :doc:`/tutorial/create-an-auto-incrementing-field`
224-
tutorial for an implementation pattern.
219+
your application and use this value for the ``_id`` value. See the
220+
:doc:`/tutorial/create-an-auto-incrementing-field` tutorial for an
221+
implementation pattern.
225222

226223
- Generate a UUID in your application code. For efficiency, store
227224
the UUID as a value of the BSON ``BinData`` type to reduce the

source/core/read-operations.txt

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

666868
Aggregation

0 commit comments

Comments
 (0)