add show performance details field to related endpoints#938
add show performance details field to related endpoints#938valkrypton wants to merge 1 commit intomeilisearch:mainfrom
Conversation
📝 WalkthroughWalkthroughAdds support for requesting and returning raw performance traces: request types gain a Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant SDK as "SDK (Request classes)"
participant Meili as "Meilisearch Server"
participant Models as "Response models"
Client->>SDK: build request with showPerformanceDetails=true
SDK->>Meili: send search/multi-search/similar-docs request (flag included)
Meili-->>SDK: response including performanceDetails object
SDK->>Models: deserialize raw performanceDetails into HashMap<String,Object>
SDK-->>Client: return result containing performanceDetails
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/test/java/com/meilisearch/integration/SearchTest.java (1)
837-847:⚠️ Potential issue | 🔴 CriticalFederation test may fail —
showPerformanceDetailsis not serialized inMultiSearchFederation.toString().As flagged in
MultiSearchFederation.java, thetoString()method doesn't includeshowPerformanceDetails. This means line 837 sets the flag but it's never sent to the server, sogetPerformanceDetails()on line 847 will likely benull, causing an NPE on.size().Consider adding a null-safety assertion (
assertThat(results.getPerformanceDetails(), is(notNullValue()))) before checking size, and ensure the serialization bug is fixed first.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/com/meilisearch/integration/SearchTest.java` around lines 837 - 847, The test sets federation.setShowPerformanceDetails(true) but MultiSearchFederation.toString() currently omits the showPerformanceDetails field so the flag never reaches the server and results.getPerformanceDetails() can be null; update MultiSearchFederation.toString() to serialize showPerformanceDetails (matching the other federation fields) and then make the test null-safe by asserting results.getPerformanceDetails() is not null (e.g., assertThat(results.getPerformanceDetails(), is(notNullValue()))) before asserting its size; reference the MultiSearchFederation.toString(), MultiSearchFederation.setShowPerformanceDetails(), and MultiSearchResult.getPerformanceDetails() symbols when applying the fixes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/com/meilisearch/sdk/model/MultiSearchResult.java`:
- Line 26: The performanceDetails field in MultiSearchResult is typed as
HashMap<String, String> but can contain non-string values; change its
declaration to HashMap<String, Object> and update any associated
accessor/mutator (e.g., getPerformanceDetails, setPerformanceDetails,
constructors, and any JSON (de)serialization annotations or usages) to use
HashMap<String, Object> so heterogeneous values are preserved.
In `@src/main/java/com/meilisearch/sdk/model/SearchResult.java`:
- Line 27: Update the performanceDetails field from HashMap<String, String> to
HashMap<String, Object> to allow non-string values during deserialization:
locate the performanceDetails declaration in the SearchResult class (field name
performanceDetails), and make the same change in MultiSearchResult
(performanceDetails) and SimilarDocumentsResults (performanceDetails); ensure
any getters/setters or usages (e.g., getPerformanceDetails(),
setPerformanceDetails(...)) and relevant imports are updated to use
HashMap<String, Object> (or Map<String, Object>) so deserialization won't fail
if the API returns numbers or nested objects.
In `@src/main/java/com/meilisearch/sdk/model/SimilarDocumentsResults.java`:
- Line 23: In SimilarDocumentsResults change the field declaration
performanceDetails from HashMap<String, String> to HashMap<String, Object> and
update any associated accessor/mutator methods, constructors, builders, and
(de)serialization logic that reference performanceDetails to use HashMap<String,
Object> instead; mirror the same adjustments done in SearchResult.java to ensure
type consistency across the models.
In `@src/test/java/com/meilisearch/integration/SearchTest.java`:
- Around line 1319-1325: In SearchTest, the assertion on searchResult hits uses
hasSize(11) but should expect the default page size of 20; update the assertion
for searchResult.getHits() from hasSize(11) to hasSize(20) so that
SearchRequest.builder().q("a").showPerformanceDetails(true).build() correctly
validates 20 returned hits; keep the other assertions (getEstimatedTotalHits and
getPerformanceDetails) unchanged.
---
Outside diff comments:
In `@src/test/java/com/meilisearch/integration/SearchTest.java`:
- Around line 837-847: The test sets federation.setShowPerformanceDetails(true)
but MultiSearchFederation.toString() currently omits the showPerformanceDetails
field so the flag never reaches the server and results.getPerformanceDetails()
can be null; update MultiSearchFederation.toString() to serialize
showPerformanceDetails (matching the other federation fields) and then make the
test null-safe by asserting results.getPerformanceDetails() is not null (e.g.,
assertThat(results.getPerformanceDetails(), is(notNullValue()))) before
asserting its size; reference the MultiSearchFederation.toString(),
MultiSearchFederation.setShowPerformanceDetails(), and
MultiSearchResult.getPerformanceDetails() symbols when applying the fixes.
| int limit; | ||
| int estimatedTotalHits; | ||
| HashMap<String, FacetsByIndexInfo> facetsByIndex; | ||
| HashMap<String, String> performanceDetails; |
There was a problem hiding this comment.
Same issue: use HashMap<String, Object> for performanceDetails.
See the comment on SearchResult.java — this field likely contains non-string values.
Proposed fix
- HashMap<String, String> performanceDetails;
+ HashMap<String, Object> performanceDetails;📝 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.
| HashMap<String, String> performanceDetails; | |
| HashMap<String, Object> performanceDetails; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/meilisearch/sdk/model/MultiSearchResult.java` at line 26,
The performanceDetails field in MultiSearchResult is typed as HashMap<String,
String> but can contain non-string values; change its declaration to
HashMap<String, Object> and update any associated accessor/mutator (e.g.,
getPerformanceDetails, setPerformanceDetails, constructors, and any JSON
(de)serialization annotations or usages) to use HashMap<String, Object> so
heterogeneous values are preserved.
| int limit; | ||
| int estimatedTotalHits; | ||
| HashMap<String, Object> _vectors; | ||
| HashMap<String, String> performanceDetails; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Meilisearch performanceDetails response format API documentation
💡 Result:
Meilisearch exposes performanceDetails in search-like responses when you enable the request flag showPerformanceDetails: true (added in Meilisearch v1.35.0). The field format is:
performanceDetails: object / map of"<span>" -> "<human_duration>"(string durations), e.g.:The same map appears per-result in multi-search as{ "performanceDetails": { "<span>": "<human_duration>" } }results[].performanceDetails. [1]
Type-wise, client SDKs model it as a map (e.g., map[string]any in the Go SDK) keyed by span name. [2]
Sources: [1] [2]
🏁 Script executed:
# Find and examine the SearchResult.java file and related model files
fd SearchResult.java
fd MultiSearchResult.java
fd SimilarDocumentsResults.javaRepository: meilisearch/meilisearch-java
Length of output: 387
🏁 Script executed:
# Examine SearchResult.java around line 27
cat -n src/main/java/com/meilisearch/sdk/model/SearchResult.java | head -50Repository: meilisearch/meilisearch-java
Length of output: 1052
🏁 Script executed:
# Examine MultiSearchResult.java for performanceDetails
cat -n src/main/java/com/meilisearch/sdk/model/MultiSearchResult.java | head -70Repository: meilisearch/meilisearch-java
Length of output: 1013
🏁 Script executed:
# Examine SimilarDocumentsResults.java for performanceDetails
cat -n src/main/java/com/meilisearch/sdk/model/SimilarDocumentsResults.java | head -70Repository: meilisearch/meilisearch-java
Length of output: 813
🏁 Script executed:
# Check for any Jackson annotations or custom deserializers
rg -A 5 "performanceDetails" src/main/java/com/meilisearch/sdk/model/Repository: meilisearch/meilisearch-java
Length of output: 914
🏁 Script executed:
# Check the deserialization configuration, likely in MeilisearchClient or similar
fd -e java | xargs rg -l "ObjectMapper|JsonDeserialize" | head -10Repository: meilisearch/meilisearch-java
Length of output: 436
🏁 Script executed:
# Check the Jackson configuration
cat -n src/main/java/com/meilisearch/sdk/json/JacksonJsonHandler.javaRepository: meilisearch/meilisearch-java
Length of output: 3989
🏁 Script executed:
# Check if there are any tests that show the performanceDetails usage
rg -B 5 -A 5 "performanceDetails" src/test/Repository: meilisearch/meilisearch-java
Length of output: 54
🏁 Script executed:
# Check the issue `#933` if referenced in code or docs
rg -i "issue.*933\|#933" --include="*.md" --include="*.java"Repository: meilisearch/meilisearch-java
Length of output: 513
🏁 Script executed:
# Search for any tests or usage of performanceDetails
fd -e java | xargs rg "performanceDetails"Repository: meilisearch/meilisearch-java
Length of output: 405
🏁 Script executed:
# Check if there's any documentation about performanceDetails or future compatibility concerns
rg "showPerformanceDetails\|performanceDetails" --type mdRepository: meilisearch/meilisearch-java
Length of output: 54
🏁 Script executed:
# Check what other SDKs do - look at git history or comments mentioning other SDKs
rg -i "go\|node\|rust\|python" src/main/java/com/meilisearch/sdk/model/ -B 2 -A 2Repository: meilisearch/meilisearch-java
Length of output: 54
🏁 Script executed:
# Check if there are any other fields that model "raw data" or extensible objects
rg "HashMap<String, Object>" src/main/java/com/meilisearch/sdk/model/ -B 1 -A 1Repository: meilisearch/meilisearch-java
Length of output: 2459
🏁 Script executed:
# Look for any issue tracker references or comments about forward compatibility
rg "future\|forward\|evolve\|extend\|raw" src/main/java/com/meilisearch/sdk/model/SearchResult.java -B 2 -A 2Repository: meilisearch/meilisearch-java
Length of output: 54
Change performanceDetails from HashMap<String, String> to HashMap<String, Object> for forward compatibility.
While Meilisearch 1.35+ currently returns performanceDetails as string-to-string mappings (e.g., {"<span>": "<human_duration>"), the field is documented as extensible and may evolve to include numeric values or nested objects in future versions. Using HashMap<String, String> would cause deserialization failures if the API changes. The Go SDK uses map[string]any for this reason. This pattern also aligns with other flexible fields in these models (e.g., _vectors, facetDistribution).
Fix applies to:
SearchResult.java(line 27)MultiSearchResult.java(line 26)SimilarDocumentsResults.java(line 23)
Proposed fix
- HashMap<String, String> performanceDetails;
+ HashMap<String, Object> performanceDetails;📝 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.
| HashMap<String, String> performanceDetails; | |
| HashMap<String, Object> performanceDetails; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/meilisearch/sdk/model/SearchResult.java` at line 27, Update
the performanceDetails field from HashMap<String, String> to HashMap<String,
Object> to allow non-string values during deserialization: locate the
performanceDetails declaration in the SearchResult class (field name
performanceDetails), and make the same change in MultiSearchResult
(performanceDetails) and SimilarDocumentsResults (performanceDetails); ensure
any getters/setters or usages (e.g., getPerformanceDetails(),
setPerformanceDetails(...)) and relevant imports are updated to use
HashMap<String, Object> (or Map<String, Object>) so deserialization won't fail
if the API returns numbers or nested objects.
| int offset; | ||
| int limit; | ||
| int estimatedTotalHits; | ||
| HashMap<String, String> performanceDetails; |
There was a problem hiding this comment.
Same issue: use HashMap<String, Object> for performanceDetails.
See the comment on SearchResult.java.
Proposed fix
- HashMap<String, String> performanceDetails;
+ HashMap<String, Object> performanceDetails;📝 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.
| HashMap<String, String> performanceDetails; | |
| HashMap<String, Object> performanceDetails; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/meilisearch/sdk/model/SimilarDocumentsResults.java` at line
23, In SimilarDocumentsResults change the field declaration performanceDetails
from HashMap<String, String> to HashMap<String, Object> and update any
associated accessor/mutator methods, constructors, builders, and
(de)serialization logic that reference performanceDetails to use HashMap<String,
Object> instead; mirror the same adjustments done in SearchResult.java to ensure
type consistency across the models.
| SearchRequest searchRequest = | ||
| SearchRequest.builder().q("a").showPerformanceDetails(true).build(); | ||
| SearchResult searchResult = (SearchResult) index.search(searchRequest); | ||
|
|
||
| assertThat(searchResult.getHits(), hasSize(11)); | ||
| assertThat(searchResult.getEstimatedTotalHits(), is(equalTo(31))); | ||
| assertThat(searchResult.getPerformanceDetails().size(), greaterThan(0)); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and examine SearchRequest class to understand default limit
fd -t f -n "SearchRequest" --extension java | head -5Repository: meilisearch/meilisearch-java
Length of output: 302
🏁 Script executed:
# Look at the test file to understand the patterns
rg -n "testSearchOffset|testBasicSearch|offset.*20|hasSize" src/test/java/com/meilisearch/integration/SearchTest.java | head -30Repository: meilisearch/meilisearch-java
Length of output: 1362
🏁 Script executed:
# Find where SearchRequest is defined and check its defaults
fd -t f "SearchRequest.java" | grep -v testRepository: meilisearch/meilisearch-java
Length of output: 298
🏁 Script executed:
# Examine SearchRequest.java for default limit
cat src/main/java/com/meilisearch/sdk/SearchRequest.java | head -100Repository: meilisearch/meilisearch-java
Length of output: 3612
🏁 Script executed:
# View the test context around line 1323
sed -n '1300,1330p' src/test/java/com/meilisearch/integration/SearchTest.javaRepository: meilisearch/meilisearch-java
Length of output: 1265
🏁 Script executed:
# View the test context around line 305 to understand the pattern
sed -n '295,315p' src/test/java/com/meilisearch/integration/SearchTest.javaRepository: meilisearch/meilisearch-java
Length of output: 949
🏁 Script executed:
# Check if there's any special handling in search when showPerformanceDetails is set
rg -n "showPerformanceDetails" src/main/java/com/meilisearch/sdk/ -A 3 -B 3Repository: meilisearch/meilisearch-java
Length of output: 4591
🏁 Script executed:
# Look at the index.search method to see if it modifies the request
fd -t f "Index.java" | grep -v test | xargs cat | grep -A 20 "public.*search.*SearchRequest"Repository: meilisearch/meilisearch-java
Length of output: 1015
🏁 Script executed:
# Check if there's any test setup that might affect this specific test
sed -n '1300,1328p' src/test/java/com/meilisearch/integration/SearchTest.javaRepository: meilisearch/meilisearch-java
Length of output: 1265
Test assertion on line 1323 is incorrect — expected hit count should be 20, not 11.
With query "a", no explicit limit (default is 20 per SearchRequest javadoc), and no offset, the search should return 20 hits. The hasSize(11) appears to be a copy-paste error from testSearchOffset (line 79), where offset(20) with 31 total hits produces 31 − 20 = 11 remaining results. Compare with testSearchWithFrequencyMatchingStrategy (line 305), where query "and" correctly returns hasSize(20) with the same default limit applied.
Proposed fix
- assertThat(searchResult.getHits(), hasSize(11));
+ assertThat(searchResult.getHits(), hasSize(20));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/test/java/com/meilisearch/integration/SearchTest.java` around lines 1319
- 1325, In SearchTest, the assertion on searchResult hits uses hasSize(11) but
should expect the default page size of 20; update the assertion for
searchResult.getHits() from hasSize(11) to hasSize(20) so that
SearchRequest.builder().q("a").showPerformanceDetails(true).build() correctly
validates 20 returned hits; keep the other assertions (getEstimatedTotalHits and
getPerformanceDetails) unchanged.
4199f96 to
d323fc5
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/java/com/meilisearch/sdk/SearchRequest.java (1)
51-57: Minor: Javadoc constructor comment omitsshowPerformanceDetails.The constructor doc lists defaults for all serialized fields but
showPerformanceDetailsis missing.📝 Suggested Javadoc update
* Constructor for SearchRequest for building search queries with the default values: offset: 0, * limit: 20, attributesToRetrieve: ["*"], attributesToCrop: null, cropLength: 200, * attributesToHighlight: null, filter: null, showMatchesPosition: false, facets: null, sort: - * null, showRankingScore: false, showRankingScoreDetails: false, rankingScoreThreshold: null, - * retrieveVectors: false + * null, showRankingScore: false, showRankingScoreDetails: false, rankingScoreThreshold: null, + * retrieveVectors: false, showPerformanceDetails: false🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/meilisearch/sdk/SearchRequest.java` around lines 51 - 57, The Javadoc for the SearchRequest constructor omits the default for the showPerformanceDetails field; update the constructor comment in SearchRequest.java to include showPerformanceDetails (with its default value) alongside the other serialized field defaults so the documentation accurately reflects all fields initialized by the constructor—locate the constructor comment for SearchRequest and add the showPerformanceDetails default to the list.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/test/java/com/meilisearch/integration/SearchTest.java`:
- Line 847: Replace the direct size() assertions on the possibly-null map with a
Hamcrest map matcher that handles nulls: change usages of
assertThat(results.getPerformanceDetails().size(), greaterThan(0)) to
assertThat(results.getPerformanceDetails(), aMapWithSize(greaterThan(0))) in
SearchTest (references to getPerformanceDetails), and apply the same replacement
at the other two locations flagged (the occurrences around lines 1114 and 1325).
---
Duplicate comments:
In `@src/main/java/com/meilisearch/sdk/model/MultiSearchResult.java`:
- Line 26: No change needed: the field declaration performanceDetails of type
HashMap<String, Object> in class MultiSearchResult is correct and matches the
fix applied in SearchResult.java; leave the declaration "HashMap<String, Object>
performanceDetails" as-is and no further modifications are required.
In `@src/test/java/com/meilisearch/integration/SearchTest.java`:
- Line 1323: The assertion expecting 11 hits is a copy-paste error; update the
test that asserts on searchResult.getHits() to expect 20 hits instead of 11 (the
test invokes q("a") with default offset and default limit 20, so
searchResult.getHits() should have size 20). Locate the failing assertion in
SearchTest.java referencing searchResult.getHits() (the hasSize(11) call) and
change it to hasSize(20).
---
Nitpick comments:
In `@src/main/java/com/meilisearch/sdk/SearchRequest.java`:
- Around line 51-57: The Javadoc for the SearchRequest constructor omits the
default for the showPerformanceDetails field; update the constructor comment in
SearchRequest.java to include showPerformanceDetails (with its default value)
alongside the other serialized field defaults so the documentation accurately
reflects all fields initialized by the constructor—locate the constructor
comment for SearchRequest and add the showPerformanceDetails default to the
list.
d323fc5 to
9a70d02
Compare
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/test/java/com/meilisearch/integration/SearchTest.java`:
- Around line 1319-1325: The assertion for hit count is wrong: update the test
in SearchTest where SearchRequest searchRequest =
SearchRequest.builder().q("a").showPerformanceDetails(true).build() and
SearchResult searchResult = (SearchResult) index.search(searchRequest) to expect
20 hits (change the hasSize matcher from 11 to 20); verify getHits() is asserted
with hasSize(20) to reflect the default limit of 20 when no offset/limit is
provided.
Pull Request
Related issue
Fixes #933
What does this PR do?
showPerformanceDetailsto all related endpointsperformanceDetailsFieldPR checklist
Please check if your PR fulfills the following requirements:
Thank you so much for contributing to Meilisearch!
Summary by CodeRabbit
New Features
Tests