Skip to content

Commit

Permalink
Merge pull request #14772 from Automattic/vkarpov15/gh-8006
Browse files Browse the repository at this point in the history
feat(model+query): support `options` parameter for distinct()
  • Loading branch information
vkarpov15 authored Aug 8, 2024
2 parents 220dd50 + 58f384d commit d6853b8
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 8 deletions.
8 changes: 6 additions & 2 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2115,17 +2115,21 @@ Model.countDocuments = function countDocuments(conditions, options) {
*
* @param {String} field
* @param {Object} [conditions] optional
* @param {Object} [options] optional
* @return {Query}
* @api public
*/

Model.distinct = function distinct(field, conditions) {
Model.distinct = function distinct(field, conditions, options) {
_checkContext(this, 'distinct');
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function') {
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function' || typeof arguments[2] === 'function') {
throw new MongooseError('Model.distinct() no longer accepts a callback');
}

const mq = new this.Query({}, {}, this, this.$__collection);
if (options != null) {
mq.setOptions(options);
}

return mq.distinct(field, conditions);
};
Expand Down
15 changes: 11 additions & 4 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -2773,7 +2773,7 @@ Query.prototype.estimatedDocumentCount = function(options) {
this.op = 'estimatedDocumentCount';
this._validateOp();

if (typeof options === 'object' && options != null) {
if (options != null) {
this.setOptions(options);
}

Expand Down Expand Up @@ -2832,7 +2832,7 @@ Query.prototype.countDocuments = function(conditions, options) {
this.merge(conditions);
}

if (typeof options === 'object' && options != null) {
if (options != null) {
this.setOptions(options);
}

Expand Down Expand Up @@ -2870,21 +2870,24 @@ Query.prototype.__distinct = async function __distinct() {
*
* #### Example:
*
* distinct(field, conditions, options)
* distinct(field, conditions)
* distinct(field)
* distinct()
*
* @param {String} [field]
* @param {Object|Query} [filter]
* @param {Object} [options]
* @return {Query} this
* @see distinct https://www.mongodb.com/docs/manual/reference/method/db.collection.distinct/
* @api public
*/

Query.prototype.distinct = function(field, conditions) {
Query.prototype.distinct = function(field, conditions, options) {
if (typeof field === 'function' ||
typeof conditions === 'function' ||
typeof arguments[2] === 'function') {
typeof options === 'function' ||
typeof arguments[3] === 'function') {
throw new MongooseError('Query.prototype.distinct() no longer accepts a callback');
}

Expand All @@ -2903,6 +2906,10 @@ Query.prototype.distinct = function(field, conditions) {
this._distinct = field;
}

if (options != null) {
this.setOptions(options);
}

return this;
};

Expand Down
19 changes: 19 additions & 0 deletions test/docs/transactions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,25 @@ describe('transactions', function() {
assert.deepEqual(fromDb, { name: 'Tyrion Lannister' });
});

it('distinct (gh-8006)', async function() {
const Character = db.model('gh8006_Character', new Schema({ name: String, rank: String }, { versionKey: false }));

const session = await db.startSession();

session.startTransaction();
await Character.create([{ name: 'Will Riker', rank: 'Commander' }, { name: 'Jean-Luc Picard', rank: 'Captain' }], { session });

let names = await Character.distinct('name', {}, { session });
assert.deepStrictEqual(names.sort(), ['Jean-Luc Picard', 'Will Riker']);

names = await Character.distinct('name', { rank: 'Captain' }, { session });
assert.deepStrictEqual(names.sort(), ['Jean-Luc Picard']);

// Undo both update and delete since doc should pull from `$session()`
await session.abortTransaction();
session.endSession();
});

it('save() with no changes (gh-8571)', async function() {
db.deleteModel(/Test/);
const Test = db.model('Test', Schema({ name: String }));
Expand Down
10 changes: 10 additions & 0 deletions test/query.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,16 @@ describe('Query', function() {

assert.equal(q.op, 'distinct');
});

it('using options parameter for distinct', function() {
const q = new Query({});
const options = { collation: { locale: 'en', strength: 2 } };

q.distinct('blah', {}, options);

assert.equal(q.op, 'distinct');
assert.deepEqual(q.options.collation, options.collation);
});
});

describe('findOne', function() {
Expand Down
1 change: 1 addition & 0 deletions test/types/queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Test.find({ name: { $gte: 'Test' } }, null, { collation: { locale: 'en-us' } }).
Test.findOne().orFail(new Error('bar')).then((doc: ITest | null) => console.log('Found! ' + doc));

Test.distinct('name').exec().then((res: Array<any>) => console.log(res[0]));
Test.distinct('name', {}, { collation: { locale: 'en', strength: 2 } }).exec().then((res: Array<any>) => console.log(res[0]));

Test.findOneAndUpdate({ name: 'test' }, { name: 'test2' }).exec().then((res: ITest | null) => console.log(res));
Test.findOneAndUpdate({ name: 'test' }, { name: 'test2' }).then((res: ITest | null) => console.log(res));
Expand Down
3 changes: 2 additions & 1 deletion types/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,8 @@ declare module 'mongoose' {
/** Creates a `distinct` query: returns the distinct values of the given `field` that match `filter`. */
distinct<DocKey extends string, ResultType = unknown>(
field: DocKey,
filter?: FilterQuery<TRawDocType>
filter?: FilterQuery<TRawDocType>,
options?: QueryOptions<TRawDocType>
): QueryWithHelpers<
Array<
DocKey extends keyof WithLevel1NestedPaths<TRawDocType>
Expand Down
3 changes: 2 additions & 1 deletion types/query.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ declare module 'mongoose' {
/** Creates a `distinct` query: returns the distinct values of the given `field` that match `filter`. */
distinct<DocKey extends string, ResultType = unknown>(
field: DocKey,
filter?: FilterQuery<RawDocType>
filter?: FilterQuery<RawDocType>,
options?: QueryOptions<DocType>
): QueryWithHelpers<
Array<
DocKey extends keyof WithLevel1NestedPaths<DocType>
Expand Down

0 comments on commit d6853b8

Please sign in to comment.