@@ -73,6 +73,37 @@ const usersInNY = await queryLeaf.execute(`
7373` );
7474```
7575
76+ ### Using Cursors for Large Result Sets
77+
78+ ``` typescript
79+ // Use cursor for memory-efficient processing of large result sets
80+ const cursor = await queryLeaf .executeCursor (`
81+ SELECT _id, customer, total, items
82+ FROM orders
83+ WHERE status = 'completed'
84+ ` );
85+
86+ try {
87+ // Process one document at a time without loading everything in memory
88+ let totalRevenue = 0 ;
89+ await cursor .forEach (order => {
90+ // Process each order individually
91+ totalRevenue += order .total ;
92+
93+ // Access and process nested data
94+ order .items .forEach (item => {
95+ // Process each item in the order
96+ console .log (` Order ${order ._id }: ${item .quantity }x ${item .name } ` );
97+ });
98+ });
99+
100+ console .log (` Total revenue: $${totalRevenue } ` );
101+ } finally {
102+ // Always close the cursor when done
103+ await cursor .close ();
104+ }
105+ ```
106+
76107### Array Element Access
77108
78109``` typescript
@@ -169,11 +200,11 @@ async function getUserDashboardData(userId) {
169200}
170201```
171202
172- ### Product Catalog with Filtering
203+ ### Product Catalog with Filtering and Cursor-Based Pagination
173204
174205``` typescript
175- // Product catalog with filtering
176- async function getProductCatalog(filters = {}) {
206+ // Product catalog with filtering and cursor-based pagination
207+ async function getProductCatalog(filters = {}, useCursor = false ) {
177208 const client = new MongoClient (' mongodb://localhost:27017' );
178209 await client .connect ();
179210
@@ -217,9 +248,52 @@ async function getProductCatalog(filters = {}) {
217248 query += ` LIMIT ${filters .limit } ` ;
218249 }
219250
220- // Execute query
221- return await queryLeaf .execute (query );
251+ if (filters .offset ) {
252+ query += ` OFFSET ${filters .offset } ` ;
253+ }
254+
255+ // Execute query with or without cursor based on preference
256+ if (useCursor ) {
257+ // Return a cursor for client-side pagination or streaming
258+ return await queryLeaf .executeCursor (query );
259+ } else {
260+ // Return all results at once (traditional approach)
261+ return await queryLeaf .execute (query );
262+ }
263+ } catch (error ) {
264+ console .error (' Error fetching product catalog:' , error );
265+ throw error ;
266+ } finally {
267+ if (! useCursor ) {
268+ // If we returned a cursor, the caller is responsible for closing the client
269+ // after they are done with the cursor
270+ await client .close ();
271+ }
272+ }
273+ }
274+
275+ // Example of using the product catalog with cursor
276+ async function streamProductCatalog() {
277+ const client = new MongoClient (' mongodb://localhost:27017' );
278+ await client .connect ();
279+
280+ let cursor = null ;
281+ try {
282+ const queryLeaf = new QueryLeaf (client , ' store' );
283+ // Get a cursor for large result set
284+ cursor = await getProductCatalog ({ category: ' Electronics' , inStock: true }, true );
285+
286+ // Stream products to client one by one
287+ console .log (' Streaming products:' );
288+ await cursor .forEach (product => {
289+ console .log (` - ${product .name }: $${product .price } (${product .stock } in stock) ` );
290+ });
291+ } catch (error ) {
292+ console .error (' Error:' , error );
222293 } finally {
294+ // Close cursor if we have one
295+ if (cursor ) await cursor .close ();
296+ // Close client connection
223297 await client .close ();
224298 }
225299}
0 commit comments