You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.8 KiB
94 lines
2.8 KiB
2 months ago
|
'use strict';
|
||
|
|
||
|
const Aspect = require('./operation').Aspect;
|
||
|
const defineAspects = require('./operation').defineAspects;
|
||
|
const CommandOperationV2 = require('./command_v2');
|
||
|
const decorateWithCollation = require('../utils').decorateWithCollation;
|
||
|
const decorateWithReadConcern = require('../utils').decorateWithReadConcern;
|
||
|
const maxWireVersion = require('../core/utils').maxWireVersion;
|
||
|
const MongoError = require('../error').MongoError;
|
||
|
|
||
|
/**
|
||
|
* Return a list of distinct values for the given key across a collection.
|
||
|
*
|
||
|
* @class
|
||
|
* @property {Collection} a Collection instance.
|
||
|
* @property {string} key Field of the document to find distinct values for.
|
||
|
* @property {object} query The query for filtering the set of documents to which we apply the distinct filter.
|
||
|
* @property {object} [options] Optional settings. See Collection.prototype.distinct for a list of options.
|
||
|
*/
|
||
|
class DistinctOperation extends CommandOperationV2 {
|
||
|
/**
|
||
|
* Construct a Distinct operation.
|
||
|
*
|
||
|
* @param {Collection} a Collection instance.
|
||
|
* @param {string} key Field of the document to find distinct values for.
|
||
|
* @param {object} query The query for filtering the set of documents to which we apply the distinct filter.
|
||
|
* @param {object} [options] Optional settings. See Collection.prototype.distinct for a list of options.
|
||
|
*/
|
||
|
constructor(collection, key, query, options) {
|
||
|
super(collection, options);
|
||
|
|
||
|
this.collection = collection;
|
||
|
this.key = key;
|
||
|
this.query = query;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Execute the operation.
|
||
|
*
|
||
|
* @param {Collection~resultCallback} [callback] The command result callback
|
||
|
*/
|
||
|
execute(server, callback) {
|
||
|
const coll = this.collection;
|
||
|
const key = this.key;
|
||
|
const query = this.query;
|
||
|
const options = this.options;
|
||
|
|
||
|
// Distinct command
|
||
|
const cmd = {
|
||
|
distinct: coll.collectionName,
|
||
|
key: key,
|
||
|
query: query
|
||
|
};
|
||
|
|
||
|
// Add maxTimeMS if defined
|
||
|
if (typeof options.maxTimeMS === 'number') {
|
||
|
cmd.maxTimeMS = options.maxTimeMS;
|
||
|
}
|
||
|
|
||
|
// Do we have a readConcern specified
|
||
|
decorateWithReadConcern(cmd, coll, options);
|
||
|
|
||
|
// Have we specified collation
|
||
|
try {
|
||
|
decorateWithCollation(cmd, coll, options);
|
||
|
} catch (err) {
|
||
|
return callback(err, null);
|
||
|
}
|
||
|
|
||
|
if (this.explain && maxWireVersion(server) < 4) {
|
||
|
callback(new MongoError(`server does not support explain on distinct`));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
super.executeCommand(server, cmd, (err, result) => {
|
||
|
if (err) {
|
||
|
callback(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
callback(null, this.options.full || this.explain ? result : result.values);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
defineAspects(DistinctOperation, [
|
||
|
Aspect.READ_OPERATION,
|
||
|
Aspect.RETRYABLE,
|
||
|
Aspect.EXECUTE_WITH_SELECTION,
|
||
|
Aspect.EXPLAINABLE
|
||
|
]);
|
||
|
|
||
|
module.exports = DistinctOperation;
|