Skip to content

Conversation

Ritinpaul
Copy link

@Ritinpaul Ritinpaul commented Sep 28, 2025

Pull Request

Related issue

Fixes #1996

What does this PR do?

  • Adds support for the sort parameter in the documents API (index.search).
  • Updates the SearchParams type to include sort: string[].
  • Ensures that the sort parameter is correctly forwarded to the Meilisearch server.
  • Adds test cases for single-field and multi-field sorting.
  • Updates documentation and examples to include usage of the sort option.

PR checklist

Please check if your PR fulfills the following requirements:

  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Thanks a lot for reviewing this PR!

Summary by CodeRabbit

  • New Features

    • Fetch documents with sorting support, including multi-field sort (e.g., ["rating:desc","release_date:asc"]).
    • Graceful handling of empty sort arrays, returning default order.
    • Improved compatibility to recognize sort availability in newer server versions.
  • Documentation

    • Added code samples demonstrating single and multi-field document sorting.
  • Tests

    • Added comprehensive tests for sorting (single, multi-field, empty, invalid), index renaming, and index swapping.
    • Minor test cleanup.
  • Chores

    • Increased test client wait timeout for more reliable test runs.

Copy link

coderabbitai bot commented Sep 28, 2025

Walkthrough

Adds optional sort support to the documents API, normalizes params in getDocuments to omit empty sort arrays, extends types (DocumentsQuery.sort, IndexOptions.uid?, SearchResponse.queryVector?), adds code samples, and introduces tests for sorting, empty-sort handling, non-sortable errors, index rename via update, and swapIndexes with rename.

Changes

Cohort / File(s) Summary of changes
Documents API logic
src/indexes.ts
getDocuments now creates a shallow copy normalizedParams, deletes sort when it's an empty array, and uses normalizedParams for GET/POST document endpoints; JSDoc updated to reference sort.
Type updates
src/types/types.ts
Added DocumentsQuery.sort?: string[] (format attribute:direction), optional IndexOptions.uid?, and optional SearchResponse.queryVector?.
Code samples
.code-samples.meilisearch.yaml
Added samples: get_documents_sort_1 (sort by release_date:desc) and get_documents_sort_multiple_1 (sort by rating:desc, release_date:asc).
Document sorting tests
tests/documents.test.ts
New tests for single-field sort, multi-field sort, empty sort: [] behavior, and error when sorting by a non-sortable attribute.
Index rename & swap tests
tests/index.test.ts, tests/client.test.ts
Added test for renaming index via update (changing UID) and a swapIndexes test asserting rename: true appears in swap details and task type indexSwap.
Test utils update (timeouts)
tests/utils/meilisearch-test-utils.ts
Added timeout: 60_000 to defaultWaitOptions for MeiliSearch client instances.
Minor test cleanup
tests/get_search.test.ts
Removed a redundant comment; no behavior change.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App as Application
  participant SDK as SDK.getDocuments
  participant MS as Meilisearch Server

  App->>SDK: getDocuments(indexUid, params { limit, fields, sort?, ... })
  rect rgba(220,235,245,0.35)
    note right of SDK: normalize params into shallow copy
    SDK->>SDK: normalizedParams = { ...params }
    alt sort is empty array
      SDK->>SDK: delete normalizedParams.sort
      note right of SDK: omit empty sort to avoid server rejection
    else
      SDK->>SDK: keep normalizedParams.sort
    end
  end

  alt POST /documents/fetch used
    SDK->>MS: POST /indexes/:uid/documents/fetch body: normalizedParams
    MS-->>SDK: 200 Documents (sorted if requested)
  else GET /documents used
    SDK->>MS: GET /indexes/:uid/documents?{normalizedParams}
    MS-->>SDK: 200 Documents (sorted if requested)
  end

  SDK-->>App: Documents list

  rect rgba(245,225,225,0.25)
    note over MS,SDK: Error when sorting by non-sortable attribute
    MS-->>SDK: 400 "Attribute `...` is not sortable"
    SDK-->>App: Propagate error
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Fix index swaps types #2000 — Adds rename: boolean to IndexSwap and updates swap tests to assert rename: true (directly related to the new swap test).

Suggested reviewers

  • curquiza
  • flevi29

Poem

I hopped through indexes, tidy and spry,
Sorted by date and rating high.
When UIDs change and swaps ensue,
I nudged the params, omitted the blue.
Carrots for tests — a joyful chew. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request introduces unrelated changes such as new tests for index swapping and renaming, and default client timeouts, which are not part of the linked issue’s scope of adding sort support to the documents API. Consider removing or splitting out the index swap, rename, and timeout adjustments into separate pull requests to keep this submission focused on the sort parameter enhancement.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the main enhancement of the pull request by indicating that support for the sort parameter is being added to the documents API, which aligns directly with the PR’s primary change.
Linked Issues Check ✅ Passed The pull request updates the documents methods to accept the sort parameter, adds corresponding type definitions, forwards the parameter to the server, and includes new tests for single-field and multi-field sorting, fulfilling the tasks defined in issue #1996.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between beccd2c and 09ce73d.

📒 Files selected for processing (4)
  • tests/client.test.ts (2 hunks)
  • tests/get_search.test.ts (0 hunks)
  • tests/index.test.ts (1 hunks)
  • tests/utils/meilisearch-test-utils.ts (4 hunks)
💤 Files with no reviewable changes (1)
  • tests/get_search.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/client.test.ts
  • tests/index.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
tests/utils/meilisearch-test-utils.ts (1)
src/meilisearch.ts (1)
  • MeiliSearch (49-570)
🔇 Additional comments (1)
tests/utils/meilisearch-test-utils.ts (1)

19-19: LGTM! Timeout additions improve test reliability.

Adding explicit timeout: 60_000 to defaultWaitOptions ensures test operations won't hang indefinitely, improving test suite reliability. The 60-second timeout aligns with the explicit timeout used in waitTask calls (line 97).

Also applies to: 28-28, 33-33, 73-73, 83-83


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/documents.test.ts (1)

292-301: Strengthen multi-field sort assertion

We’re aiming to verify forwarding of the entire sort array, yet this check only confirms the first entry (id:desc). Because id stays unique in dataset, a regression that strips the secondary key (title:asc) would still pass. Please reshape the test data or expectations so the first sort key contains duplicates (e.g., sort primarily on genre) and assert the order within those duplicates; that way the test actually fails if we drop the second key.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f7c885 and 7f161f0.

📒 Files selected for processing (9)
  • .code-samples.meilisearch.yaml (2 hunks)
  • package.json (1 hunks)
  • src/indexes.ts (1 hunks)
  • src/types/types.ts (3 hunks)
  • tests/client.test.ts (1 hunks)
  • tests/documents.test.ts (1 hunks)
  • tests/get_search.test.ts (0 hunks)
  • tests/index.test.ts (1 hunks)
  • tests/utils/meilisearch-test-utils.ts (4 hunks)
💤 Files with no reviewable changes (1)
  • tests/get_search.test.ts
🧰 Additional context used
🧬 Code graph analysis (5)
tests/client.test.ts (3)
tests/utils/meilisearch-test-utils.ts (1)
  • getClient (369-369)
src/meilisearch.ts (1)
  • index (92-94)
src/types/task_and_batch.ts (1)
  • IndexSwap (109-112)
tests/index.test.ts (1)
src/types/types.ts (2)
  • ErrorStatusCode (864-1224)
  • ErrorStatusCode (1226-1227)
tests/utils/meilisearch-test-utils.ts (1)
src/meilisearch.ts (1)
  • MeiliSearch (49-570)
tests/documents.test.ts (2)
tests/env/node/getting_started.cjs (1)
  • dataset (12-19)
tests/utils/meilisearch-test-utils.ts (2)
  • dataset (372-372)
  • Book (339-345)
src/indexes.ts (1)
src/types/types.ts (1)
  • ResourceResults (129-132)

Comment on lines 34 to 35
rename_an_index_1: |-
client.updateIndex('INDEX_A', { indexUid: 'INDEX_B' })
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix the rename example to use the correct payload key

updateIndex expects the new identifier under uid, not indexUid. Shipping this sample as-is will make readers copy a snippet that the server rejects.(meilisearch.com)

-  client.updateIndex('INDEX_A', { indexUid: 'INDEX_B' })
+  client.updateIndex('INDEX_A', { uid: 'INDEX_B' })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rename_an_index_1: |-
client.updateIndex('INDEX_A', { indexUid: 'INDEX_B' })
rename_an_index_1: |-
client.updateIndex('INDEX_A', { uid: 'INDEX_B' })
🤖 Prompt for AI Agents
In .code-samples.meilisearch.yaml around lines 34 to 35, the example uses an
incorrect payload key `indexUid` when calling client.updateIndex; the API
expects the new identifier under the `uid` key. Change the payload object to use
`uid: 'INDEX_B'` instead of `indexUid: 'INDEX_B'` so the sample matches the
server expectation.

Comment on lines 570 to 608
test(`${permission} key: Swap two indexes with rename`, async () => {
const client = await getClient(permission);
const originalUid1 = index.uid;
const originalUid2 = index2.uid;

await client
.index(originalUid1)
.addDocuments([{ id: 1, title: "index_1" }])
.waitTask();
await client
.index(originalUid2)
.addDocuments([{ id: 1, title: "index_2" }])
.waitTask();

const swaps: IndexSwap[] = [
{ indexes: [originalUid1, originalUid2], rename: true },
];

const resolvedTask = await client.swapIndexes(swaps).waitTask();

// Verify the swap task completed with expected details
expect(resolvedTask.type).toEqual("indexSwap");
expect(resolvedTask.details?.swaps).toEqual(swaps);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Rename swap test should assert a successful rename

We’re pre-populating both indexes and then calling swapIndexes with rename: true, even though the API expects the second UID to be unused when you opt into rename mode. If the server rejects the rename (e.g., with index_already_exists), the test still “passes” because we only read the task type/details and never assert success or the post-rename state. Let’s stop creating the destination index ahead of time and assert that the task succeeds and that the old UID is gone while the new UID now holds the payload.(meilisearch.com)

-        await client
-          .index(originalUid2)
-          .addDocuments([{ id: 1, title: "index_2" }])
-          .waitTask();
-
         const swaps: IndexSwap[] = [
           { indexes: [originalUid1, originalUid2], rename: true },
         ];
 
         const resolvedTask = await client.swapIndexes(swaps).waitTask();
 
-        // Verify the swap task completed with expected details
-        expect(resolvedTask.type).toEqual("indexSwap");
-        expect(resolvedTask.details?.swaps).toEqual(swaps);
+        expect(resolvedTask.status).toEqual("succeeded");
+        expect(resolvedTask.type).toEqual("indexSwap");
+        expect(resolvedTask.details?.swaps).toEqual(swaps);
+        await expect(
+          client.index(originalUid1).getDocument(1),
+        ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INDEX_NOT_FOUND);
+        const renamedDoc = await client.index(originalUid2).getDocument(1);
+        expect(renamedDoc.title).toEqual("index_1");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test(`${permission} key: Swap two indexes with rename`, async () => {
const client = await getClient(permission);
const originalUid1 = index.uid;
const originalUid2 = index2.uid;
await client
.index(originalUid1)
.addDocuments([{ id: 1, title: "index_1" }])
.waitTask();
await client
.index(originalUid2)
.addDocuments([{ id: 1, title: "index_2" }])
.waitTask();
const swaps: IndexSwap[] = [
{ indexes: [originalUid1, originalUid2], rename: true },
];
const resolvedTask = await client.swapIndexes(swaps).waitTask();
// Verify the swap task completed with expected details
expect(resolvedTask.type).toEqual("indexSwap");
expect(resolvedTask.details?.swaps).toEqual(swaps);
});
test(`${permission} key: Swap two indexes with rename`, async () => {
const client = await getClient(permission);
const originalUid1 = index.uid;
const originalUid2 = index2.uid;
// only populate the source index
await client
.index(originalUid1)
.addDocuments([{ id: 1, title: "index_1" }])
.waitTask();
const swaps: IndexSwap[] = [
{ indexes: [originalUid1, originalUid2], rename: true },
];
const resolvedTask = await client.swapIndexes(swaps).waitTask();
expect(resolvedTask.status).toEqual("succeeded");
expect(resolvedTask.type).toEqual("indexSwap");
expect(resolvedTask.details?.swaps).toEqual(swaps);
// originalUid1 should no longer exist
await expect(
client.index(originalUid1).getDocument(1),
).rejects.toHaveProperty("cause.code", ErrorStatusCode.INDEX_NOT_FOUND);
// new index originalUid2 should now contain the documents from originalUid1
const renamedDoc = await client.index(originalUid2).getDocument(1);
expect(renamedDoc.title).toEqual("index_1");
});
🤖 Prompt for AI Agents
In tests/client.test.ts around lines 570 to 593, the rename-swap test is
creating both source and destination indexes then calling swapIndexes with
rename:true which violates the API expectation and allows silent rejection;
remove the code that pre-creates/populates the destination index (originalUid2),
call swapIndexes with rename:true where originalUid2 is unused, await the task
and assert it succeeded (e.g., status 'succeeded'), then verify the old UID no
longer exists and the new UID contains the expected document (check the document
by id/title) to confirm the rename occurred.

@Ritinpaul Ritinpaul force-pushed the feat/documents-api-sort branch from 7f161f0 to 1a1f07f Compare September 28, 2025 11:09
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f161f0 and 1a1f07f.

📒 Files selected for processing (4)
  • .code-samples.meilisearch.yaml (1 hunks)
  • src/indexes.ts (1 hunks)
  • src/types/types.ts (3 hunks)
  • tests/documents.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • .code-samples.meilisearch.yaml
  • src/indexes.ts
  • src/types/types.ts
🧰 Additional context used
🧬 Code graph analysis (1)
tests/documents.test.ts (2)
tests/env/node/getting_started.cjs (2)
  • client (4-7)
  • dataset (12-19)
tests/utils/meilisearch-test-utils.ts (3)
  • getClient (369-369)
  • dataset (372-372)
  • Book (339-345)

Copy link

codecov bot commented Sep 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.84%. Comparing base (4f7c885) to head (09ce73d).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2038   +/-   ##
=======================================
  Coverage   98.83%   98.84%           
=======================================
  Files          18       18           
  Lines        1549     1557    +8     
  Branches      334      338    +4     
=======================================
+ Hits         1531     1539    +8     
  Misses         18       18           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

[v1.16.0] Add support for sorting on the documents API

1 participant