Skip to content

Query cursor 1 #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Dec 14, 2012
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 37 additions & 8 deletions source/applications/read.txt
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,23 @@ Consider the following examples that illustrate the use of the
Cursor
~~~~~~

:method:`find() <db.collection.find()>` returns a :term:`cursor`;
however, in the :program:`mongo` shell, the cursor is automatically
iterated up to 20 times to print the documents referenced by the
cursor. To access the documents, you must explicitly handle the
cursor, as in the following example:
The :method:`find() <db.collection.find()>` method returns a
:term:`cursor`; however, in the :program:`mongo` shell, if the result
of the :method:`find() <db.collection.find()>` is not assigned to a
variable, then the cursor is automatically iterated up to 20 times to
print the documents referenced by the cursor, as in the following
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/reference/collected/?

example:

.. code-block:: javascript

db.bios.find( { _id: 1 } );

This operation will iterate the cursor up to 20 times and print the
first 20 documents referenced by the cursor.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iterate and print the first 20 documents collected by the cursor?

(collected? returned? the cursor isn't a list of references, so referenced isn't the right word, and we haven't settled on a consistent term here.)


If the result of the :method:`find() <db.collection.find()>` is
assigned to a variable, you can use the cursor method :method:`next()
<cursor.next()>` to access the documents, as in the following example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you assign a variable to a query....


.. code-block:: javascript

Expand All @@ -345,9 +357,21 @@ cursor, as in the following example:
print (tojson(myName));
}

See the :method:`cursor.forEach()`, :method:`cursor.hasNext()`,
:method:`cursor.next()` documentation for more information on cursor
handling.
For more information on cursor handling, see:

- :method:`cursor.hasNext()`

- :method:`cursor.next()`

- :method:`cursor.forEach()`

- :ref:`cursors <read-operations-cursors>`

- :ref:`JavaScript cursor methods<js-query-cursor-methods>`


Modify Cursor Behavior
``````````````````````

In addition to the ``<query>`` and the ``<projection>`` arguments, the
:program:`mongo` shell and the :doc:`drivers </applications/drivers>`
Expand Down Expand Up @@ -401,6 +425,11 @@ You may chain these cursor methods; however, the :method:`limit()

db.bios.find().limit( 5 ).sort( { name: 1 } )

See :ref:`JavaScript cursor methods <js-query-cursor-methods>` and your
:doc:`driver </applications/drivers>` documentation for more
information on cursor methods. See :ref:`read-operations-cursors` for
more information regarding cursors.

.. _crud-read-findOne:
.. _crud-read-find-one:

Expand Down
9 changes: 3 additions & 6 deletions source/core/document.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,9 @@ Consider the following options for the value of an ``_id`` field:
additional index.

- Generate a sequence number for the documents in your collection in
your application and use this value for the ``_id`` value.

.. TODO add the following when the tutorial is live

see the :doc:`/tutorial/create-an-auto-incrementing-field`
tutorial for an implementation pattern.
your application and use this value for the ``_id`` value. See the
:doc:`/tutorial/create-an-auto-incrementing-field` tutorial for an
implementation pattern.

- Generate a UUID in your application code. For efficiency, store
the UUID as a value of the BSON ``BinData`` type to reduce the
Expand Down
139 changes: 138 additions & 1 deletion source/core/read-operations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ the query used an index. This query:
- returned 5 documents, as indicated by the :data:`n` field;

- scanned 5 documents from the index, as indicated by the
:data:`nscanned`` field;
:data:`nscanned` field;

- then read 5 full documents from the collection, as indicated by
the :data:`nscannedObjects` field.
Expand Down Expand Up @@ -656,6 +656,143 @@ indexes at all. Consider the following situations:
cannot use an index. *However*, the regular expression with anchors
to the beginning of a string *can* use an index.

.. _read-operations-cursors:

Cursors
-------

The :method:`find() <db.collection.find()>` method returns a
:term:`cursor`; however, in the :program:`mongo` shell, if the result
of the :method:`find() <db.collection.find()>` is not assigned to a
variable, then the cursor is automatically iterated up to 20 times to
print the documents referenced by the cursor, as in the following
example:

.. code-block:: javascript

db.inventory.find( { type: 'food' } );

This operation will iterate the cursor up to 20 times and print the
first 20 documents referenced by the cursor.

If the result of the :method:`find() <db.collection.find()>` is
assigned to a variable, you can use the cursor method :method:`next()
<cursor.next()>` to access the documents, as in the following example:

.. code-block:: javascript

var myCursor = db.inventory.find( { type: 'food' } );

var myDocument = myCursor.hasNext() ? myCursor.next() : null;

if (myDocument) {
var myItem = myDocument.item;

print (tojson(myItem));
}

See :ref:`JavaScript cursor methods <js-query-cursor-methods>` and your
:doc:`driver </applications/drivers>` documentation for more
information on cursor methods.

Array Mode
~~~~~~~~~~

Additionally, with some of the :doc:`drivers </applications/drivers>`,
you can use the cursor in "array mode" and access the documents with an
index (i.e. ``cursor[index]``), as in the following example:

.. code-block:: javascript

var myCursor = db.inventory.find( { type: 'food' } );

for (var idx = 0; idx < myCursor.length(); idx++ ){
myDoc = myCursor[idx];
print (tojson(myDoc));
}

The "array mode" loads into RAM the documents up to the highest
specified index and should not be used for queries which may return
very large number of data that may exceed memory.

You can also convert the cursor explicitly to an array, as in the following:

.. code-block:: javascript

var myCursor = db.inventory.find( { type: 'food' } );
var documentArray = myCursor.toArray();

The ``toArray()`` method loads into RAM all documents returned by the cursor.

.. TODO link to toArray() method once the page has been added

Consider the following behaviors related to cursors:

- By default, the server will automatically close the cursor after 10
minutes of inactivity or if the cursor has been exhausted. To
override this behavior, you can specify the "noTimeout" :wiki:`wire
protocol option <Mongo Wire Protocol>` in your query; however, you
should either close the cursor manually or exhaust the cursor. In the
:program:`mongo` shell, you can set the "noTimeout" option. See your
:doc:`driver </applications/drivers>` documentation for information
on setting the "noTimeout" option.

- Write operations may interleave during latent access to the cursor.
This may cause a document to be returned multiple times. To handle
this situation, see the information on :wiki:`snapshot mode <How to do
Snapshotted Queries in the Mongo Database>`.

.. TODO link instead to faq snapshot when that becomes available.

- The MongoDB server returns the query results in batches:

- For most queries, the default size of each batch is either 101
documents or enough documents to exceed 1 megabyte, whichever
condition is met first. To override the default size of each batch,
see :method:`cursor.batchSize()` and :method:`cursor.limit()`.

- For queries that include a sort operation *without* an index, the
server must load all the documents in memory to perform the sort
and will return all documents in the first batch.

- Batch size cannot exceed the :ref:`maximum BSON document size
<limit-bson-document-size>`.

- As you iterate through the cursor and reach the end of that batch,
if there are more results, :method:`cursor.next()` will perform a
:data:`getmore operation <op>` to retrieve the next batch.

To see how many documents remain in the batch as you iterate the
cursor, you can use the :method:`cursor.objsLeftInBatch()` method,
as in the following example:

.. code-block:: javascript

var myCursor = db.inventory.find();

var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;

myCursor.objsLeftInBatch();

- Batch results may provide performance benefits if you only need to
access a subset of the results, as in the following example which only
requires the first two documents:

.. code-block:: javascript

var myCursor = db.inventory.find();

var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
var mySecondDocument = myCursor.hasNext() ? myCursor.next() : null;

- You can retrieve cursor information, such as the number of open
cursors, using the command :dbcommand:`cursorInfo`, as in the
following example:

.. code-block:: javascript

db.runCommand( { cursorInfo: 1 } )

.. _read-operations-aggregation:

Aggregation
Expand Down