From be3830316b497fedbba18ea0b712e12c83e9b4e5 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Mon, 12 Aug 2024 14:06:30 -0400 Subject: [PATCH 1/5] DOCSP-39705: Cursors --- source/includes/read-ops/cursors.java | 44 +++++++++++ source/read-data-from-mongo.txt | 1 + source/read/cursors.txt | 104 ++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 source/includes/read-ops/cursors.java create mode 100644 source/read/cursors.txt diff --git a/source/includes/read-ops/cursors.java b/source/includes/read-ops/cursors.java new file mode 100644 index 00000000..763f1db2 --- /dev/null +++ b/source/includes/read-ops/cursors.java @@ -0,0 +1,44 @@ +import com.mongodb.ConnectionString; +import com.mongodb.CursorType; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.model.Filters; +import com.mongodb.reactivestreams.client.*; +import org.bson.Document; +import reactor.core.publisher.Flux; + +import java.util.List; + +public class Cursors { + public static void main(String[] args) { + String uri = ""; + + MongoClientSettings settings = MongoClientSettings.builder() + .applyConnectionString(new ConnectionString(uri)) + .build(); + + try (MongoClient mongoClient = MongoClients.create(settings)) + { + MongoDatabase database = mongoClient.getDatabase("sample_restaurants"); + MongoCollection collection = database.getCollection("restaurants"); + + // start-cursor-iterate + FindPublisher findPublisher = collection.find(); + + Flux.from(findPublisher) + .doOnNext(x -> System.out.println(x.getString("name"))) + .blockLast(); + // end-cursor-iterate + + // start-cursor-list + FindPublisher findPublisher = collection.find(Filters.eq("name", "Dunkin' Donuts")); + List resultsList = Flux.from(findPublisher).collectList().block(); + // end-cursor-list + + // start-tailable-cursor + FindPublisher findPublisher = collection.find().cursorType(CursorType.TailableAwait); + Flux.from(findPublisher) + .doOnNext(System.out::println) + .blockLast(); + // end-tailable-cursor + } + } diff --git a/source/read-data-from-mongo.txt b/source/read-data-from-mongo.txt index 580ddc4e..b62af563 100644 --- a/source/read-data-from-mongo.txt +++ b/source/read-data-from-mongo.txt @@ -27,6 +27,7 @@ Read Data From MongoDB /read/specify-fields-return /read/specify-documents-to-return /read/count-documents + /read/cursors /read/read-preference /read/text-search /read/geo diff --git a/source/read/cursors.txt b/source/read/cursors.txt new file mode 100644 index 00000000..17665e66 --- /dev/null +++ b/source/read/cursors.txt @@ -0,0 +1,104 @@ +.. _java-rs-cursors: + +========================= +Access Data From a Cursor +========================= + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, results, oplog + +Overview +-------- + +In this guide, you can learn how to access data from a **cursor** with the +{+driver-short+}. + +A cursor is a mechanism that returns the results of a read operation in iterable +batches. Because a cursor holds only a subset of documents at any given time, +cursors reduce both memory consumption and network bandwidth usage. + +Whenever the {+driver-short+} performs a read operation that returns multiple +documents, it automatically returns those documents in a cursor. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``sample_restaurants.restaurants`` collection +from the :atlas:`Atlas sample datasets `. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see the +:ref:`` guide. + +.. include:: includes/reactor-note.rst + +Access Cursor Contents Iteratively +---------------------------------- + +To iterate over the contents of a cursor, use the ``Flux.from()`` method, as shown in the +following example: + +.. literalinclude:: /includes/read-ops/cursors.java + :start-after: start-cursor-iterate + :end-before: end-cursor-iterate + :language: java + :dedent: + :copyable: + +Retrieve All Documents +---------------------- + +.. warning:: + + If the number and size of documents returned by your query exceeds available + application memory, your program will crash. If you expect a large result + set, :ref:`access your cursor iteratively `. + +To retrieve all documents from a cursor, convert the cursor into a ``List`` as +shown in the following example: + +.. literalinclude:: /includes/read-ops/cursors.java + :start-after: start-cursor-list + :end-before: end-cursor-list + :language: java + :dedent: + :copyable: + +Tailable Cursors +---------------- + +When querying on a :manual:`capped collection `, you +can use a **tailable cursor** that remains open after the client exhausts the +results in a cursor. To create a tailable cursor with capped collection, +specify ``CursorType.TailableAwait`` to the ``cursorType`` method of a +``FindPublisher`` object. + +The following example creates a tailable cursor on a collection: + +.. literalinclude:: /includes/read-ops/cursors.java + :start-after: start-tailable-cursor + :end-before: end-tailable-cursor + :language: java + :dedent: + :copyable: + +To learn more about tailable cursors and their usage, see the :manual:`Tailable Cursors guide +` in the {+mdb-server+} manual. + +API Documentation +----------------- + +To learn more about any of the methods or types discussed in this +guide, see the following API documentation: + +- `find() <{+api+}/mongodb-driver-reactivestreams/com/mongodb/reactivestreams/client/MongoCollection.html#find()>`__ +- `FindPublisher <{+api+}/mongodb-driver-reactivestreams/com/mongodb/reactivestreams/client/FindPublisher.html>`__ +- `CursorType <{+api+}/mongodb-driver-core/com/mongodb/CursorType.html>`__ From 63b72f2d115a6a03cd570a5b5659fa74c96bb9db Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 14 Aug 2024 16:25:23 -0400 Subject: [PATCH 2/5] Fix --- source/includes/read-ops/cursors.java | 1 - 1 file changed, 1 deletion(-) diff --git a/source/includes/read-ops/cursors.java b/source/includes/read-ops/cursors.java index 763f1db2..c3018c17 100644 --- a/source/includes/read-ops/cursors.java +++ b/source/includes/read-ops/cursors.java @@ -23,7 +23,6 @@ public static void main(String[] args) { // start-cursor-iterate FindPublisher findPublisher = collection.find(); - Flux.from(findPublisher) .doOnNext(x -> System.out.println(x.getString("name"))) .blockLast(); From bc76afdc5def405d154e98b9484a0000484e4f54 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 15 Aug 2024 10:43:39 -0400 Subject: [PATCH 3/5] Address NR feedback --- source/read/cursors.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/read/cursors.txt b/source/read/cursors.txt index 17665e66..51b5ecc1 100644 --- a/source/read/cursors.txt +++ b/source/read/cursors.txt @@ -20,7 +20,7 @@ Access Data From a Cursor Overview -------- -In this guide, you can learn how to access data from a **cursor** with the +In this guide, you can learn how to access data from a **cursor** by using the {+driver-short+}. A cursor is a mechanism that returns the results of a read operation in iterable @@ -62,7 +62,7 @@ Retrieve All Documents application memory, your program will crash. If you expect a large result set, :ref:`access your cursor iteratively `. -To retrieve all documents from a cursor, convert the cursor into a ``List`` as +To retrieve all documents from a cursor, convert the cursor into a ``List``, as shown in the following example: .. literalinclude:: /includes/read-ops/cursors.java @@ -77,11 +77,11 @@ Tailable Cursors When querying on a :manual:`capped collection `, you can use a **tailable cursor** that remains open after the client exhausts the -results in a cursor. To create a tailable cursor with capped collection, -specify ``CursorType.TailableAwait`` to the ``cursorType`` method of a +results in a cursor. To create a tailable cursor on a capped collection, +pass a value of ``CursorType.TailableAwait`` to the ``cursorType()`` method of a ``FindPublisher`` object. -The following example creates a tailable cursor on a collection: +The following example creates a tailable cursor on a collection and prints its contents: .. literalinclude:: /includes/read-ops/cursors.java :start-after: start-tailable-cursor From 9de75756d065bd91daeae090c1618316ef5839a1 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 29 Aug 2024 09:18:36 -0400 Subject: [PATCH 4/5] Address RL technical feedback --- source/read/cursors.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/read/cursors.txt b/source/read/cursors.txt index 51b5ecc1..e5dfa4b0 100644 --- a/source/read/cursors.txt +++ b/source/read/cursors.txt @@ -30,6 +30,11 @@ cursors reduce both memory consumption and network bandwidth usage. Whenever the {+driver-short+} performs a read operation that returns multiple documents, it automatically returns those documents in a cursor. +In the {+driver-short+}, some streams are backed by cursors. The size of batches used +in these underlying cursors depends on the demand requested on the ``Subscription`` for the +``Publisher``. The batch size of data contained by each underlying cursor can be set by +using the ``FindPublisher.batchSize()`` method. + Sample Data ~~~~~~~~~~~ @@ -40,6 +45,8 @@ free MongoDB Atlas cluster and load the sample datasets, see the .. include:: includes/reactor-note.rst +.. _java-rs-cursors-iterate: + Access Cursor Contents Iteratively ---------------------------------- @@ -60,7 +67,7 @@ Retrieve All Documents If the number and size of documents returned by your query exceeds available application memory, your program will crash. If you expect a large result - set, :ref:`access your cursor iteratively `. + set, :ref:`access your cursor iteratively `. To retrieve all documents from a cursor, convert the cursor into a ``List``, as shown in the following example: From 4dc413842f76d47c5c0fc61eecc29d949580610d Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 29 Aug 2024 12:05:23 -0400 Subject: [PATCH 5/5] Fix --- source/read/cursors.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/read/cursors.txt b/source/read/cursors.txt index e5dfa4b0..5b2f1af2 100644 --- a/source/read/cursors.txt +++ b/source/read/cursors.txt @@ -27,9 +27,6 @@ A cursor is a mechanism that returns the results of a read operation in iterable batches. Because a cursor holds only a subset of documents at any given time, cursors reduce both memory consumption and network bandwidth usage. -Whenever the {+driver-short+} performs a read operation that returns multiple -documents, it automatically returns those documents in a cursor. - In the {+driver-short+}, some streams are backed by cursors. The size of batches used in these underlying cursors depends on the demand requested on the ``Subscription`` for the ``Publisher``. The batch size of data contained by each underlying cursor can be set by