distinct.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import type { Document } from '../bson';
  2. import type { Collection } from '../collection';
  3. import type { Server } from '../sdam/server';
  4. import type { ClientSession } from '../sessions';
  5. import { type Callback, decorateWithCollation, decorateWithReadConcern } from '../utils';
  6. import { CommandCallbackOperation, type CommandOperationOptions } from './command';
  7. import { Aspect, defineAspects } from './operation';
  8. /** @public */
  9. export type DistinctOptions = CommandOperationOptions;
  10. /**
  11. * Return a list of distinct values for the given key across a collection.
  12. * @internal
  13. */
  14. export class DistinctOperation extends CommandCallbackOperation<any[]> {
  15. override options: DistinctOptions;
  16. collection: Collection;
  17. /** Field of the document to find distinct values for. */
  18. key: string;
  19. /** The query for filtering the set of documents to which we apply the distinct filter. */
  20. query: Document;
  21. /**
  22. * Construct a Distinct operation.
  23. *
  24. * @param collection - Collection instance.
  25. * @param key - Field of the document to find distinct values for.
  26. * @param query - The query for filtering the set of documents to which we apply the distinct filter.
  27. * @param options - Optional settings. See Collection.prototype.distinct for a list of options.
  28. */
  29. constructor(collection: Collection, key: string, query: Document, options?: DistinctOptions) {
  30. super(collection, options);
  31. this.options = options ?? {};
  32. this.collection = collection;
  33. this.key = key;
  34. this.query = query;
  35. }
  36. override executeCallback(
  37. server: Server,
  38. session: ClientSession | undefined,
  39. callback: Callback<any[]>
  40. ): void {
  41. const coll = this.collection;
  42. const key = this.key;
  43. const query = this.query;
  44. const options = this.options;
  45. // Distinct command
  46. const cmd: Document = {
  47. distinct: coll.collectionName,
  48. key: key,
  49. query: query
  50. };
  51. // Add maxTimeMS if defined
  52. if (typeof options.maxTimeMS === 'number') {
  53. cmd.maxTimeMS = options.maxTimeMS;
  54. }
  55. // we check for undefined specifically here to allow falsy values
  56. // eslint-disable-next-line no-restricted-syntax
  57. if (typeof options.comment !== 'undefined') {
  58. cmd.comment = options.comment;
  59. }
  60. // Do we have a readConcern specified
  61. decorateWithReadConcern(cmd, coll, options);
  62. // Have we specified collation
  63. try {
  64. decorateWithCollation(cmd, coll, options);
  65. } catch (err) {
  66. return callback(err);
  67. }
  68. super.executeCommandCallback(server, session, cmd, (err, result) => {
  69. if (err) {
  70. callback(err);
  71. return;
  72. }
  73. callback(undefined, this.explain ? result : result.values);
  74. });
  75. }
  76. }
  77. defineAspects(DistinctOperation, [Aspect.READ_OPERATION, Aspect.RETRYABLE, Aspect.EXPLAINABLE]);