1 | ;
|
2 |
|
3 | const MongoError = require('./core').MongoError;
|
4 | const Cursor = require('./cursor');
|
5 | const CursorState = require('./core/cursor').CursorState;
|
6 | const deprecate = require('util').deprecate;
|
7 |
|
8 | /**
|
9 | * @fileOverview The **AggregationCursor** class is an internal class that embodies an aggregation cursor on MongoDB
|
10 | * allowing for iteration over the results returned from the underlying query. It supports
|
11 | * one by one document iteration, conversion to an array or can be iterated as a Node 4.X
|
12 | * or higher stream
|
13 | *
|
14 | * **AGGREGATIONCURSOR Cannot directly be instantiated**
|
15 | * @example
|
16 | * const MongoClient = require('mongodb').MongoClient;
|
17 | * const test = require('assert');
|
18 | * // Connection url
|
19 | * const url = 'mongodb://localhost:27017';
|
20 | * // Database Name
|
21 | * const dbName = 'test';
|
22 | * // Connect using MongoClient
|
23 | * MongoClient.connect(url, function(err, client) {
|
24 | * // Create a collection we want to drop later
|
25 | * const col = client.db(dbName).collection('createIndexExample1');
|
26 | * // Insert a bunch of documents
|
27 | * col.insert([{a:1, b:1}
|
28 | * , {a:2, b:2}, {a:3, b:3}
|
29 | * , {a:4, b:4}], {w:1}, function(err, result) {
|
30 | * test.equal(null, err);
|
31 | * // Show that duplicate records got dropped
|
32 | * col.aggregation({}, {cursor: {}}).toArray(function(err, items) {
|
33 | * test.equal(null, err);
|
34 | * test.equal(4, items.length);
|
35 | * client.close();
|
36 | * });
|
37 | * });
|
38 | * });
|
39 | */
|
40 |
|
41 | /**
|
42 | * Namespace provided by the browser.
|
43 | * @external Readable
|
44 | */
|
45 |
|
46 | /**
|
47 | * Creates a new Aggregation Cursor instance (INTERNAL TYPE, do not instantiate directly)
|
48 | * @class AggregationCursor
|
49 | * @extends external:Readable
|
50 | * @fires AggregationCursor#data
|
51 | * @fires AggregationCursor#end
|
52 | * @fires AggregationCursor#close
|
53 | * @fires AggregationCursor#readable
|
54 | * @return {AggregationCursor} an AggregationCursor instance.
|
55 | */
|
56 | class AggregationCursor extends Cursor {
|
57 | constructor(topology, operation, options) {
|
58 | super(topology, operation, options);
|
59 | }
|
60 |
|
61 | /**
|
62 | * Set the batch size for the cursor.
|
63 | * @method
|
64 | * @param {number} value The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
|
65 | * @throws {MongoError}
|
66 | * @return {AggregationCursor}
|
67 | */
|
68 | batchSize(value) {
|
69 | if (this.s.state === CursorState.CLOSED || this.isDead()) {
|
70 | throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
71 | }
|
72 |
|
73 | if (typeof value !== 'number') {
|
74 | throw MongoError.create({ message: 'batchSize requires an integer', driver: true });
|
75 | }
|
76 |
|
77 | this.operation.options.batchSize = value;
|
78 | this.setCursorBatchSize(value);
|
79 | return this;
|
80 | }
|
81 |
|
82 | /**
|
83 | * Add a geoNear stage to the aggregation pipeline
|
84 | * @method
|
85 | * @param {object} document The geoNear stage document.
|
86 | * @return {AggregationCursor}
|
87 | */
|
88 | geoNear(document) {
|
89 | this.operation.addToPipeline({ $geoNear: document });
|
90 | return this;
|
91 | }
|
92 |
|
93 | /**
|
94 | * Add a group stage to the aggregation pipeline
|
95 | * @method
|
96 | * @param {object} document The group stage document.
|
97 | * @return {AggregationCursor}
|
98 | */
|
99 | group(document) {
|
100 | this.operation.addToPipeline({ $group: document });
|
101 | return this;
|
102 | }
|
103 |
|
104 | /**
|
105 | * Add a limit stage to the aggregation pipeline
|
106 | * @method
|
107 | * @param {number} value The state limit value.
|
108 | * @return {AggregationCursor}
|
109 | */
|
110 | limit(value) {
|
111 | this.operation.addToPipeline({ $limit: value });
|
112 | return this;
|
113 | }
|
114 |
|
115 | /**
|
116 | * Add a match stage to the aggregation pipeline
|
117 | * @method
|
118 | * @param {object} document The match stage document.
|
119 | * @return {AggregationCursor}
|
120 | */
|
121 | match(document) {
|
122 | this.operation.addToPipeline({ $match: document });
|
123 | return this;
|
124 | }
|
125 |
|
126 | /**
|
127 | * Add a maxTimeMS stage to the aggregation pipeline
|
128 | * @method
|
129 | * @param {number} value The state maxTimeMS value.
|
130 | * @return {AggregationCursor}
|
131 | */
|
132 | maxTimeMS(value) {
|
133 | this.operation.options.maxTimeMS = value;
|
134 | return this;
|
135 | }
|
136 |
|
137 | /**
|
138 | * Add a out stage to the aggregation pipeline
|
139 | * @method
|
140 | * @param {number} destination The destination name.
|
141 | * @return {AggregationCursor}
|
142 | */
|
143 | out(destination) {
|
144 | this.operation.addToPipeline({ $out: destination });
|
145 | return this;
|
146 | }
|
147 |
|
148 | /**
|
149 | * Add a project stage to the aggregation pipeline
|
150 | * @method
|
151 | * @param {object} document The project stage document.
|
152 | * @return {AggregationCursor}
|
153 | */
|
154 | project(document) {
|
155 | this.operation.addToPipeline({ $project: document });
|
156 | return this;
|
157 | }
|
158 |
|
159 | /**
|
160 | * Add a lookup stage to the aggregation pipeline
|
161 | * @method
|
162 | * @param {object} document The lookup stage document.
|
163 | * @return {AggregationCursor}
|
164 | */
|
165 | lookup(document) {
|
166 | this.operation.addToPipeline({ $lookup: document });
|
167 | return this;
|
168 | }
|
169 |
|
170 | /**
|
171 | * Add a redact stage to the aggregation pipeline
|
172 | * @method
|
173 | * @param {object} document The redact stage document.
|
174 | * @return {AggregationCursor}
|
175 | */
|
176 | redact(document) {
|
177 | this.operation.addToPipeline({ $redact: document });
|
178 | return this;
|
179 | }
|
180 |
|
181 | /**
|
182 | * Add a skip stage to the aggregation pipeline
|
183 | * @method
|
184 | * @param {number} value The state skip value.
|
185 | * @return {AggregationCursor}
|
186 | */
|
187 | skip(value) {
|
188 | this.operation.addToPipeline({ $skip: value });
|
189 | return this;
|
190 | }
|
191 |
|
192 | /**
|
193 | * Add a sort stage to the aggregation pipeline
|
194 | * @method
|
195 | * @param {object} document The sort stage document.
|
196 | * @return {AggregationCursor}
|
197 | */
|
198 | sort(document) {
|
199 | this.operation.addToPipeline({ $sort: document });
|
200 | return this;
|
201 | }
|
202 |
|
203 | /**
|
204 | * Add a unwind stage to the aggregation pipeline
|
205 | * @method
|
206 | * @param {number} field The unwind field name.
|
207 | * @return {AggregationCursor}
|
208 | */
|
209 | unwind(field) {
|
210 | this.operation.addToPipeline({ $unwind: field });
|
211 | return this;
|
212 | }
|
213 |
|
214 | /**
|
215 | * Return the cursor logger
|
216 | * @method
|
217 | * @return {Logger} return the cursor logger
|
218 | * @ignore
|
219 | */
|
220 | getLogger() {
|
221 | return this.logger;
|
222 | }
|
223 | }
|
224 |
|
225 | // aliases
|
226 | AggregationCursor.prototype.get = AggregationCursor.prototype.toArray;
|
227 |
|
228 | // deprecated methods
|
229 | deprecate(
|
230 | AggregationCursor.prototype.geoNear,
|
231 | 'The `$geoNear` stage is deprecated in MongoDB 4.0, and removed in version 4.2.'
|
232 | );
|
233 |
|
234 | /**
|
235 | * AggregationCursor stream data event, fired for each document in the cursor.
|
236 | *
|
237 | * @event AggregationCursor#data
|
238 | * @type {object}
|
239 | */
|
240 |
|
241 | /**
|
242 | * AggregationCursor stream end event
|
243 | *
|
244 | * @event AggregationCursor#end
|
245 | * @type {null}
|
246 | */
|
247 |
|
248 | /**
|
249 | * AggregationCursor stream close event
|
250 | *
|
251 | * @event AggregationCursor#close
|
252 | * @type {null}
|
253 | */
|
254 |
|
255 | /**
|
256 | * AggregationCursor stream readable event
|
257 | *
|
258 | * @event AggregationCursor#readable
|
259 | * @type {null}
|
260 | */
|
261 |
|
262 | /**
|
263 | * Get the next available document from the cursor, returns null if no more documents are available.
|
264 | * @function AggregationCursor.prototype.next
|
265 | * @param {AggregationCursor~resultCallback} [callback] The result callback.
|
266 | * @throws {MongoError}
|
267 | * @return {Promise} returns Promise if no callback passed
|
268 | */
|
269 |
|
270 | /**
|
271 | * Check if there is any document still available in the cursor
|
272 | * @function AggregationCursor.prototype.hasNext
|
273 | * @param {AggregationCursor~resultCallback} [callback] The result callback.
|
274 | * @throws {MongoError}
|
275 | * @return {Promise} returns Promise if no callback passed
|
276 | */
|
277 |
|
278 | /**
|
279 | * The callback format for results
|
280 | * @callback AggregationCursor~toArrayResultCallback
|
281 | * @param {MongoError} error An error instance representing the error during the execution.
|
282 | * @param {object[]} documents All the documents the satisfy the cursor.
|
283 | */
|
284 |
|
285 | /**
|
286 | * Returns an array of documents. The caller is responsible for making sure that there
|
287 | * is enough memory to store the results. Note that the array only contain partial
|
288 | * results when this cursor had been previously accessed. In that case,
|
289 | * cursor.rewind() can be used to reset the cursor.
|
290 | * @method AggregationCursor.prototype.toArray
|
291 | * @param {AggregationCursor~toArrayResultCallback} [callback] The result callback.
|
292 | * @throws {MongoError}
|
293 | * @return {Promise} returns Promise if no callback passed
|
294 | */
|
295 |
|
296 | /**
|
297 | * The callback format for results
|
298 | * @callback AggregationCursor~resultCallback
|
299 | * @param {MongoError} error An error instance representing the error during the execution.
|
300 | * @param {(object|null)} result The result object if the command was executed successfully.
|
301 | */
|
302 |
|
303 | /**
|
304 | * Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
|
305 | * not all of the elements will be iterated if this cursor had been previously accessed.
|
306 | * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike
|
307 | * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements
|
308 | * at any given time if batch size is specified. Otherwise, the caller is responsible
|
309 | * for making sure that the entire result can fit the memory.
|
310 | * @method AggregationCursor.prototype.each
|
311 | * @deprecated
|
312 | * @param {AggregationCursor~resultCallback} callback The result callback.
|
313 | * @throws {MongoError}
|
314 | * @return {null}
|
315 | */
|
316 |
|
317 | /**
|
318 | * Close the cursor, sending a AggregationCursor command and emitting close.
|
319 | * @method AggregationCursor.prototype.close
|
320 | * @param {AggregationCursor~resultCallback} [callback] The result callback.
|
321 | * @return {Promise} returns Promise if no callback passed
|
322 | */
|
323 |
|
324 | /**
|
325 | * Is the cursor closed
|
326 | * @method AggregationCursor.prototype.isClosed
|
327 | * @return {boolean}
|
328 | */
|
329 |
|
330 | /**
|
331 | * Execute the explain for the cursor
|
332 | * @method AggregationCursor.prototype.explain
|
333 | * @param {AggregationCursor~resultCallback} [callback] The result callback.
|
334 | * @return {Promise} returns Promise if no callback passed
|
335 | */
|
336 |
|
337 | /**
|
338 | * Clone the cursor
|
339 | * @function AggregationCursor.prototype.clone
|
340 | * @return {AggregationCursor}
|
341 | */
|
342 |
|
343 | /**
|
344 | * Resets the cursor
|
345 | * @function AggregationCursor.prototype.rewind
|
346 | * @return {AggregationCursor}
|
347 | */
|
348 |
|
349 | /**
|
350 | * The callback format for the forEach iterator method
|
351 | * @callback AggregationCursor~iteratorCallback
|
352 | * @param {Object} doc An emitted document for the iterator
|
353 | */
|
354 |
|
355 | /**
|
356 | * The callback error format for the forEach iterator method
|
357 | * @callback AggregationCursor~endCallback
|
358 | * @param {MongoError} error An error instance representing the error during the execution.
|
359 | */
|
360 |
|
361 | /**
|
362 | * Iterates over all the documents for this cursor using the iterator, callback pattern.
|
363 | * @method AggregationCursor.prototype.forEach
|
364 | * @param {AggregationCursor~iteratorCallback} iterator The iteration callback.
|
365 | * @param {AggregationCursor~endCallback} callback The end callback.
|
366 | * @throws {MongoError}
|
367 | * @return {null}
|
368 | */
|
369 |
|
370 | module.exports = AggregationCursor;
|