aggregation_cursor.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.AggregationCursor = void 0;
  4. const aggregate_1 = require("../operations/aggregate");
  5. const execute_operation_1 = require("../operations/execute_operation");
  6. const utils_1 = require("../utils");
  7. const abstract_cursor_1 = require("./abstract_cursor");
  8. /** @internal */
  9. const kPipeline = Symbol('pipeline');
  10. /** @internal */
  11. const kOptions = Symbol('options');
  12. /**
  13. * The **AggregationCursor** class is an internal class that embodies an aggregation cursor on MongoDB
  14. * allowing for iteration over the results returned from the underlying query. It supports
  15. * one by one document iteration, conversion to an array or can be iterated as a Node 4.X
  16. * or higher stream
  17. * @public
  18. */
  19. class AggregationCursor extends abstract_cursor_1.AbstractCursor {
  20. /** @internal */
  21. constructor(topology, namespace, pipeline = [], options = {}) {
  22. super(topology, namespace, options);
  23. this[kPipeline] = pipeline;
  24. this[kOptions] = options;
  25. }
  26. get pipeline() {
  27. return this[kPipeline];
  28. }
  29. clone() {
  30. const clonedOptions = (0, utils_1.mergeOptions)({}, this[kOptions]);
  31. delete clonedOptions.session;
  32. return new AggregationCursor(this.topology, this.namespace, this[kPipeline], {
  33. ...clonedOptions
  34. });
  35. }
  36. map(transform) {
  37. return super.map(transform);
  38. }
  39. /** @internal */
  40. _initialize(session, callback) {
  41. const aggregateOperation = new aggregate_1.AggregateOperation(this.namespace, this[kPipeline], {
  42. ...this[kOptions],
  43. ...this.cursorOptions,
  44. session
  45. });
  46. (0, execute_operation_1.executeOperation)(this.topology, aggregateOperation, (err, response) => {
  47. if (err || response == null)
  48. return callback(err);
  49. // TODO: NODE-2882
  50. callback(undefined, { server: aggregateOperation.server, session, response });
  51. });
  52. }
  53. explain(verbosity, callback) {
  54. if (typeof verbosity === 'function')
  55. (callback = verbosity), (verbosity = true);
  56. if (verbosity == null)
  57. verbosity = true;
  58. return (0, execute_operation_1.executeOperation)(this.topology, new aggregate_1.AggregateOperation(this.namespace, this[kPipeline], {
  59. ...this[kOptions],
  60. ...this.cursorOptions,
  61. explain: verbosity
  62. }), callback);
  63. }
  64. group($group) {
  65. (0, abstract_cursor_1.assertUninitialized)(this);
  66. this[kPipeline].push({ $group });
  67. return this;
  68. }
  69. /** Add a limit stage to the aggregation pipeline */
  70. limit($limit) {
  71. (0, abstract_cursor_1.assertUninitialized)(this);
  72. this[kPipeline].push({ $limit });
  73. return this;
  74. }
  75. /** Add a match stage to the aggregation pipeline */
  76. match($match) {
  77. (0, abstract_cursor_1.assertUninitialized)(this);
  78. this[kPipeline].push({ $match });
  79. return this;
  80. }
  81. /** Add an out stage to the aggregation pipeline */
  82. out($out) {
  83. (0, abstract_cursor_1.assertUninitialized)(this);
  84. this[kPipeline].push({ $out });
  85. return this;
  86. }
  87. /**
  88. * Add a project stage to the aggregation pipeline
  89. *
  90. * @remarks
  91. * In order to strictly type this function you must provide an interface
  92. * that represents the effect of your projection on the result documents.
  93. *
  94. * By default chaining a projection to your cursor changes the returned type to the generic {@link Document} type.
  95. * You should specify a parameterized type to have assertions on your final results.
  96. *
  97. * @example
  98. * ```typescript
  99. * // Best way
  100. * const docs: AggregationCursor<{ a: number }> = cursor.project<{ a: number }>({ _id: 0, a: true });
  101. * // Flexible way
  102. * const docs: AggregationCursor<Document> = cursor.project({ _id: 0, a: true });
  103. * ```
  104. *
  105. * @remarks
  106. * In order to strictly type this function you must provide an interface
  107. * that represents the effect of your projection on the result documents.
  108. *
  109. * **Note for Typescript Users:** adding a transform changes the return type of the iteration of this cursor,
  110. * it **does not** return a new instance of a cursor. This means when calling project,
  111. * you should always assign the result to a new variable in order to get a correctly typed cursor variable.
  112. * Take note of the following example:
  113. *
  114. * @example
  115. * ```typescript
  116. * const cursor: AggregationCursor<{ a: number; b: string }> = coll.aggregate([]);
  117. * const projectCursor = cursor.project<{ a: number }>({ _id: 0, a: true });
  118. * const aPropOnlyArray: {a: number}[] = await projectCursor.toArray();
  119. *
  120. * // or always use chaining and save the final cursor
  121. *
  122. * const cursor = coll.aggregate().project<{ a: string }>({
  123. * _id: 0,
  124. * a: { $convert: { input: '$a', to: 'string' }
  125. * }});
  126. * ```
  127. */
  128. project($project) {
  129. (0, abstract_cursor_1.assertUninitialized)(this);
  130. this[kPipeline].push({ $project });
  131. return this;
  132. }
  133. /** Add a lookup stage to the aggregation pipeline */
  134. lookup($lookup) {
  135. (0, abstract_cursor_1.assertUninitialized)(this);
  136. this[kPipeline].push({ $lookup });
  137. return this;
  138. }
  139. /** Add a redact stage to the aggregation pipeline */
  140. redact($redact) {
  141. (0, abstract_cursor_1.assertUninitialized)(this);
  142. this[kPipeline].push({ $redact });
  143. return this;
  144. }
  145. /** Add a skip stage to the aggregation pipeline */
  146. skip($skip) {
  147. (0, abstract_cursor_1.assertUninitialized)(this);
  148. this[kPipeline].push({ $skip });
  149. return this;
  150. }
  151. /** Add a sort stage to the aggregation pipeline */
  152. sort($sort) {
  153. (0, abstract_cursor_1.assertUninitialized)(this);
  154. this[kPipeline].push({ $sort });
  155. return this;
  156. }
  157. /** Add a unwind stage to the aggregation pipeline */
  158. unwind($unwind) {
  159. (0, abstract_cursor_1.assertUninitialized)(this);
  160. this[kPipeline].push({ $unwind });
  161. return this;
  162. }
  163. // deprecated methods
  164. /** @deprecated Add a geoNear stage to the aggregation pipeline */
  165. geoNear($geoNear) {
  166. (0, abstract_cursor_1.assertUninitialized)(this);
  167. this[kPipeline].push({ $geoNear });
  168. return this;
  169. }
  170. }
  171. exports.AggregationCursor = AggregationCursor;
  172. //# sourceMappingURL=aggregation_cursor.js.map