Skip to content

Commit e8ce022

Browse files
authored
Merge pull request #14375 from Automattic/vkarpov15/gh-14365
feat(query): add `options` parameter to `Query.prototype.sort()`
2 parents 31e0a69 + 4beb8bc commit e8ce022

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

lib/query.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,19 +2861,27 @@ Query.prototype.distinct = function(field, conditions) {
28612861
* Cannot be used with `distinct()`
28622862
*
28632863
* @param {Object|String|Array<Array<(string | number)>>} arg
2864+
* @param {Object} [options]
2865+
* @param {Boolean} [options.override=false] If true, replace existing sort options with `arg`
28642866
* @return {Query} this
28652867
* @see cursor.sort https://www.mongodb.com/docs/manual/reference/method/cursor.sort/
28662868
* @api public
28672869
*/
28682870

2869-
Query.prototype.sort = function(arg) {
2870-
if (arguments.length > 1) {
2871-
throw new Error('sort() only takes 1 Argument');
2871+
Query.prototype.sort = function(arg, options) {
2872+
if (arguments.length > 2) {
2873+
throw new Error('sort() takes at most 2 arguments');
2874+
}
2875+
if (options != null && typeof options !== 'object') {
2876+
throw new Error('sort() options argument must be an object or nullish');
28722877
}
28732878

28742879
if (this.options.sort == null) {
28752880
this.options.sort = {};
28762881
}
2882+
if (options && options.override) {
2883+
this.options.sort = {};
2884+
}
28772885
const sort = this.options.sort;
28782886
if (typeof arg === 'string') {
28792887
const properties = arg.indexOf(' ') === -1 ? [arg] : arg.split(' ');

test/query.test.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ describe('Query', function() {
795795
e = err;
796796
}
797797
assert.ok(e, 'uh oh. no error was thrown');
798-
assert.equal(e.message, 'sort() only takes 1 Argument');
798+
assert.equal(e.message, 'sort() takes at most 2 arguments');
799799

800800
});
801801
});
@@ -4191,4 +4191,27 @@ describe('Query', function() {
41914191
assert.strictEqual(doc.account.owner, undefined);
41924192
assert.strictEqual(doc.account.taxIds, undefined);
41934193
});
4194+
4195+
it('allows overriding sort (gh-14365)', function() {
4196+
const testSchema = new mongoose.Schema({
4197+
name: String
4198+
});
4199+
4200+
const Test = db.model('Test', testSchema);
4201+
4202+
const q = Test.find().select('name').sort({ name: -1, _id: -1 });
4203+
assert.deepStrictEqual(q.getOptions().sort, { name: -1, _id: -1 });
4204+
4205+
q.sort({ name: 1 }, { override: true });
4206+
assert.deepStrictEqual(q.getOptions().sort, { name: 1 });
4207+
4208+
q.sort(null, { override: true });
4209+
assert.deepStrictEqual(q.getOptions().sort, {});
4210+
4211+
q.sort({ _id: 1 }, { override: true });
4212+
assert.deepStrictEqual(q.getOptions().sort, { _id: 1 });
4213+
4214+
q.sort({}, { override: true });
4215+
assert.deepStrictEqual(q.getOptions().sort, {});
4216+
});
41944217
});

types/query.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,10 @@ declare module 'mongoose' {
715715
slice(val: number | Array<number>): this;
716716

717717
/** Sets the sort order. If an object is passed, values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`. */
718-
sort(arg?: string | { [key: string]: SortOrder | { $meta: any } } | [string, SortOrder][] | undefined | null): this;
718+
sort(
719+
arg?: string | { [key: string]: SortOrder | { $meta: any } } | [string, SortOrder][] | undefined | null,
720+
options?: { override?: boolean }
721+
): this;
719722

720723
/** Sets the tailable option (for use with capped collections). */
721724
tailable(bool?: boolean, opts?: {

0 commit comments

Comments
 (0)