Skip to content

fix: preserve $meta direction in [field, direction] sort pair#4988

Open
spokodev wants to merge 1 commit into
mongodb:mainfrom
spokodev:w32/mongo-sort-meta-pair
Open

fix: preserve $meta direction in [field, direction] sort pair#4988
spokodev wants to merge 1 commit into
mongodb:mainfrom
spokodev:w32/mongo-sort-meta-pair

Conversation

@spokodev

@spokodev spokodev commented Jul 2, 2026

Copy link
Copy Markdown

Description

Sorting by $meta is silently rejected in the [field, direction] pair form of sort. The documented, type-legal input

cursor.sort(['score', { $meta: 'textScore' }])

which is the canonical way to sort full-text search results by relevance, throws:

MongoInvalidArgumentError: Invalid sort direction: [{"$meta":"textScore"}]

The equivalent object form { score: { $meta: 'textScore' } } and the deep form [['score', { $meta: 'textScore' }]] both work, so the three shapes the API accepts behave inconsistently.

Root cause

In src/sort.ts, pairToMap calls prepareDirection([v[1]]), wrapping the direction in an array, unlike every sibling converter which passes the raw value. A scalar direction coincidentally survives the array to string coercion ([-1] -> "-1"), but a $meta object does not (isMeta returns false for an array), so it is rejected.

This is a regression: $meta-in-pair support was added in #1808, and the #2573 sort refactor reintroduced the array wrapping.

Fix

-  return new Map([[`${v[0]}`, prepareDirection([v[1]])]]);
+  return new Map([[`${v[0]}`, prepareDirection(v[1])]]);

Test

Added test/unit/sort.test.ts (no test/unit file covered formatSort before). The $meta pair case fails unpatched with the error above and passes after; the scalar-direction pair cases pass throughout, showing the fix is scoped. Full test/unit suite stays green.

formatSort's pairToMap wrapped the direction in an array
(prepareDirection([v[1]])) unlike every sibling converter. Scalar directions
survive the array-to-string coercion, but a $meta object does not (isMeta is
false for an array), so the documented cursor.sort(['score', { $meta:
'textScore' }]) throws Invalid sort direction while the object and deep-array
forms work. Pass the raw value through, as the other converters do.
@spokodev spokodev requested a review from a team as a code owner July 2, 2026 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant