Skip to content

fix(NODE-7643): 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(NODE-7643): 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
@johnmtll

johnmtll commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Thank you for taking the time to fill out this detailed PR! This PR will be tracked by NODE-7643 and will be prioritized in the next triage session.

@johnmtll johnmtll changed the title fix: preserve $meta direction in [field, direction] sort pair fix(NODE-7658): preserve $meta direction in [field, direction] sort pair Jul 7, 2026
@johnmtll johnmtll added External Submission PR submitted from outside the team tracked-in-jira Ticket filed in MongoDB's Jira system labels Jul 7, 2026
@johnmtll johnmtll changed the title fix(NODE-7658): preserve $meta direction in [field, direction] sort pair fix(NODE-7643): preserve $meta direction in [field, direction] sort pair Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Submission PR submitted from outside the team tracked-in-jira Ticket filed in MongoDB's Jira system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants