aggregate.js 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.AggregateOperation = exports.DB_AGGREGATE_COLLECTION = void 0;
  4. const error_1 = require("../error");
  5. const utils_1 = require("../utils");
  6. const write_concern_1 = require("../write_concern");
  7. const command_1 = require("./command");
  8. const operation_1 = require("./operation");
  9. /** @internal */
  10. exports.DB_AGGREGATE_COLLECTION = 1;
  11. const MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT = 8;
  12. /** @internal */
  13. class AggregateOperation extends command_1.CommandOperation {
  14. constructor(ns, pipeline, options) {
  15. super(undefined, { ...options, dbName: ns.db });
  16. this.options = { ...options };
  17. // Covers when ns.collection is null, undefined or the empty string, use DB_AGGREGATE_COLLECTION
  18. this.target = ns.collection || exports.DB_AGGREGATE_COLLECTION;
  19. this.pipeline = pipeline;
  20. // determine if we have a write stage, override read preference if so
  21. this.hasWriteStage = false;
  22. if (typeof options?.out === 'string') {
  23. this.pipeline = this.pipeline.concat({ $out: options.out });
  24. this.hasWriteStage = true;
  25. }
  26. else if (pipeline.length > 0) {
  27. const finalStage = pipeline[pipeline.length - 1];
  28. if (finalStage.$out || finalStage.$merge) {
  29. this.hasWriteStage = true;
  30. }
  31. }
  32. if (this.hasWriteStage) {
  33. this.trySecondaryWrite = true;
  34. }
  35. else {
  36. delete this.options.writeConcern;
  37. }
  38. if (this.explain && this.writeConcern) {
  39. throw new error_1.MongoInvalidArgumentError('Option "explain" cannot be used on an aggregate call with writeConcern');
  40. }
  41. if (options?.cursor != null && typeof options.cursor !== 'object') {
  42. throw new error_1.MongoInvalidArgumentError('Cursor options must be an object');
  43. }
  44. }
  45. get canRetryRead() {
  46. return !this.hasWriteStage;
  47. }
  48. addToPipeline(stage) {
  49. this.pipeline.push(stage);
  50. }
  51. async execute(server, session) {
  52. const options = this.options;
  53. const serverWireVersion = (0, utils_1.maxWireVersion)(server);
  54. const command = { aggregate: this.target, pipeline: this.pipeline };
  55. if (this.hasWriteStage && serverWireVersion < MIN_WIRE_VERSION_$OUT_READ_CONCERN_SUPPORT) {
  56. this.readConcern = undefined;
  57. }
  58. if (this.hasWriteStage && this.writeConcern) {
  59. write_concern_1.WriteConcern.apply(command, this.writeConcern);
  60. }
  61. if (options.bypassDocumentValidation === true) {
  62. command.bypassDocumentValidation = options.bypassDocumentValidation;
  63. }
  64. if (typeof options.allowDiskUse === 'boolean') {
  65. command.allowDiskUse = options.allowDiskUse;
  66. }
  67. if (options.hint) {
  68. command.hint = options.hint;
  69. }
  70. if (options.let) {
  71. command.let = options.let;
  72. }
  73. // we check for undefined specifically here to allow falsy values
  74. // eslint-disable-next-line no-restricted-syntax
  75. if (options.comment !== undefined) {
  76. command.comment = options.comment;
  77. }
  78. command.cursor = options.cursor || {};
  79. if (options.batchSize && !this.hasWriteStage) {
  80. command.cursor.batchSize = options.batchSize;
  81. }
  82. return super.executeCommand(server, session, command);
  83. }
  84. }
  85. exports.AggregateOperation = AggregateOperation;
  86. (0, operation_1.defineAspects)(AggregateOperation, [
  87. operation_1.Aspect.READ_OPERATION,
  88. operation_1.Aspect.RETRYABLE,
  89. operation_1.Aspect.EXPLAINABLE,
  90. operation_1.Aspect.CURSOR_CREATING
  91. ]);
  92. //# sourceMappingURL=aggregate.js.map