Skip to content

Add custom metadata support for document tasks#736

Open
kumarUjjawal wants to merge 1 commit into
meilisearch:mainfrom
kumarUjjawal:feat/metadata
Open

Add custom metadata support for document tasks#736
kumarUjjawal wants to merge 1 commit into
meilisearch:mainfrom
kumarUjjawal:feat/metadata

Conversation

@kumarUjjawal
Copy link
Copy Markdown
Contributor

@kumarUjjawal kumarUjjawal commented Nov 26, 2025

Pull Request

Related issue

Fixes #733

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 optional per-request custom metadata for document operations; metadata is preserved and surfaced in task/status responses for better tracking.
  • Documentation

    • Examples, doctests, and README updated to show supplying and reading custom metadata; tests adjusted to reflect the new parameter.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 26, 2025

📝 Walkthrough

Walkthrough

Adds an optional per-request custom_metadata: Option<&str> parameter to document-related index methods, propagates it into request payloads as DocumentTaskQuery, and surfaces it in task responses via new custom_metadata: Option<String> fields on task/TaskInfo structs; examples/tests updated to pass None where applicable.

Changes

Cohort / File(s) Summary
Core Index API
src/indexes.rs
Added DocumentTaskQuery<'a> (primary_key + custom_metadata) and updated many Index methods to accept custom_metadata: Option<&str> (add/update/delete variants, batch/ndjson/csv). Requests now send DocumentTaskQuery as the query payload.
Document API & Helpers
src/documents.rs
Added execute_with_custom_metadata for deletion queries; execute delegates to it. Delete helpers updated to accept and forward custom_metadata.
Client & Call Sites
src/client.rs, src/search.rs, src/lib.rs
Updated method signatures/usages and doctests to include the new custom_metadata parameter; call sites updated to pass None where metadata is not provided.
Task & TaskInfo structs
src/task_info.rs, src/tasks.rs
Added pub custom_metadata: Option<String> to TaskInfo, SucceededTask, EnqueuedTask, and ProcessingTask; deserialization maps customMetadata.
Examples & Apps
examples/cli-app/src/main.rs, examples/cli-app-with-awc/src/main.rs, examples/web_app_graphql/src/graphql_schema/.../search.rs, README.md
Example and sample app call sites updated to pass an extra None argument for the new parameter.
Tests & Misc
tests..., src/documents.rs (tests)
Tests updated/extended to assert propagation of custom_metadata; helpers added to check task metadata; test setup calls updated to include None where needed.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant Index
    participant DocQuery as DocumentTaskQuery
    participant HTTP
    participant TaskInfo

    rect rgba(120,180,240,0.08)
    App->>Index: add_documents(docs, primary_key, custom_metadata)
    note right of Index: builds DocumentTaskQuery(primary_key, custom_metadata)
    Index->>DocQuery: DocumentTaskQuery::new(primary_key, custom_metadata)
    Index->>HTTP: POST /indexes/{uid}/documents\n(payload: DocQuery + docs)
    end

    rect rgba(160,220,140,0.08)
    HTTP->>TaskInfo: returns TaskInfo JSON (includes customMetadata)
    TaskInfo->>App: TaskInfo { custom_metadata: Some("..."), ... }
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

breaking-change

Suggested reviewers

  • curquiza

Poem

🐰 I hopped through code both bright and spry,

Tucked metadata where tasks go by,
Each batch now wears a tiny note,
A carrot-tag upon the tote,
Hop, patch, and sparkle — metadata nigh! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add custom metadata support for document tasks' accurately and concisely summarizes the main change in the pull request, which adds custom metadata parameters to document-related API methods.
Linked Issues check ✅ Passed The pull request successfully implements all objectives from issue #733: adds optional metadata parameters to all specified document operation methods (add_or_replace, add_documents, add_or_update, delete_all_documents, delete_document, delete_documents, etc.) and includes test cases validating metadata propagation.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing custom metadata support for document tasks as specified in linked issue #733; no unrelated or out-of-scope changes are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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.

Copy link
Copy Markdown
Contributor

@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 (3)
src/tasks.rs (1)

154-175: Expose custom_metadata on task variants in a backward-compatible way

Adding pub custom_metadata: Option<String> to SucceededTask, EnqueuedTask, and ProcessingTask under #[serde(rename_all = "camelCase")] correctly maps the server’s customMetadata field and remains backward-compatible for deserialization (field is optional and existing JSON still matches via .. patterns in tests). Consider adding a brief doc comment on this field to make its relation to Meilisearch’s “tasks custom metadata” feature explicit for SDK users.

Also applies to: 183-196, 204-219

src/documents.rs (1)

415-427: DocumentDeletionQuery metadata extension looks correct and keeps API stable

execute delegating to execute_with_custom_metadata with None preserves the old API while adding the new capability. Lifetimes on custom_metadata: Option<&'a str> are consistent with the struct’s lifetime, and the call into Index::delete_documents_with matches the new signature.

One minor nit: the generic T: DeserializeOwned + 'static on both methods is now unused; if you ever do a breaking release, consider simplifying these to non‑generic fns or adding a PhantomData<T> to avoid the unused type parameter warning. For now, this is harmless and keeps source compatibility.

src/indexes.rs (1)

592-666: Write/update document routes correctly propagate custom_metadata

For add_or_replace, add_documents, add_or_update, and their *_unchecked_payload / NDJSON / CSV variants, the extra custom_metadata: Option<&str> is consistently threaded into a DocumentTaskQuery::new(primary_key, custom_metadata) used as the request’s query payload. This keeps existing primary key behavior intact while adding metadata support on all the expected code paths, including streaming ones.

Given the repeated pattern (build URL, construct DocumentTaskQuery, then call request or stream_request), you might later consider a small private helper to reduce duplication, but it’s not necessary for clarity or correctness right now.

Also applies to: 706-739, 779-846, 884-940, 942-1013, 1055-1078

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16a31ae and 0fad2af.

📒 Files selected for processing (10)
  • examples/cli-app-with-awc/src/main.rs (1 hunks)
  • examples/cli-app/src/main.rs (1 hunks)
  • examples/web_app_graphql/src/graphql_schema/users/query/search.rs (2 hunks)
  • src/client.rs (6 hunks)
  • src/documents.rs (5 hunks)
  • src/indexes.rs (51 hunks)
  • src/lib.rs (2 hunks)
  • src/search.rs (3 hunks)
  • src/task_info.rs (5 hunks)
  • src/tasks.rs (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-12T13:28:23.700Z
Learnt from: LukasKalbertodt
Repo: meilisearch/meilisearch-rust PR: 625
File: src/search.rs:368-370
Timestamp: 2025-06-12T13:28:23.700Z
Learning: In the Meilisearch Rust client, `SearchQuery` serializes its per-query federation settings under the key `federationOptions`; only the top-level multi-search parameter is named `federation`.

Applied to files:

  • src/client.rs
🧬 Code graph analysis (7)
src/tasks.rs (1)
src/client.rs (2)
  • None (1532-1532)
  • None (1613-1613)
src/task_info.rs (1)
src/client.rs (2)
  • None (1532-1532)
  • None (1613-1613)
examples/cli-app-with-awc/src/main.rs (1)
src/client.rs (2)
  • None (1532-1532)
  • None (1613-1613)
src/search.rs (1)
src/client.rs (2)
  • None (1532-1532)
  • None (1613-1613)
examples/cli-app/src/main.rs (1)
src/client.rs (2)
  • None (1532-1532)
  • None (1613-1613)
src/client.rs (2)
src/reqwest.rs (1)
  • qualified_version (131-135)
src/batches.rs (3)
  • None (141-141)
  • None (169-169)
  • None (193-193)
src/indexes.rs (2)
src/documents.rs (7)
  • new (89-94)
  • new (218-228)
  • new (400-405)
  • index (62-64)
  • index (161-161)
  • index (383-383)
  • index (544-544)
src/request.rs (1)
  • query (39-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: integration-tests
🔇 Additional comments (16)
examples/cli-app-with-awc/src/main.rs (1)

186-194: Example call correctly updated for new add_or_update signature

Adding the trailing None keeps this example in sync with the new add_or_update API while preserving existing behavior (no custom metadata sent).

src/lib.rs (2)

29-38: Top-level “Add Documents” doctest matches extended add_documents API

The extra None parameter correctly accounts for the new optional metadata argument without changing the example’s behavior.


182-190: Filterable attributes doctest updated consistently for metadata argument

This doctest’s add_documents call now matches the three-argument signature and keeps the example behavior intact by passing None metadata.

examples/web_app_graphql/src/graphql_schema/users/query/search.rs (1)

24-38: GraphQL example updated correctly for add_documents metadata parameter

Both add_documents calls now include the new optional metadata argument as None, keeping control flow and behavior identical while aligning with the updated API.

examples/cli-app/src/main.rs (1)

110-118: CLI example synchronized with new add_or_update signature

The additional None argument for metadata is correct and keeps this example compiling and behaving as before.

src/tasks.rs (1)

290-299: Docs and tests now use three-argument add_documents consistently

The Task docs example and all affected tests now call add_documents with (…, primary_key_opt, None) which matches the extended API and keeps the existing semantics (no metadata) while exercising the new parameter.

Also applies to: 935-961, 1225-1238, 1258-1289

src/task_info.rs (1)

9-18: TaskInfo now surfaces custom_metadata with solid deserialization coverage

Exposing pub custom_metadata: Option<String> on TaskInfo (camelCase serde) matches the server field, and the updated test_deserialize_task_info verifies correct mapping from "customMetadata". The updated add_documents(&[..], None, None) usage in the async test keeps behavior unchanged while aligning with the new API.

Also applies to: 114-141, 145-176

src/search.rs (1)

972-985: Search examples/tests correctly updated for metadata-aware document APIs

The facet-search documentation now calls add_or_replace with the extra metadata argument as None, and both setup_test_index helpers use the three-argument add_documents signature. All of these keep test and example behavior intact while matching the new API.

Also applies to: 1225-1238, 1258-1289

src/client.rs (2)

167-191: Client documentation kept in sync with extended document/task APIs

The multi-search, wait_for_task, and get_task examples now use add_or_replace, add_documents, and delete_all_documents with their updated signatures (extra metadata or options argument), consistently passing None where no metadata is desired. This maintains example behavior while matching the new public API surface.

Also applies to: 889-919, 956-968


1548-1549: Tests correctly import qualified_version and use new add_documents signature

Bringing reqwest::qualified_version into scope matches its use in test_methods_has_qualified_version_as_header, and the two add_documents calls in test_swapping_two_indexes now include the trailing None metadata argument, keeping the test logic unchanged but compatible with the updated API.

Also applies to: 1560-1580

src/documents.rs (1)

144-144: Updated call sites for extra custom_metadata parameter are consistent

The additional None arguments wired into add_or_replace in the doctest, setup_test_index, and the two delete_documents_with test calls align with the new API and keep existing behavior (no metadata) unchanged.

Also applies to: 488-488, 540-541, 569-570

src/indexes.rs (5)

80-103: DocumentTaskQuery design matches Meilisearch query conventions

The internal DocumentTaskQuery<'a> cleanly encapsulates primary_key and custom_metadata with #[serde(rename_all = "camelCase")] and skip_serializing_if = "Option::is_none", which should serialize to the expected primaryKey / customMetadata query parameters only when present. Using separate constructors (new and with_metadata) keeps call sites clear between routes that also set a primary key and those that only tag tasks.

No issues from a correctness perspective.


1080-1131: Delete document APIs now support per-task metadata without changing semantics

delete_all_documents, delete_document, delete_documents, and delete_documents_with now all accept custom_metadata: Option<&str> and wrap it via DocumentTaskQuery::with_metadata(custom_metadata) passed as the query component of the HTTP method. Bodies (when present) remain unchanged, so server-side behavior for filters and ID lists is preserved; only the optional metadata is new.

The use of Method::<_, ()>::Delete { query } for DELETE routes is type-correct with the generic Method<Q, B> definition, and lifetimes on the borrowed &str metadata are no stricter than existing borrowed query structs elsewhere in this module.

Also applies to: 1133-1185, 1187-1242, 1285-1302


1673-1687: Batch helpers correctly fan out custom_metadata per produced task

add_documents_in_batches and update_documents_in_batches now accept custom_metadata: Option<&str> and forward it unchanged into each inner add_documents / add_or_update call. This matches the doc comments that every task produced by the batch is tagged with the same metadata.

Capacity reservation is still based on the document count (existing behavior); no new performance or correctness concerns introduced here.

Also applies to: 1770-1785


2232-2242: Helper and CSV/NDJSON tests give solid coverage of metadata propagation

The expect_task_metadata helper centralizes the assertion on Task::Succeeded { content }.custom_metadata, making the new tests concise and less error-prone.

The test_add_documents_ndjson, test_update_documents_ndjson, test_add_documents_csv, and test_update_documents_csv tests validate that:

  • TaskInfo.custom_metadata reflects the provided metadata, and
  • The final Task retrieved via wait_for_completion preserves the same metadata.

This is exactly what we need to guard the new behavior on the streaming code paths.

Also applies to: 2413-2514


2579-2692: test_document_tasks_custom_metadata thoroughly exercises all main document task variants

This test is a nice end-to-end check that custom_metadata flows correctly through:

  • add_documents
  • delete_document
  • add_or_update
  • delete_documents
  • delete_documents_with (via DocumentDeletionQuery)
  • delete_all_documents

Asserting both TaskInfo.custom_metadata and the Task’s content.custom_metadata via expect_task_metadata gives good confidence that the SDK is correctly wiring the metadata end-to-end for the primary document operations.

@curquiza curquiza changed the title feat: add custom metadata support for document tasks Add custom metadata support for document tasks Dec 29, 2025
curquiza
curquiza previously approved these changes Dec 29, 2025
@curquiza curquiza enabled auto-merge December 29, 2025 17:36
@curquiza curquiza disabled auto-merge December 29, 2025 18:00
@curquiza
Copy link
Copy Markdown
Member

@kumarUjjawal sorry can you rebase your PR? Or updated it with main? Looks like I cannot re-run the tests... so I cannot merge it

@kumarUjjawal
Copy link
Copy Markdown
Contributor Author

@kumarUjjawal sorry can you rebase your PR? Or updated it with main? Looks like I cannot re-run the tests... so I cannot merge it

Should pass now

Copy link
Copy Markdown
Contributor

@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 (2)
src/documents.rs (1)

415-427: Consider adding documentation for the new method

The new execute_with_custom_metadata method is a useful addition that allows passing custom metadata for deletion tasks. However, it lacks a documentation comment explaining its purpose and usage.

📝 Suggested documentation
     pub async fn execute<T: DeserializeOwned + 'static>(&self) -> Result<TaskInfo, Error> {
         self.execute_with_custom_metadata::<T>(None).await
     }

-    /// Same as [`DocumentDeletionQuery::execute`] but allows passing `custom_metadata` for the created task.
+    /// Execute the document deletion query with optional custom metadata.
+    ///
+    /// This method is similar to [`execute`](DocumentDeletionQuery::execute), but allows
+    /// attaching custom metadata to the deletion task. The metadata will be included in the
+    /// resulting [`TaskInfo`] and can be used to track or categorize tasks.
+    ///
+    /// # Arguments
+    ///
+    /// * `custom_metadata` - Optional metadata string to attach to the task
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// # use meilisearch_sdk::{client::*, indexes::*, documents::*};
+    /// # let client = Client::new("http://localhost:7700", Some("masterKey")).unwrap();
+    /// # let index = client.index("movies");
+    /// let mut query = DocumentDeletionQuery::new(&index);
+    /// query.with_filter("year < 2000");
+    /// let task = query.execute_with_custom_metadata::<()>(Some("cleanup-old-movies")).await.unwrap();
+    /// ```
     pub async fn execute_with_custom_metadata<T: DeserializeOwned + 'static>(
         &self,
         custom_metadata: Option<&'a str>,
     ) -> Result<TaskInfo, Error> {
src/indexes.rs (1)

2579-2692: Comprehensive test coverage for metadata propagation.

The test test_document_tasks_custom_metadata thoroughly validates metadata through the full task lifecycle for key operations: add, update, delete single, delete batch, delete with filter, and delete all.

Consider adding explicit tests for add_documents_in_batches and update_documents_in_batches with metadata to verify that each batch task receives the metadata string. Currently, these are only implicitly covered.

🔎 Example test addition
// Test batch operations with metadata
let batch_tasks = index
    .add_documents_in_batches(
        &[
            SimpleDocument { id: 10, name: "ten" },
            SimpleDocument { id: 11, name: "eleven" },
        ],
        Some(1), // batch_size = 1 to create multiple tasks
        Some("id"),
        Some("batch-meta"),
    )
    .await?;

for task_info in &batch_tasks {
    assert_eq!(task_info.custom_metadata.as_deref(), Some("batch-meta"));
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fad2af and aefd375.

📒 Files selected for processing (10)
  • examples/cli-app-with-awc/src/main.rs
  • examples/cli-app/src/main.rs
  • examples/web_app_graphql/src/graphql_schema/users/query/search.rs
  • src/client.rs
  • src/documents.rs
  • src/indexes.rs
  • src/lib.rs
  • src/search.rs
  • src/task_info.rs
  • src/tasks.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/tasks.rs
  • examples/cli-app-with-awc/src/main.rs
  • examples/cli-app/src/main.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-12T13:28:23.700Z
Learnt from: LukasKalbertodt
Repo: meilisearch/meilisearch-rust PR: 625
File: src/search.rs:368-370
Timestamp: 2025-06-12T13:28:23.700Z
Learning: In the Meilisearch Rust client, `SearchQuery` serializes its per-query federation settings under the key `federationOptions`; only the top-level multi-search parameter is named `federation`.

Applied to files:

  • src/client.rs
🧬 Code graph analysis (3)
src/search.rs (1)
src/client.rs (4)
  • None (1541-1541)
  • None (1584-1584)
  • None (1587-1587)
  • None (1682-1682)
src/indexes.rs (2)
src/documents.rs (7)
  • new (89-94)
  • new (218-228)
  • new (400-405)
  • index (62-64)
  • index (161-161)
  • index (383-383)
  • index (544-544)
src/request.rs (1)
  • query (39-47)
src/client.rs (1)
src/batches.rs (3)
  • None (141-141)
  • None (169-169)
  • None (193-193)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: integration-tests
🔇 Additional comments (23)
examples/web_app_graphql/src/graphql_schema/users/query/search.rs (1)

27-27: LGTM: Consistent API update

Both call sites correctly updated to pass None for the new custom_metadata parameter.

Also applies to: 36-36

src/lib.rs (1)

37-37: Doctest examples updated correctly

The doctest examples have been updated to include the new custom_metadata parameter (passing None). The examples remain valid and will continue to pass.

Also applies to: 189-189

src/task_info.rs (3)

17-17: New field added to TaskInfo

The custom_metadata field is properly added as an optional string. The field will be populated from JSON responses containing customMetadata (camelCase).


114-141: Good test coverage for custom_metadata deserialization

The test properly verifies that:

  • JSON with "customMetadata": "batch-1" deserializes correctly
  • The field is accessible as custom_metadata in Rust
  • The assertion correctly validates the value

65-65: Doctest and test updated correctly

Call sites updated to pass None for the new custom_metadata parameter.

Also applies to: 160-160

src/search.rs (2)

976-976: Doctest updated correctly

The facet search example has been updated to pass None for the new custom_metadata parameter in the add_or_replace call.


1237-1237: Test setup functions updated consistently

Both setup_test_index and setup_test_video_index helper functions have been updated to pass None for the new custom_metadata parameter in add_documents calls.

Also applies to: 1288-1288

src/client.rs (3)

171-171: Multi-search example updated correctly

The doctest example for multi-search has been updated to pass None for the new custom_metadata parameter.


912-912: Doctest examples updated consistently

Both the wait_for_task and get_task examples have been updated to pass None for the new custom_metadata parameter.

Also applies to: 964-964


1635-1635: Test updated correctly

The test_swapping_two_indexes test has been updated to pass None for the new custom_metadata parameter in both add_documents calls.

Also applies to: 1646-1646

src/documents.rs (2)

144-144: Doctest updated correctly

The example for DocumentQuery::execute has been updated to pass None for the new custom_metadata parameter.


488-488: Test helper and calls updated correctly

The setup_test_index helper function and delete_documents_with calls have been updated to pass None for the new custom_metadata parameter.

Also applies to: 540-540, 569-569

src/indexes.rs (11)

80-103: LGTM!

The DocumentTaskQuery struct is well-designed with appropriate serde attributes for optional field serialization. The two constructors (new for operations requiring primary_key, with_metadata for delete operations) provide a clean API.


647-666: LGTM!

The method signature and implementation correctly propagate the custom_metadata parameter through DocumentTaskQuery to the HTTP request.


706-729: LGTM!

Correctly propagates custom_metadata through DocumentTaskQuery for stream requests.


1118-1131: LGTM!

All delete methods correctly use DocumentTaskQuery::with_metadata() to propagate custom metadata without a primary key. The implementation is consistent across delete_all_documents, delete_document, delete_documents, and delete_documents_with.

Also applies to: 1168-1185, 1225-1242, 1285-1302


1674-1689: LGTM!

The batch methods correctly propagate custom_metadata to each sub-task. The documentation at lines 1673 and 1770 appropriately notes that the same metadata tags every task in a batch.

Also applies to: 1771-1786


2232-2242: LGTM!

The expect_task_metadata helper function is well-designed for validating metadata in tests. It correctly handles the succeeded task case and provides a clear panic message for debugging.


600-602: LGTM!

The documentation clearly explains the purpose of custom_metadata and its visibility through /tasks or webhooks.


780-793: LGTM!

The NDJSON and CSV helper methods correctly forward custom_metadata to their underlying unchecked payload implementations.

Also applies to: 833-846, 885-893, 932-940


994-1013: LGTM!

The add_or_update and add_or_update_unchecked_payload methods correctly mirror their add_or_replace counterparts with proper metadata propagation.

Also applies to: 1055-1078


2320-2361: LGTM!

The test_update_document_json test correctly passes None for the new custom_metadata parameter, maintaining backward compatibility testing.


647-652: Breaking API changes present - version requirement unverified.

These method signature changes (adding custom_metadata: Option<&str>) do introduce breaking changes for existing SDK consumers, as confirmed by modifications across add_or_replace, add_or_update, delete_all_documents, delete_document, delete_documents, and delete_documents_with.

However, verification could not confirm:

  • The specific Meilisearch v1.26 requirement claim; the README only states general v1.x compatibility
  • Whether issue #733 directly addresses this change
  • Existence of migration guidance or version-specific documentation

Recommend verifying the Meilisearch server version requirement and updating documentation accordingly if this requires v1.26+ specifically.

Copy link
Copy Markdown
Contributor

@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 (3)
src/tasks.rs (1)

165-186: Task structs extended with custom_metadata cleanly

Adding custom_metadata: Option<String> to SucceededTask (and similarly in EnqueuedTask / ProcessingTask) is backward compatible with existing deserialization and pattern matches, and fits the camelCase wire format. Consider adding a short doc comment explaining it carries the user‑supplied customMetadata from the task payload, but this is optional.

src/documents.rs (1)

415-427: New execute_with_custom_metadata nicely extends deletion without breaking callers

DocumentDeletionQuery::execute now simply forwards to execute_with_custom_metadata::<T>(None), and the new method passes custom_metadata through to Index::delete_documents_with. The reuse of 'a for the metadata reference is compatible with how DocumentDeletionQuery is created.

Only minor note (for a future breaking release): the generic T bound on both methods is now unused and could be dropped then to simplify the API.

src/indexes.rs (1)

2322-2692: test_document_tasks_custom_metadata thoroughly exercises document-task metadata

The test_document_tasks_custom_metadata case covers all major document operations:

  • add_documents, add_or_update (single and multi-doc),
  • delete_document,
  • delete_documents (batch),
  • delete_documents_with (filter),
  • delete_all_documents,

and checks both TaskInfo.custom_metadata at submission time and Task::Succeeded’s content.custom_metadata after wait_for_completion. Combined with expect_task_metadata, this is a solid regression suite for the new feature.

Only optional thought: if you want parity, you could add a tiny assertion for metadata on tasks produced by the batch helpers (add_documents_in_batches / update_documents_in_batches) in a follow-up, but the core feature is already well covered.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aefd375 and 7288f92.

📒 Files selected for processing (11)
  • README.md
  • examples/cli-app-with-awc/src/main.rs
  • examples/cli-app/src/main.rs
  • examples/web_app_graphql/src/graphql_schema/users/query/search.rs
  • src/client.rs
  • src/documents.rs
  • src/indexes.rs
  • src/lib.rs
  • src/search.rs
  • src/task_info.rs
  • src/tasks.rs
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/task_info.rs
  • src/search.rs
  • examples/web_app_graphql/src/graphql_schema/users/query/search.rs
  • src/lib.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-12T13:28:23.700Z
Learnt from: LukasKalbertodt
Repo: meilisearch/meilisearch-rust PR: 625
File: src/search.rs:368-370
Timestamp: 2025-06-12T13:28:23.700Z
Learning: In the Meilisearch Rust client, `SearchQuery` serializes its per-query federation settings under the key `federationOptions`; only the top-level multi-search parameter is named `federation`.

Applied to files:

  • src/client.rs
🧬 Code graph analysis (5)
examples/cli-app/src/main.rs (1)
src/client.rs (4)
  • None (1541-1541)
  • None (1584-1584)
  • None (1587-1587)
  • None (1682-1682)
src/client.rs (1)
src/batches.rs (3)
  • None (141-141)
  • None (169-169)
  • None (193-193)
src/tasks.rs (1)
src/client.rs (4)
  • None (1541-1541)
  • None (1584-1584)
  • None (1587-1587)
  • None (1682-1682)
examples/cli-app-with-awc/src/main.rs (1)
src/client.rs (4)
  • None (1541-1541)
  • None (1584-1584)
  • None (1587-1587)
  • None (1682-1682)
src/indexes.rs (1)
src/request.rs (1)
  • query (39-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: integration-tests
🔇 Additional comments (13)
examples/cli-app-with-awc/src/main.rs (1)

186-195: Callsite correctly updated for new custom_metadata argument

Passing None as the new third parameter matches the updated add_or_update(&self, docs, primary_key, custom_metadata) signature; no behavior change in the example.

examples/cli-app/src/main.rs (1)

110-118: Example aligned with extended add_or_update API

The extra None argument is correctly wired as custom_metadata for the updated add_or_update signature; example remains behaviorally identical.

src/tasks.rs (3)

194-230: Enqueued/Processing task metadata field matches the rest of the model

The new custom_metadata: Option<String> on EnqueuedTask and ProcessingTask matches the field added on SucceededTask and what TaskInfo exposes, so tasks from /tasks will consistently surface per‑task metadata across all statuses.


301-308: Doc example updated for new add_documents signature

The doctest now uses add_documents(&[..], None, None), matching the new (primary_key, custom_metadata) tail parameters; good to keep examples in sync with the public API.


946-964: Test test_wait_for_task_with_args correctly adapted to new API

The additional None argument on add_documents aligns with the new custom_metadata parameter and keeps the test logic unchanged.

src/client.rs (2)

167-191: Doctest callsites now match extended Index document APIs

The examples for multi-search and client‑level wait_for_task now invoke add_or_replace / add_documents with an extra trailing None for custom_metadata, which matches the new Index method signatures and keeps the sample behavior intact.


963-965: Tests correctly adjusted for delete_all_documents and add_documents signatures

  • index.delete_all_documents(None) now passes custom_metadata explicitly.
  • add_documents invocations in test_swapping_two_indexes use the new (primary_key, custom_metadata) parameter list.

These keep the tests compiling and semantically equivalent with the previous behavior (no metadata attached).

Also applies to: 1629-1647

src/documents.rs (2)

139-146: Doctest updated to new add_or_replace signature

The example now calls add_or_replace(&[..], None, None), lining up with the extended (primary_key, custom_metadata) parameters without changing behavior.


467-571: Test helpers and delete-with-filter tests correctly use new metadata parameter

  • setup_test_index now calls add_documents(&[..], None, None).
  • Both test_delete_documents_with and test_delete_documents_with_filter_not_filterable pass None into delete_documents_with(&query, None).

This keeps the tests exercising the same behavior while aligning with the new signature that allows optional custom_metadata.

src/indexes.rs (4)

80-104: DocumentTaskQuery centralizes primaryKey/customMetadata query handling

Introducing DocumentTaskQuery<'a> and using it as the query for all document‑mutating endpoints (add_or_replace, add_documents, add_or_update, and _unchecked_payload/NDJSON/CSV variants) is a clean way to keep primary_key and custom_metadata wiring consistent. The camelCase rename plus skip_serializing_if = "Option::is_none" matches the expected wire format and avoids stray query parameters when both are None.

Type usage with Method::Post / stream_request is correct, and the new custom_metadata: Option<&str> parameters on the public APIs are threaded through everywhere.

Also applies to: 647-741, 706-729


1080-1291: Delete endpoints now properly support per-task custom_metadata

delete_all_documents, delete_document, delete_documents, and delete_documents_with all now:

  • Accept custom_metadata: Option<&str> in their public signatures.
  • Build a DocumentTaskQuery::with_metadata(custom_metadata) for the HTTP query.
  • Keep existing behavior for the request body and URL path unchanged.

This matches the server’s API expectations and ensures every deletion task can carry user‑defined metadata, consistent with the addition/update endpoints.


1673-1786: Batch helpers propagate custom_metadata consistently

Both add_documents_in_batches and update_documents_in_batches now accept custom_metadata: Option<&str> and pass it through to add_documents / add_or_update for every chunk. This means each task created for a batch will share the same metadata string, which is exactly what the new doc comments describe.


2322-2514: CSV/NDJSON tests validate metadata propagation end-to-end

The new tests:

  • Call add_documents_ndjson / update_documents_ndjson and add_documents_csv / update_documents_csv with non‑None metadata strings.
  • Assert that TaskInfo.custom_metadata is set correctly.
  • Await completion and use expect_task_metadata to assert the resulting Task::Succeeded carries the same custom_metadata.

This gives strong coverage that the new query plumbing (DocumentTaskQuery) and the task deserialization (Task/SucceededTask) are correctly wired together for streaming document formats as well.

@kumarUjjawal
Copy link
Copy Markdown
Contributor Author

meilisearch-sdk = "0.24.3"

Should use the local path?

@curquiza
Copy link
Copy Markdown
Member

meilisearch-sdk = "0.24.3"

Should use the local path?

Yes, thank you!

@curquiza
Copy link
Copy Markdown
Member

@kumarUjjawal
Copy link
Copy Markdown
Contributor Author

Also, tests are failing: https://github.com/meilisearch/meilisearch-rust/actions/runs/20579542524/job/59103940634?pr=736

Yeah the tests are failing becuase we are adding a new field which doesn't exist of the meilisearch-sdk = "0.24.3" , if we update the integration test to use the local path, the test should pass.

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.26] Add tasks custom metadata

2 participants