distinct.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. 'use strict';
  2. const Aspect = require('./operation').Aspect;
  3. const defineAspects = require('./operation').defineAspects;
  4. const CommandOperationV2 = require('./command_v2');
  5. const decorateWithCollation = require('../utils').decorateWithCollation;
  6. const decorateWithReadConcern = require('../utils').decorateWithReadConcern;
  7. /**
  8. * Return a list of distinct values for the given key across a collection.
  9. *
  10. * @class
  11. * @property {Collection} a Collection instance.
  12. * @property {string} key Field of the document to find distinct values for.
  13. * @property {object} query The query for filtering the set of documents to which we apply the distinct filter.
  14. * @property {object} [options] Optional settings. See Collection.prototype.distinct for a list of options.
  15. */
  16. class DistinctOperation extends CommandOperationV2 {
  17. /**
  18. * Construct a Distinct operation.
  19. *
  20. * @param {Collection} a Collection instance.
  21. * @param {string} key Field of the document to find distinct values for.
  22. * @param {object} query The query for filtering the set of documents to which we apply the distinct filter.
  23. * @param {object} [options] Optional settings. See Collection.prototype.distinct for a list of options.
  24. */
  25. constructor(collection, key, query, options) {
  26. super(collection, options);
  27. this.collection = collection;
  28. this.key = key;
  29. this.query = query;
  30. }
  31. /**
  32. * Execute the operation.
  33. *
  34. * @param {Collection~resultCallback} [callback] The command result callback
  35. */
  36. execute(server, callback) {
  37. const coll = this.collection;
  38. const key = this.key;
  39. const query = this.query;
  40. const options = this.options;
  41. // Distinct command
  42. const cmd = {
  43. distinct: coll.collectionName,
  44. key: key,
  45. query: query
  46. };
  47. // Add maxTimeMS if defined
  48. if (typeof options.maxTimeMS === 'number') {
  49. cmd.maxTimeMS = options.maxTimeMS;
  50. }
  51. // Do we have a readConcern specified
  52. decorateWithReadConcern(cmd, coll, options);
  53. // Have we specified collation
  54. try {
  55. decorateWithCollation(cmd, coll, options);
  56. } catch (err) {
  57. return callback(err, null);
  58. }
  59. super.executeCommand(server, cmd, (err, result) => {
  60. if (err) {
  61. callback(err);
  62. return;
  63. }
  64. callback(null, this.options.full ? result : result.values);
  65. });
  66. }
  67. }
  68. defineAspects(DistinctOperation, [
  69. Aspect.READ_OPERATION,
  70. Aspect.RETRYABLE,
  71. Aspect.EXECUTE_WITH_SELECTION
  72. ]);
  73. module.exports = DistinctOperation;