All files / src/operations distinct.ts

100% Statements 26/26
100% Branches 10/10
100% Functions 3/3
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104          135x 135x 135x                                           135x                                 17225x   17225x 17225x 17225x 17225x       18093x               18005x 18005x 18005x 18005x     18005x             18005x 33x         18005x 344x     18005x 30x       18005x     18005x   18005x   16597x       135x  
import type { Document } from '../bson';
import type { Collection } from '../collection';
import type { Server } from '../sdam/server';
import type { ClientSession } from '../sessions';
import { type TimeoutContext } from '../timeout';
import { decorateWithCollation, decorateWithReadConcern } from '../utils';
import { CommandOperation, type CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';
 
/** @public */
export type DistinctOptions = CommandOperationOptions & {
  /**
   * @sinceServerVersion 7.1
   *
   * The index to use. Specify either the index name as a string or the index key pattern.
   * If specified, then the query system will only consider plans using the hinted index.
   *
   * If provided as a string, `hint` must be index name for an index on the collection.
   * If provided as an object, `hint` must be an index description for an index defined on the collection.
   *
   * See https://www.mongodb.com/docs/manual/reference/command/distinct/#command-fields.
   */
  hint?: Document | string;
};
 
/**
 * Return a list of distinct values for the given key across a collection.
 * @internal
 */
export class DistinctOperation extends CommandOperation<any[]> {
  override options: DistinctOptions;
  collection: Collection;
  /** Field of the document to find distinct values for. */
  key: string;
  /** The query for filtering the set of documents to which we apply the distinct filter. */
  query: Document;
 
  /**
   * Construct a Distinct operation.
   *
   * @param collection - Collection instance.
   * @param key - Field of the document to find distinct values for.
   * @param query - The query for filtering the set of documents to which we apply the distinct filter.
   * @param options - Optional settings. See Collection.prototype.distinct for a list of options.
   */
  constructor(collection: Collection, key: string, query: Document, options?: DistinctOptions) {
    super(collection, options);
 
    this.options = options ?? {};
    this.collection = collection;
    this.key = key;
    this.query = query;
  }
 
  override get commandName() {
    return 'distinct' as const;
  }
 
  override async execute(
    server: Server,
    session: ClientSession | undefined,
    timeoutContext: TimeoutContext
  ): Promise<any[]> {
    const coll = this.collection;
    const key = this.key;
    const query = this.query;
    const options = this.options;
 
    // Distinct command
    const cmd: Document = {
      distinct: coll.collectionName,
      key: key,
      query: query
    };
 
    // Add maxTimeMS if defined
    if (typeof options.maxTimeMS === 'number') {
      cmd.maxTimeMS = options.maxTimeMS;
    }
 
    // we check for undefined specifically here to allow falsy values
    // eslint-disable-next-line no-restricted-syntax
    if (typeof options.comment !== 'undefined') {
      cmd.comment = options.comment;
    }
 
    if (options.hint != null) {
      cmd.hint = options.hint;
    }
 
    // Do we have a readConcern specified
    decorateWithReadConcern(cmd, coll, options);
 
    // Have we specified collation
    decorateWithCollation(cmd, coll, options);
 
    const result = await super.executeCommand(server, session, cmd, timeoutContext);
 
    return this.explain ? result : result.values;
  }
}
 
defineAspects(DistinctOperation, [Aspect.READ_OPERATION, Aspect.RETRYABLE, Aspect.EXPLAINABLE]);