Skip to content

Commit d6853b8

Browse files
authored
Merge pull request #14772 from Automattic/vkarpov15/gh-8006
feat(model+query): support `options` parameter for distinct()
2 parents 220dd50 + 58f384d commit d6853b8

File tree

7 files changed

+51
-8
lines changed

7 files changed

+51
-8
lines changed

lib/model.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,17 +2115,21 @@ Model.countDocuments = function countDocuments(conditions, options) {
21152115
*
21162116
* @param {String} field
21172117
* @param {Object} [conditions] optional
2118+
* @param {Object} [options] optional
21182119
* @return {Query}
21192120
* @api public
21202121
*/
21212122

2122-
Model.distinct = function distinct(field, conditions) {
2123+
Model.distinct = function distinct(field, conditions, options) {
21232124
_checkContext(this, 'distinct');
2124-
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function') {
2125+
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function' || typeof arguments[2] === 'function') {
21252126
throw new MongooseError('Model.distinct() no longer accepts a callback');
21262127
}
21272128

21282129
const mq = new this.Query({}, {}, this, this.$__collection);
2130+
if (options != null) {
2131+
mq.setOptions(options);
2132+
}
21292133

21302134
return mq.distinct(field, conditions);
21312135
};

lib/query.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,7 +2773,7 @@ Query.prototype.estimatedDocumentCount = function(options) {
27732773
this.op = 'estimatedDocumentCount';
27742774
this._validateOp();
27752775

2776-
if (typeof options === 'object' && options != null) {
2776+
if (options != null) {
27772777
this.setOptions(options);
27782778
}
27792779

@@ -2832,7 +2832,7 @@ Query.prototype.countDocuments = function(conditions, options) {
28322832
this.merge(conditions);
28332833
}
28342834

2835-
if (typeof options === 'object' && options != null) {
2835+
if (options != null) {
28362836
this.setOptions(options);
28372837
}
28382838

@@ -2870,21 +2870,24 @@ Query.prototype.__distinct = async function __distinct() {
28702870
*
28712871
* #### Example:
28722872
*
2873+
* distinct(field, conditions, options)
28732874
* distinct(field, conditions)
28742875
* distinct(field)
28752876
* distinct()
28762877
*
28772878
* @param {String} [field]
28782879
* @param {Object|Query} [filter]
2880+
* @param {Object} [options]
28792881
* @return {Query} this
28802882
* @see distinct https://www.mongodb.com/docs/manual/reference/method/db.collection.distinct/
28812883
* @api public
28822884
*/
28832885

2884-
Query.prototype.distinct = function(field, conditions) {
2886+
Query.prototype.distinct = function(field, conditions, options) {
28852887
if (typeof field === 'function' ||
28862888
typeof conditions === 'function' ||
2887-
typeof arguments[2] === 'function') {
2889+
typeof options === 'function' ||
2890+
typeof arguments[3] === 'function') {
28882891
throw new MongooseError('Query.prototype.distinct() no longer accepts a callback');
28892892
}
28902893

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

2909+
if (options != null) {
2910+
this.setOptions(options);
2911+
}
2912+
29062913
return this;
29072914
};
29082915

test/docs/transactions.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,25 @@ describe('transactions', function() {
338338
assert.deepEqual(fromDb, { name: 'Tyrion Lannister' });
339339
});
340340

341+
it('distinct (gh-8006)', async function() {
342+
const Character = db.model('gh8006_Character', new Schema({ name: String, rank: String }, { versionKey: false }));
343+
344+
const session = await db.startSession();
345+
346+
session.startTransaction();
347+
await Character.create([{ name: 'Will Riker', rank: 'Commander' }, { name: 'Jean-Luc Picard', rank: 'Captain' }], { session });
348+
349+
let names = await Character.distinct('name', {}, { session });
350+
assert.deepStrictEqual(names.sort(), ['Jean-Luc Picard', 'Will Riker']);
351+
352+
names = await Character.distinct('name', { rank: 'Captain' }, { session });
353+
assert.deepStrictEqual(names.sort(), ['Jean-Luc Picard']);
354+
355+
// Undo both update and delete since doc should pull from `$session()`
356+
await session.abortTransaction();
357+
session.endSession();
358+
});
359+
341360
it('save() with no changes (gh-8571)', async function() {
342361
db.deleteModel(/Test/);
343362
const Test = db.model('Test', Schema({ name: String }));

test/query.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,16 @@ describe('Query', function() {
10881088

10891089
assert.equal(q.op, 'distinct');
10901090
});
1091+
1092+
it('using options parameter for distinct', function() {
1093+
const q = new Query({});
1094+
const options = { collation: { locale: 'en', strength: 2 } };
1095+
1096+
q.distinct('blah', {}, options);
1097+
1098+
assert.equal(q.op, 'distinct');
1099+
assert.deepEqual(q.options.collation, options.collation);
1100+
});
10911101
});
10921102

10931103
describe('findOne', function() {

test/types/queries.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Test.find({ name: { $gte: 'Test' } }, null, { collation: { locale: 'en-us' } }).
109109
Test.findOne().orFail(new Error('bar')).then((doc: ITest | null) => console.log('Found! ' + doc));
110110

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

113114
Test.findOneAndUpdate({ name: 'test' }, { name: 'test2' }).exec().then((res: ITest | null) => console.log(res));
114115
Test.findOneAndUpdate({ name: 'test' }, { name: 'test2' }).then((res: ITest | null) => console.log(res));

types/models.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,8 @@ declare module 'mongoose' {
621621
/** Creates a `distinct` query: returns the distinct values of the given `field` that match `filter`. */
622622
distinct<DocKey extends string, ResultType = unknown>(
623623
field: DocKey,
624-
filter?: FilterQuery<TRawDocType>
624+
filter?: FilterQuery<TRawDocType>,
625+
options?: QueryOptions<TRawDocType>
625626
): QueryWithHelpers<
626627
Array<
627628
DocKey extends keyof WithLevel1NestedPaths<TRawDocType>

types/query.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ declare module 'mongoose' {
354354
/** Creates a `distinct` query: returns the distinct values of the given `field` that match `filter`. */
355355
distinct<DocKey extends string, ResultType = unknown>(
356356
field: DocKey,
357-
filter?: FilterQuery<RawDocType>
357+
filter?: FilterQuery<RawDocType>,
358+
options?: QueryOptions<DocType>
358359
): QueryWithHelpers<
359360
Array<
360361
DocKey extends keyof WithLevel1NestedPaths<DocType>

0 commit comments

Comments
 (0)