Skip to content

Conversation

@Strift
Copy link
Collaborator

@Strift Strift commented Sep 18, 2025

Pull Request

What does this PR do?

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?

Thank you so much for contributing to Meilisearch!

Summary by CodeRabbit

  • New Features
    • Added sorting support to document queries, including multi-criteria sort and compatibility with filtering and field selection.
  • Bug Fixes
    • List-valued query parameters are now encoded as comma-separated strings for consistent API requests.
  • Tests
    • Added and updated tests to validate sorting and combined sort/filter/fields behavior.
  • Chores
    • Added symfony/polyfill-php81 dependency.

@Strift Strift added the enhancement New feature or request label Sep 18, 2025
@Strift Strift requested a review from norkunas September 18, 2025 09:39
@coderabbitai
Copy link

coderabbitai bot commented Sep 18, 2025

Walkthrough

Adds sort support to DocumentsQuery, updates query serialization to collapse list-valued parameters into comma-separated strings, adjusts tests to validate sorting and combined sort/filter/fields behavior, and adds a PHP 8.1 polyfill dependency in composer.json.

Changes

Cohort / File(s) Summary
Composer metadata
composer.json
Added require dependency symfony/polyfill-php81 (^1.33); minor trailing comma adjustment.
Documents query model
src/Contracts/DocumentsQuery.php
Added private sort (list
HTTP client query serialization
src/Http/Client.php
buildQueryString now converts list arrays to comma-separated strings via implode(',', $value) after boolean handling.
Unit tests (Contracts)
tests/Contracts/DocumentsQueryTest.php
Updated expectation: fields remains an array in toArray() (e.g., ['abc','xyz']) instead of a comma-joined string.
Integration tests (Endpoints)
tests/Endpoints/DocumentsTest.php
Replaced field-format test with sorting tests; added combined test validating sort, filters, and selected fields.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User Code
  participant Q as DocumentsQuery
  participant C as Http\Client
  participant S as Meilisearch Server

  U->>Q: setFields(['id','title'])<br/>setSort(['genre:desc','id:asc'])
  U->>C: getDocuments(index, Q->toArray())

  note over Q,C: Q->toArray() returns arrays for fields/sort

  C->>C: buildQueryString(params)
  rect rgba(220,240,255,0.4)
    note right of C: For each param value
    C->>C: if bool → 'true'/'false'
    C->>C: if list array → implode with ','
  end
  C->>S: GET /indexes/{uid}/documents?fields=id,title&sort=genre:desc,id:asc&filter=...
  S-->>C: 200 OK JSON
  C-->>U: Decoded response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Possibly related PRs

Poem

A bunny taps keys with a rhythmic sort,
Arrays align—comma ships make port.
Fields stay neat, filters stand by,
Queries hop swiftly, replies fly.
In the meadow of docs, results accord—
Carrots for order, parsley for score.
Thump! Another tidy record. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore: backport document sorting to v1.x" is concise and directly summarizes the primary change in the changeset — backporting document sorting to the v1.x branch as shown by the added sort support in DocumentsQuery, updated query serialization, and adjusted tests — and contains no noisy or misleading information.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/backport-document-sort

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

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

@Strift
Copy link
Collaborator Author

Strift commented Sep 18, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Sep 18, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Strift Strift requested a review from a team September 18, 2025 09:50
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: 0

🧹 Nitpick comments (7)
src/Contracts/DocumentsQuery.php (4)

36-39: Align sort typing with behavior (non-empty list vs possibly empty).

Property doc allows any list; toArray advertises non-empty-list. Either (a) normalize empty to null, or (b) relax the toArray phpdoc. Prefer (a) to avoid sending sort=.

Apply this if you choose (a):

-    /**
-     * @var list<non-empty-string>|null
-     */
-    private ?array $sort = null;
+    /**
+     * @var non-empty-list<non-empty-string>|null
+     */
+    private ?array $sort = null;

125-133: Normalize and validate sort values; avoid empty payloads.

Trim entries, drop empties, and null-out when nothing remains to prevent sending sort="".

-    public function setSort(array $sort): self
-    {
-        $this->sort = $sort;
-
-        return $this;
-    }
+    public function setSort(array $sort): self
+    {
+        $sort = array_values(array_filter(
+            array_map(static fn($s) => \is_string($s) ? trim($s) : (string) $s, $sort),
+            static fn(string $s) => $s !== ''
+        ));
+        $this->sort = $sort !== [] ? $sort : null;
+        return $this;
+    }

136-145: PhpDoc return shape for fields is outdated.

toArray() now returns fields as an array; the union allowing non-empty-string is misleading.

-     *     fields?: non-empty-list<string>|non-empty-string,
+     *     fields?: non-empty-list<string>,

Also consider documenting ids as “comma-separated string of IDs” for clarity.


151-156: Skip empty arrays for fields/sort in payload.

Sending fields=[] or sort=[] yields fields= or sort= after transport coercion. Treat empty as unset.

-            'fields' => $this->fields,
+            'fields' => ($this->fields ?? []) !== [] ? $this->fields : null,
...
-            'sort' => $this->sort,
+            'sort' => ($this->sort ?? []) !== [] ? $this->sort : null,
src/Http/Client.php (1)

224-226: Only implode list arrays when all elements are scalars.

As written, any list is imploded. If a list contains nested arrays (e.g., complex filters) passed via query, it will flatten incorrectly.

-            if (\is_array($value) && array_is_list($value)) {
-                $queryParams[$key] = implode(',', $value);
-            }
+            if (\is_array($value) && array_is_list($value) && self::isListOfScalars($value)) {
+                $queryParams[$key] = implode(',', array_map('strval', $value));
+            }

Add this helper in the class (outside this hunk):

private static function isListOfScalars(array $list): bool
{
    foreach ($list as $v) {
        if (\is_array($v) || \is_object($v)) {
            return false;
        }
    }
    return true;
}
tests/Endpoints/DocumentsTest.php (2)

681-694: Sorting test looks good; minor stability tweak optional.

You rely on Meilisearch task ordering by waiting only on addDocuments. It’s fine (tasks are FIFO), but explicitly waiting for the settings tasks would make the test more robust to future changes in server semantics.

-        $index->updateSortableAttributes(['id', 'genre']);
-        $index->updateFilterableAttributes(['id', 'genre']);
-        $promise = $index->addDocuments(self::DOCUMENTS);
+        $t1 = $index->updateSortableAttributes(['id', 'genre']);
+        $t2 = $index->updateFilterableAttributes(['id', 'genre']);
+        $index->waitForTask($t1['taskUid']);
+        $index->waitForTask($t2['taskUid']);
+        $promise = $index->addDocuments(self::DOCUMENTS);

696-711: Avoid key-order brittleness in field selection assertion.

JSON key order isn’t guaranteed; assert on set equality instead of order.

-        self::assertSame(['id', 'title'], array_keys($response[0]));
+        self::assertSameCanonicalizing(['id', 'title'], array_keys($response[0]));

Optionally also assert count($response[0]) === 2 to ensure no extra fields leak.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55499d8 and ba6d5c1.

📒 Files selected for processing (5)
  • composer.json (1 hunks)
  • src/Contracts/DocumentsQuery.php (2 hunks)
  • src/Http/Client.php (1 hunks)
  • tests/Contracts/DocumentsQueryTest.php (1 hunks)
  • tests/Endpoints/DocumentsTest.php (1 hunks)
🔇 Additional comments (2)
composer.json (1)

37-39: Good call adding the PHP 8.1 polyfill for array_is_list.

This keeps v1.x working on PHP < 8.1 while using array_is_list in the client. LGTM.

tests/Contracts/DocumentsQueryTest.php (1)

23-23: Assertion updated to array format — matches new API shape.

This reflects the toArray() change. LGTM.

@Strift Strift merged commit 2cb63d3 into v1.x Sep 18, 2025
11 checks passed
@Strift Strift deleted the chore/backport-document-sort branch September 18, 2025 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants