Repository navigation
fix(NODE-7643): preserve $meta direction in [field, direction] sort pair - #4988
Conversation
|
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. |
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.
662d2c0 to
4311080
Compare
|
@johnmtll, thank you for landing #4989 on 2 October. This one is now rebased onto The bug is one line in Should I add integration coverage here too, as on #4989? Evergreen will need authorizing on the new head. |
|
Hi @spokodev, thanks a lot for the PR! Yes, can you please add integration tests for the fix? |
|
Thanks, @tadjik1. Added an integration test in abf28d6, next to the existing text search sort test in Their scores are 1.5, 1, 0.75 and 2/3, so the expected order has no ties. On the old I ran it against a local standalone mongod 8.0.32: all of I also corrected the PR description. The array wrapping came from #2788, not from #2573: with |
Description
Sorting by
$metais rejected in the[field, direction]pair form ofsort. The type-legal inputthrows:
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,pairToMapcallsprepareDirection([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$metaobject does not (isMetareturns false for an array), so it is rejected.This is a regression from #2788 (NODE-3174), which replaced
pairToObjectwithpairToMapand wrapped the direction in an array. Withsrc/sort.tsfrom just before #2788, the pair form returns{ score: { $meta: 'textScore' } }.Fix
Test
Added
test/unit/sort.test.ts(notest/unitfile coveredformatSortbefore). The$metapair case fails unpatched with the error above and passes after; the scalar-direction pair cases pass throughout, showing the fix is scoped. Fulltest/unitsuite stays green.Also added an integration test in
test/integration/crud/find.test.ts: a text index ontitle, a$textsearch with the score projected, sorted with['score', { $meta: 'textScore' }]. It fails unpatched with the same error and passes after.Release Highlight
Sorting by
$metawith a[field, direction]pair now worksPreviously, passing a
$metasort direction in the[field, direction]form, for examplecursor.sort(['score', { $meta: 'textScore' }]), threwMongoInvalidArgumentError: Invalid sort direction. The object form ({ score: { $meta: 'textScore' } }) and the nested array form ([['score', { $meta: 'textScore' }]]) already worked, so the same sort was accepted or rejected depending on how it was written. All three forms now behave the same.Thanks to @spokodev for the fix!
Double check the following
npm run check:lint)type(NODE-xxxx)[!]: descriptionfeat(NODE-1234)!: rewriting everything in coffeescript