Skip to content

DOCSP-29345 - Replace forEach #671

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 3 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 0 additions & 9 deletions source/code-snippets/crud/cursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ const uri =
"mongodb+srv://<user>:<password>@<cluster-url>?writeConcern=majority";
const client = new MongoClient(uri);

async function forEachIteration(myColl) {
// start foreach cursor example
const cursor = myColl.find({});
await cursor.forEach(doc => console.log(doc));
// end foreach cursor example
console.log(await myColl.countDocuments());
}

async function asyncIteration(myColl) {
// start async cursor example
const cursor = myColl.find({});
Expand Down Expand Up @@ -81,7 +73,6 @@ async function run() {
const database = client.db("test");
const orders = database.collection("orders");

await forEachIteration(orders);
await asyncIteration(orders);
await manualIteration(orders);
await streamAPI(orders);
Expand Down
16 changes: 12 additions & 4 deletions source/code-snippets/crud/startrek.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ async function word(movies) {
if ((await movies.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function phrase(movies) {
Expand All @@ -44,7 +46,9 @@ async function phrase(movies) {
if ((await movies.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function negation(movies) {
Expand All @@ -65,7 +69,9 @@ async function negation(movies) {
if ((await movies.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function relevance(movies) {
Expand All @@ -92,7 +98,9 @@ async function relevance(movies) {
if ((await movies.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function run() {
Expand Down
8 changes: 6 additions & 2 deletions source/code-snippets/crud/theaters.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ async function proximity(theaters) {
if ((await theaters.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function range(theaters) {
Expand Down Expand Up @@ -55,7 +57,9 @@ async function range(theaters) {
if ((await theaters.countDocuments(query)) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function run() {
Expand Down
20 changes: 15 additions & 5 deletions source/code-snippets/quick-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ async function query(coll) {
async function queryMany(coll) {
console.log("find");
const cursor = coll.find({ year: 2005 });
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function insertOne(coll) {
Expand Down Expand Up @@ -108,7 +110,9 @@ async function watchStart(coll) {

async function accessCursorIterative(coll) {
const cursor = coll.find().limit(10);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function accessCursorArray(coll) {
Expand All @@ -134,17 +138,23 @@ async function skipExample(coll) {

async function sortExample(coll) {
const cursor = coll.find().limit(50).sort({ year: 1});
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function projectExample(coll) {
const cursor = coll.find().project({ _id: 0, year: 1, imdb: 1 });
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function searchText(coll) {
const result = coll.find({$text: { $search: 'zissou' }}).limit(30).project({title: 1});
await result.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
}

async function distinct(coll) {
Expand Down
6 changes: 4 additions & 2 deletions source/code-snippets/usage-examples/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ async function run() {
console.log("No documents found!");
}

// replace console.dir with your callback to access individual elements
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

} finally {
await client.close();
}
Expand Down
4 changes: 3 additions & 1 deletion source/code-snippets/usage-examples/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ async function run() {
console.warn("No documents found!");
}

await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}
} finally {
await client.close();
}
Expand Down
20 changes: 15 additions & 5 deletions source/fundamentals/crud/query-document.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ documents containing a field called "name" that has a value of "apples":

const query = { "name": "apples" };
const cursor = myColl.find(query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code snippet returns the following results:

Expand Down Expand Up @@ -107,7 +109,9 @@ value greater than 5 and prints them out:
// $gt means "greater than"
const query = { qty: { $gt : 5 } };
const cursor = myColl.find(query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code snippet returns the following results:

Expand All @@ -131,7 +135,9 @@ that is not greater than 5 and prints them out:

const query = { qty: { $not: { $gt: 5 }}};
const cursor = myColl.find(query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code snippet returns the following results:

Expand Down Expand Up @@ -179,7 +185,9 @@ field:

const query = { microsieverts: { $exists: true } };
const cursor = myColl.find(query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code snippet returns the following results:

Expand All @@ -206,7 +214,9 @@ a remainder of 0:
// $mod means "modulo" and returns the remainder after division
const query = { qty: { $mod: [ 3, 0 ] } };
const cursor = myColl.find(query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code snippet returns the following results:

Expand Down
51 changes: 19 additions & 32 deletions source/fundamentals/crud/read-operations/cursor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pulling all matching documents into a collection in process memory.
.. warning::

Do not combine different cursor paradigms on a single cursor.
Operations such as ``hasNext()``, ``forEach()``, and ``toArray()``
Operations such as ``hasNext()`` and ``toArray()``
each predictably modify the original cursor. If you mix these calls
on a single cursor, you may receive unexpected results.

Expand All @@ -68,44 +68,14 @@ pulling all matching documents into a collection in process memory.
fetch, the cursor is exhausted which means it ceases to respond to methods
that access the results.

.. _node-fundamentals-cursor-foreach:

For Each Functional Iteration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can pass a function to the `forEach() <{+api+}/classes/FindCursor.html#forEach>`__ method of any cursor to iterate through
results in a functional style:

.. literalinclude:: /code-snippets/crud/cursor.js
:language: javascript
:start-after: start foreach cursor example
:end-before: end foreach cursor example

.. _node-fundamentals-cursor-array:

Return an Array of All Documents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For use cases that require all documents matched by a query to be held
in memory at the same time, use `toArray() <{+api+}/classes/FindCursor.html#toArray>`__.
Note that large numbers of matched documents can cause performance issues
or failures if the operation exceeds memory constraints. Consider using
`forEach() <{+api+}/classes/FindCursor.html#forEach>`__ to iterate
through results unless you want to return all documents at once.

.. literalinclude:: /code-snippets/crud/cursor.js
:language: javascript
:start-after: start fetchAll cursor example
:end-before: end fetchAll cursor example

.. _node-fundamentals-async-iteration:

Asynchronous Iteration
~~~~~~~~~~~~~~~~~~~~~~

Cursors implement the :mdn:`AsyncIterator
<Web/JavaScript/Reference/Statements/for-await...of>` interface, which
allows you to use cursors in ``for``...``await`` loops:
allows you to use cursors in ``for await...of`` loops:

.. literalinclude:: /code-snippets/crud/cursor.js
:language: javascript
Expand All @@ -125,6 +95,23 @@ method to retrieve the subsequent element of the cursor:
:start-after: start manual cursor example
:end-before: end manual cursor example

.. _node-fundamentals-cursor-array:

Return an Array of All Documents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For use cases that require all documents matched by a query to be held
in memory at the same time, use the `toArray() <{+api+}/classes/FindCursor.html#toArray>`__
method. Note that large numbers of matched documents can cause performance issues
or failures if the operation exceeds memory constraints. Consider using
the ``for await...of`` syntax to iterate
through results rather than returning all documents at once.

.. literalinclude:: /code-snippets/crud/cursor.js
:language: javascript
:start-after: start fetchAll cursor example
:end-before: end fetchAll cursor example

Stream API
~~~~~~~~~~

Expand Down
12 changes: 9 additions & 3 deletions source/fundamentals/crud/read-operations/distinct.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ unique values of the ``borough`` field:

// specify "borough" as the field to return values for
const cursor = myColl.distinct("borough");
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This code outputs the following ``borough`` values:

Expand Down Expand Up @@ -98,7 +100,9 @@ excludes restaurants in "``Brooklyn``":

// find the filtered distinct values of "cuisine"
const cursor = myColl.distinct("cuisine", query);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

In this case, the query filter matches every borough value except for "``Brooklyn``". This
prevents ``distinct()`` from outputting one ``cuisine`` value, "``Middle Eastern``".
Expand Down Expand Up @@ -137,7 +141,9 @@ conventions when outputting the distinct ``restaurant`` values:
const options = { collation: { locale: "de" }};

const cursor = myColl.distinct("restaurant", query, options);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

In this case, German string ordering conventions place words beginning with "Ä" before
those beginning with "B". The code outputs the following:
Expand Down
10 changes: 7 additions & 3 deletions source/fundamentals/crud/read-operations/limit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ snippet to insert documents that describe books into the
{ "_id": 3, "name": "Atlas Shrugged", "author": "Rand", "length": 1088 },
{ "_id": 4, "name": "Infinite Jest", "author": "Wallace", "length": 1104 },
{ "_id": 5, "name": "Cryptonomicon", "author": "Stephenson", "length": 918 },
{ "_id": 6, "name": "A Dance With Dragons", "author": "Tolkein", "length": 1104 },
{ "_id": 6, "name": "A Dance With Dragons", "author": "Martin", "length": 1104 },
]);

.. include:: /includes/access-cursor-note.rst
Expand All @@ -64,7 +64,9 @@ books, and applies a ``limit`` to return only ``3`` results:
const sort = { length: -1 };
const limit = 3;
const cursor = myColl.find(query).sort(sort).limit(limit);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir;
}

The code example above outputs the following three documents, sorted by
length:
Expand Down Expand Up @@ -116,7 +118,9 @@ passing the number of documents to bypass as shown below:
const limit = 3;
const skip = 3;
const cursor = myColl.find(query).sort(sort).limit(limit).skip(skip);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir;
}

This operation returns the documents that describe the fourth through sixth
books in order of longest-to-shortest length:
Expand Down
12 changes: 9 additions & 3 deletions source/fundamentals/crud/read-operations/project.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ field of each document:
// return only* the name field
const projection = { name: 1 };
const cursor = myColl.find().project(projection);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

The projection document specifies a value of ``1`` for ``name`` to
indicate that the read operation result should *include* the ``name``
Expand Down Expand Up @@ -104,7 +106,9 @@ returned documents.
// return only the name field
const projection = { _id: 0, name: 1 };
const cursor = myColl.find().project(projection);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

The projection document specifies a value of ``1`` for ``name`` to
indicate that the read operation result should *include* the ``name``
Expand Down Expand Up @@ -132,7 +136,9 @@ order in which they are returned.

const projection = { _id: 0, rating: 1, name: 1 };
const cursor = myColl.find().project(projection);
await cursor.forEach(console.dir);
for await (const doc of cursor) {
console.dir(doc);
}

This example that identifies two fields to include in the projection yields
the following results:
Expand Down
Loading