From 9139d4f3b38223e471182753edcf482df200aedc Mon Sep 17 00:00:00 2001 From: GabrielBBaldez <130607246+GabrielBBaldez@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:42:51 -0300 Subject: [PATCH] feat: add personalized search (experimental) --- .../meilisearch/sdk/IndexSearchRequest.java | 7 ++- .../com/meilisearch/sdk/SearchRequest.java | 6 +++ .../meilisearch/sdk/model/Personalize.java | 43 +++++++++++++++++++ .../sdk/IndexSearchRequestTest.java | 25 +++++++++++ .../meilisearch/sdk/SearchRequestTest.java | 24 +++++++++++ 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/meilisearch/sdk/model/Personalize.java diff --git a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java index e0e29acc6..df2968758 100644 --- a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java @@ -2,6 +2,7 @@ import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; +import com.meilisearch.sdk.model.Personalize; import lombok.*; import lombok.experimental.Accessors; import org.json.JSONObject; @@ -41,6 +42,7 @@ public class IndexSearchRequest { protected String distinct; protected Hybrid hybrid; protected Boolean retrieveVectors; + protected Personalize personalize; /** * Constructor for MultiSearchRequest for building search queries with the default values: @@ -111,7 +113,10 @@ public String toString() { .putOpt("locales", this.locales) .putOpt("distinct", this.distinct) .putOpt("retrieveVectors", this.retrieveVectors) - .putOpt("hybrid", this.hybrid != null ? this.hybrid.toJSONObject() : null); + .putOpt("hybrid", this.hybrid != null ? this.hybrid.toJSONObject() : null) + .putOpt( + "personalize", + this.personalize != null ? this.personalize.toJSONObject() : null); return jsonObject.toString(); } diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 43e043cc1..6feb0e6ec 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -2,6 +2,7 @@ import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; +import com.meilisearch.sdk.model.Personalize; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -46,6 +47,7 @@ public class SearchRequest { protected Hybrid hybrid; protected Double[] vector; protected Boolean retrieveVectors; + protected Personalize personalize; /** * Constructor for SearchRequest for building search queries with the default values: offset: 0, * limit: 20, attributesToRetrieve: ["*"], attributesToCrop: null, cropLength: 200, @@ -116,6 +118,10 @@ public String toString() { jsonObject.put("hybrid", this.hybrid.toJSONObject()); } + if (this.personalize != null) { + jsonObject.put("personalize", this.personalize.toJSONObject()); + } + return jsonObject.toString(); } } diff --git a/src/main/java/com/meilisearch/sdk/model/Personalize.java b/src/main/java/com/meilisearch/sdk/model/Personalize.java new file mode 100644 index 000000000..799d133a3 --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/Personalize.java @@ -0,0 +1,43 @@ +package com.meilisearch.sdk.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.json.JSONObject; + +/** Personalization configuration for personalized search (experimental) */ +@Builder +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +@Setter +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Personalize { + /** Natural-language description of the user's context used to personalize the search */ + private String userContext; + + /** + * Method that returns the JSON representation of the Personalize object + * + * @return JSONObject representation of the Personalize object + */ + public JSONObject toJSONObject() { + return new JSONObject().putOpt("userContext", this.userContext); + } + + /** + * Method that returns the JSON String of the Personalize object + * + * @return JSON String of the Personalize object + */ + @Override + public String toString() { + return toJSONObject().toString(); + } +} diff --git a/src/test/java/com/meilisearch/sdk/IndexSearchRequestTest.java b/src/test/java/com/meilisearch/sdk/IndexSearchRequestTest.java index b5b1c171e..9aad21475 100644 --- a/src/test/java/com/meilisearch/sdk/IndexSearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/IndexSearchRequestTest.java @@ -5,6 +5,8 @@ import static org.hamcrest.Matchers.is; import com.meilisearch.sdk.model.Hybrid; +import com.meilisearch.sdk.model.Personalize; +import org.json.JSONObject; import org.junit.jupiter.api.Test; class IndexSearchRequestTest { @@ -54,4 +56,27 @@ void toStringWithHybridOnlyEmbedder() { String expected = "{\"q\":\"This is a Test\",\"hybrid\":{\"embedder\":\"default\"}}"; assertThat(classToTest.toString(), is(equalTo(expected))); } + + @Test + void toStringWithPersonalizeUsingBuilder() { + IndexSearchRequest classToTest = + IndexSearchRequest.builder() + .q("This is a Test") + .personalize( + Personalize.builder() + .userContext("The user prefers sci-fi movies") + .build()) + .build(); + + JSONObject json = new JSONObject(classToTest.toString()); + assertThat(json.getString("q"), is(equalTo("This is a Test"))); + assertThat( + json.getJSONObject("personalize").getString("userContext"), + is(equalTo("The user prefers sci-fi movies"))); + + // Verify getters + assertThat( + classToTest.getPersonalize().getUserContext(), + is(equalTo("The user prefers sci-fi movies"))); + } } diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index e32ecd9f6..c92a8f5e2 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -7,6 +7,7 @@ import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; +import com.meilisearch.sdk.model.Personalize; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -419,4 +420,27 @@ void toStringWithRetrieveVectors() { JSONObject json = new JSONObject(result); assertThat(json.getBoolean("retrieveVectors"), is(true)); } + + @Test + void toStringWithPersonalizeUsingBuilder() { + SearchRequest classToTest = + SearchRequest.builder() + .q("This is a Test") + .personalize( + Personalize.builder() + .userContext("The user prefers sci-fi movies") + .build()) + .build(); + + JSONObject json = new JSONObject(classToTest.toString()); + assertThat(json.getString("q"), is(equalTo("This is a Test"))); + assertThat( + json.getJSONObject("personalize").getString("userContext"), + is(equalTo("The user prefers sci-fi movies"))); + + // Verify getters + assertThat( + classToTest.getPersonalize().getUserContext(), + is(equalTo("The user prefers sci-fi movies"))); + } }