From d73b322a14f9aac6a465b1518297849bd650e1b9 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 13 Mar 2025 14:40:43 +0800 Subject: [PATCH 01/41] Initial devcontainer setup --- .devcontainer/devcontainer.json | 25 +++++++++++++++++++++++++ .devcontainer/docker-compose.yml | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..d29947ed --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +{ + "name": "Meilisearch Java", + // "image": "mcr.microsoft.com/devcontainers/java:8", + "dockerComposeFile": "./docker-compose.yml", + "service": "package", + "workspaceFolder": "/workspace", + "shutdownAction": "stopCompose" + // "customizations": { + // "vscode": { + // "extensions": [ + // "vscjava.vscode-java-pack" + // ] + // } + // } + // "features": { + // "ghcr.io/devcontainers/features/java:1": { + // "version": "none", + // "installGradle": "true", + // "installMaven": "true" + // } + // } + // "forwardPorts": [ + // 8080 + // ] +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 00000000..f4505e9e --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,24 @@ +version: "3.8" + +services: + package: + image: azul/zulu-openjdk:8-latest + tty: true + stdin_open: true + working_dir: /workspace + environment: + - MEILISEARCH_HOST=http://meilisearch:7700 + depends_on: + - meilisearch + links: + - meilisearch + volumes: + - ../:/workspace + + meilisearch: + image: getmeili/meilisearch:latest + ports: + - "7700" + environment: + - MEILI_MASTER_KEY=masterKey + - MEILI_NO_ANALYTICS=true From 5ddb097875a78bc36b6053cd9c03d405844c05e7 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 13 Mar 2025 15:11:24 +0800 Subject: [PATCH 02/41] Use gradle inside devcontainer --- .devcontainer/devcontainer.json | 30 +++++++++++++++--------------- .devcontainer/docker-compose.yml | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d29947ed..6bf11e58 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,21 +4,21 @@ "dockerComposeFile": "./docker-compose.yml", "service": "package", "workspaceFolder": "/workspace", - "shutdownAction": "stopCompose" - // "customizations": { - // "vscode": { - // "extensions": [ - // "vscjava.vscode-java-pack" - // ] - // } - // } - // "features": { - // "ghcr.io/devcontainers/features/java:1": { - // "version": "none", - // "installGradle": "true", - // "installMaven": "true" - // } - // } + "shutdownAction": "stopCompose", + "customizations": { + "vscode": { + "extensions": [ + "vscjava.vscode-java-pack" + ] + } + }, + "features": { + "ghcr.io/devcontainers/features/java:1": { + "version": "none", + "installGradle": "true", + "installMaven": "true" + } + } // "forwardPorts": [ // 8080 // ] diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index f4505e9e..7cb94ade 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.8" services: package: - image: azul/zulu-openjdk:8-latest + image: mcr.microsoft.com/devcontainers/java:8 tty: true stdin_open: true working_dir: /workspace From 45026c88aa652dca24f3fa7a9e2cd51c5f088b13 Mon Sep 17 00:00:00 2001 From: Strift Date: Sun, 9 Mar 2025 16:21:30 +0800 Subject: [PATCH 03/41] Add embedders settings --- src/main/java/com/meilisearch/sdk/Index.java | 37 +++++ .../com/meilisearch/sdk/SettingsHandler.java | 43 +++++ .../com/meilisearch/sdk/model/Embedders.java | 90 +++++++++- .../meilisearch/integration/SettingsTest.java | 155 ++++++++++++++++++ 4 files changed, 324 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/meilisearch/sdk/Index.java b/src/main/java/com/meilisearch/sdk/Index.java index ee0431a4..ca634ff4 100644 --- a/src/main/java/com/meilisearch/sdk/Index.java +++ b/src/main/java/com/meilisearch/sdk/Index.java @@ -1249,4 +1249,41 @@ public SimilarDocumentsResults searchSimilarDocuments(SimilarDocumentRequest que query, SimilarDocumentsResults.class); } + + /** + * Gets the embedders settings of the index + * + * @return a Map that contains all embedders settings + * @throws MeilisearchException if an error occurs + * @see API + * specification + */ + public Map getEmbeddersSettings() throws MeilisearchException { + return this.settingsHandler.getEmbedders(this.uid); + } + + /** + * Updates the embedders settings of the index + * + * @param embedders a Map that contains the new embedders settings + * @return TaskInfo instance + * @throws MeilisearchException if an error occurs + * @see API + * specification + */ + public TaskInfo updateEmbeddersSettings(Map embedders) throws MeilisearchException { + return this.settingsHandler.updateEmbedders(this.uid, embedders); + } + + /** + * Resets the embedders settings of the index + * + * @return TaskInfo instance + * @throws MeilisearchException if an error occurs + * @see API + * specification + */ + public TaskInfo resetEmbeddersSettings() throws MeilisearchException { + return this.settingsHandler.resetEmbedders(this.uid); + } } diff --git a/src/main/java/com/meilisearch/sdk/SettingsHandler.java b/src/main/java/com/meilisearch/sdk/SettingsHandler.java index c70f9f80..07c0e270 100644 --- a/src/main/java/com/meilisearch/sdk/SettingsHandler.java +++ b/src/main/java/com/meilisearch/sdk/SettingsHandler.java @@ -2,6 +2,7 @@ import com.meilisearch.sdk.exceptions.MeilisearchException; import com.meilisearch.sdk.http.URLBuilder; +import com.meilisearch.sdk.model.Embedders; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; import com.meilisearch.sdk.model.Pagination; @@ -769,4 +770,46 @@ public TaskInfo resetNonSeparatorTokensSettings(String uid) { return httpClient.delete( settingsPath(uid).addSubroute("non-separator-tokens").getURL(), TaskInfo.class); } + + /** + * Gets the embedders settings of the index + * + * @param uid Index identifier + * @return a Map that contains all embedders settings + * @throws MeilisearchException if an error occurs + */ + Map getEmbedders(String uid) throws MeilisearchException { + return httpClient.get( + settingsPath(uid).addSubroute("embedders").getURL(), + Map.class, + String.class, + Embedders.class); + } + + /** + * Updates the embedders settings of the index + * + * @param uid Index identifier + * @param embedders a Map that contains the new embedders settings + * @return TaskInfo instance + * @throws MeilisearchException if an error occurs + */ + TaskInfo updateEmbedders(String uid, Map embedders) throws MeilisearchException { + return httpClient.patch( + settingsPath(uid).addSubroute("embedders").getURL(), + embedders == null ? httpClient.jsonHandler.encode(embedders) : embedders, + TaskInfo.class); + } + + /** + * Resets the embedders settings of the index + * + * @param uid Index identifier + * @return TaskInfo instance + * @throws MeilisearchException if an error occurs + */ + TaskInfo resetEmbedders(String uid) throws MeilisearchException { + return httpClient.delete( + settingsPath(uid).addSubroute("embedders").getURL(), TaskInfo.class); + } } diff --git a/src/main/java/com/meilisearch/sdk/model/Embedders.java b/src/main/java/com/meilisearch/sdk/model/Embedders.java index 99fa7408..0de7c4be 100644 --- a/src/main/java/com/meilisearch/sdk/model/Embedders.java +++ b/src/main/java/com/meilisearch/sdk/model/Embedders.java @@ -2,22 +2,110 @@ import lombok.*; import lombok.experimental.Accessors; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonInclude; @Builder @AllArgsConstructor(access = AccessLevel.PACKAGE) @Getter @Setter @Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class Embedders { + /** + * Source of the embedder. + * Accepts: ollama, rest, openAI, huggingFace and userProvided + */ protected EmbedderSource source; - protected String url; + + /** + * API key for authentication with the embedder service. + * Optional: Only applicable for openAi, ollama, and rest sources. + */ protected String apiKey; + + /** + * Model to use for generating embeddings. + * Optional: Only applicable for ollama, openAI, and huggingFace sources. + */ protected String model; + + /** + * Template for document embedding. + * Optional. + */ protected String documentTemplate; + + /** + * Dimensions of the embedding vectors. + * Optional: Only applicable for openAi, huggingFace, ollama, and rest sources. + */ protected Integer dimensions; + + /** + * Distribution configuration. + * Optional. + */ + protected String distribution; + + /** + * Request configuration. + * Mandatory only when using rest embedder, optional otherwise. + */ + protected Map request; + + /** + * Response configuration. + * Mandatory only when using rest embedder, optional otherwise. + */ + protected Map response; + + /** + * Maximum bytes for document template. + * Optional. + */ + protected Integer documentTemplateMaxBytes; + + /** + * Revision identifier. + * Optional: Only applicable for huggingFace. + */ protected String revision; + + /** + * HTTP headers. + * Optional: Only applicable for rest. + */ + protected Map headers; + + /** + * Whether to use binary quantization. + * Optional. + */ + protected Boolean binaryQuantized; + + /** + * URL for the embedder service. + * Optional. + */ + protected String url; + + /** + * Input fields for the embedder. + * Optional. + */ protected String[] inputField; + + /** + * Type of input for the embedder. + * Optional. + */ protected EmbedderInputType inputType; + + /** + * Query for the embedder. + * Optional. + */ protected String query; public Embedders() {} diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index b345bdac..6451df0f 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -16,6 +16,8 @@ import com.meilisearch.integration.classes.AbstractIT; import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; +import com.meilisearch.sdk.model.Embedders; +import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; @@ -1465,4 +1467,157 @@ public void testResetNonSeparatorTokensSettings() throws Exception { nonSeparatorTokensAfterReset, is(arrayWithSize(initialNonSeparatorTokens.length))); assertThat(nonSeparatorTokensAfterReset, is(equalTo(initialNonSeparatorTokens))); } + + @Test + @DisplayName("Test get embedders settings by uid") + public void testGetEmbeddersSettings() throws Exception { + Index index = createIndex("testGetEmbeddersSettings"); + Settings initialSettings = index.getSettings(); + Map initialEmbedders = index.getEmbeddersSettings(); + + assertThat(initialEmbedders, is(equalTo(initialSettings.getEmbedders()))); + } + + @Test + @DisplayName("Test update embedders settings") + public void testUpdateEmbeddersSettings() throws Exception { + Index index = createIndex("testUpdateEmbeddersSettings"); + Map initialEmbedders = index.getEmbeddersSettings(); + + // Create new embedders settings + HashMap newEmbedders = new HashMap<>(); + + // Test OpenAI embedder with apiKey and model + Embedders openAiEmbedder = new Embedders() + .setSource(EmbedderSource.OPEN_AI) + .setApiKey("test-api-key") + .setModel("text-embedding-ada-002") + .setDimensions(1536) + .setDocumentTemplate("OpenAI document: {{document}}") + .setDocumentTemplateMaxBytes(8000) + .setBinaryQuantized(true); + + // Test HuggingFace embedder with model and revision + Embedders huggingFaceEmbedder = new Embedders() + .setSource(EmbedderSource.HUGGING_FACE) + .setModel("sentence-transformers/all-MiniLM-L6-v2") + .setRevision("main") + .setDistribution("uniform"); + + // Test REST embedder with request and response + Map request = new HashMap<>(); + request.put("url", "https://api.example.com/embeddings"); + request.put("method", "POST"); + + Map response = new HashMap<>(); + response.put("embeddingsPath", "embeddings"); + + Map headers = new HashMap<>(); + headers.put("Authorization", "Bearer test-token"); + + Embedders restEmbedder = new Embedders() + .setSource(EmbedderSource.REST) + .setApiKey("test-rest-key") + .setRequest(request) + .setResponse(response) + .setHeaders(headers) + .setDimensions(384); + + // Test Ollama embedder + Embedders ollamaEmbedder = new Embedders() + .setSource(EmbedderSource.OLLAMA) + .setModel("llama2") + .setApiKey("test-ollama-key") + .setDimensions(4096); + + // Test UserProvided embedder + Embedders userProvidedEmbedder = new Embedders() + .setSource(EmbedderSource.USER_PROVIDED) + .setDimensions(768); + + // Add all embedders to the map + newEmbedders.put("openai", openAiEmbedder); + newEmbedders.put("huggingface", huggingFaceEmbedder); + newEmbedders.put("rest", restEmbedder); + newEmbedders.put("ollama", ollamaEmbedder); + newEmbedders.put("user", userProvidedEmbedder); + + // Update settings + index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); + Map updatedEmbedders = index.getEmbeddersSettings(); + + // Verify results + assertThat(updatedEmbedders.size(), is(equalTo(5))); + + // Check OpenAI embedder + Embedders retrievedOpenAi = updatedEmbedders.get("openai"); + assertThat(retrievedOpenAi.getSource(), is(equalTo(EmbedderSource.OPEN_AI))); + assertThat(retrievedOpenAi.getApiKey(), is(equalTo("test-api-key"))); + assertThat(retrievedOpenAi.getModel(), is(equalTo("text-embedding-ada-002"))); + assertThat(retrievedOpenAi.getDimensions(), is(equalTo(1536))); + assertThat(retrievedOpenAi.getDocumentTemplate(), is(equalTo("OpenAI document: {{document}}"))); + assertThat(retrievedOpenAi.getDocumentTemplateMaxBytes(), is(equalTo(8000))); + assertThat(retrievedOpenAi.getBinaryQuantized(), is(equalTo(true))); + + // Check HuggingFace embedder + Embedders retrievedHf = updatedEmbedders.get("huggingface"); + assertThat(retrievedHf.getSource(), is(equalTo(EmbedderSource.HUGGING_FACE))); + assertThat(retrievedHf.getModel(), is(equalTo("sentence-transformers/all-MiniLM-L6-v2"))); + assertThat(retrievedHf.getRevision(), is(equalTo("main"))); + assertThat(retrievedHf.getDistribution(), is(equalTo("uniform"))); + + // Check REST embedder + Embedders retrievedRest = updatedEmbedders.get("rest"); + assertThat(retrievedRest.getSource(), is(equalTo(EmbedderSource.REST))); + assertThat(retrievedRest.getApiKey(), is(equalTo("test-rest-key"))); + assertThat(retrievedRest.getRequest(), is(notNullValue())); + assertThat(retrievedRest.getResponse(), is(notNullValue())); + assertThat(retrievedRest.getHeaders(), is(notNullValue())); + assertThat(retrievedRest.getDimensions(), is(equalTo(384))); + + // Check Ollama embedder + Embedders retrievedOllama = updatedEmbedders.get("ollama"); + assertThat(retrievedOllama.getSource(), is(equalTo(EmbedderSource.OLLAMA))); + assertThat(retrievedOllama.getModel(), is(equalTo("llama2"))); + assertThat(retrievedOllama.getApiKey(), is(equalTo("test-ollama-key"))); + assertThat(retrievedOllama.getDimensions(), is(equalTo(4096))); + + // Check UserProvided embedder + Embedders retrievedUser = updatedEmbedders.get("user"); + assertThat(retrievedUser.getSource(), is(equalTo(EmbedderSource.USER_PROVIDED))); + assertThat(retrievedUser.getDimensions(), is(equalTo(768))); + } + + @Test + @DisplayName("Test reset embedders settings") + public void testResetEmbeddersSettings() throws Exception { + Index index = createIndex("testResetEmbeddersSettings"); + Map initialEmbedders = index.getEmbeddersSettings(); + + // Create new embedders settings + HashMap newEmbedders = new HashMap<>(); + Embedders embedder = new Embedders() + .setSource(EmbedderSource.USER_PROVIDED) + .setDimensions(768); + newEmbedders.put("test", embedder); + + // Update settings + index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); + Map updatedEmbedders = index.getEmbeddersSettings(); + + // Reset settings + index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); + Map resetEmbedders = index.getEmbeddersSettings(); + + // Verify results + assertThat(updatedEmbedders.size(), is(equalTo(1))); + assertThat(updatedEmbedders.containsKey("test"), is(true)); + + // After reset, should be back to initial state + if (initialEmbedders == null) { + assertThat(resetEmbedders == null || resetEmbedders.isEmpty(), is(true)); + } else { + assertThat(resetEmbedders.size(), is(equalTo(initialEmbedders.size()))); + } + } } From 74ed1f25681dffaf273b1a48dc9beafffe6ab089 Mon Sep 17 00:00:00 2001 From: Strift Date: Wed, 12 Mar 2025 15:13:58 +0800 Subject: [PATCH 04/41] Run spotless --- src/main/java/com/meilisearch/sdk/Index.java | 3 +- .../com/meilisearch/sdk/SettingsHandler.java | 3 +- .../com/meilisearch/sdk/model/Embedders.java | 81 +++++-------------- .../meilisearch/integration/SettingsTest.java | 70 ++++++++-------- 4 files changed, 62 insertions(+), 95 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/Index.java b/src/main/java/com/meilisearch/sdk/Index.java index ca634ff4..584010c2 100644 --- a/src/main/java/com/meilisearch/sdk/Index.java +++ b/src/main/java/com/meilisearch/sdk/Index.java @@ -1271,7 +1271,8 @@ public Map getEmbeddersSettings() throws MeilisearchException * @see API * specification */ - public TaskInfo updateEmbeddersSettings(Map embedders) throws MeilisearchException { + public TaskInfo updateEmbeddersSettings(Map embedders) + throws MeilisearchException { return this.settingsHandler.updateEmbedders(this.uid, embedders); } diff --git a/src/main/java/com/meilisearch/sdk/SettingsHandler.java b/src/main/java/com/meilisearch/sdk/SettingsHandler.java index 07c0e270..2018cedb 100644 --- a/src/main/java/com/meilisearch/sdk/SettingsHandler.java +++ b/src/main/java/com/meilisearch/sdk/SettingsHandler.java @@ -794,7 +794,8 @@ Map getEmbedders(String uid) throws MeilisearchException { * @return TaskInfo instance * @throws MeilisearchException if an error occurs */ - TaskInfo updateEmbedders(String uid, Map embedders) throws MeilisearchException { + TaskInfo updateEmbedders(String uid, Map embedders) + throws MeilisearchException { return httpClient.patch( settingsPath(uid).addSubroute("embedders").getURL(), embedders == null ? httpClient.jsonHandler.encode(embedders) : embedders, diff --git a/src/main/java/com/meilisearch/sdk/model/Embedders.java b/src/main/java/com/meilisearch/sdk/model/Embedders.java index 0de7c4be..f9c15dfd 100644 --- a/src/main/java/com/meilisearch/sdk/model/Embedders.java +++ b/src/main/java/com/meilisearch/sdk/model/Embedders.java @@ -1,9 +1,9 @@ package com.meilisearch.sdk.model; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Map; import lombok.*; import lombok.experimental.Accessors; -import java.util.Map; -import com.fasterxml.jackson.annotation.JsonInclude; @Builder @AllArgsConstructor(access = AccessLevel.PACKAGE) @@ -12,100 +12,61 @@ @Accessors(chain = true) @JsonInclude(JsonInclude.Include.NON_NULL) public class Embedders { - /** - * Source of the embedder. - * Accepts: ollama, rest, openAI, huggingFace and userProvided - */ + /** Source of the embedder. Accepts: ollama, rest, openAI, huggingFace and userProvided */ protected EmbedderSource source; /** - * API key for authentication with the embedder service. - * Optional: Only applicable for openAi, ollama, and rest sources. + * API key for authentication with the embedder service. Optional: Only applicable for openAi, + * ollama, and rest sources. */ protected String apiKey; /** - * Model to use for generating embeddings. - * Optional: Only applicable for ollama, openAI, and huggingFace sources. + * Model to use for generating embeddings. Optional: Only applicable for ollama, openAI, and + * huggingFace sources. */ protected String model; - /** - * Template for document embedding. - * Optional. - */ + /** Template for document embedding. Optional. */ protected String documentTemplate; /** - * Dimensions of the embedding vectors. - * Optional: Only applicable for openAi, huggingFace, ollama, and rest sources. + * Dimensions of the embedding vectors. Optional: Only applicable for openAi, huggingFace, + * ollama, and rest sources. */ protected Integer dimensions; - /** - * Distribution configuration. - * Optional. - */ + /** Distribution configuration. Optional. */ protected String distribution; - /** - * Request configuration. - * Mandatory only when using rest embedder, optional otherwise. - */ + /** Request configuration. Mandatory only when using rest embedder, optional otherwise. */ protected Map request; - /** - * Response configuration. - * Mandatory only when using rest embedder, optional otherwise. - */ + /** Response configuration. Mandatory only when using rest embedder, optional otherwise. */ protected Map response; - /** - * Maximum bytes for document template. - * Optional. - */ + /** Maximum bytes for document template. Optional. */ protected Integer documentTemplateMaxBytes; - /** - * Revision identifier. - * Optional: Only applicable for huggingFace. - */ + /** Revision identifier. Optional: Only applicable for huggingFace. */ protected String revision; - /** - * HTTP headers. - * Optional: Only applicable for rest. - */ + /** HTTP headers. Optional: Only applicable for rest. */ protected Map headers; - /** - * Whether to use binary quantization. - * Optional. - */ + /** Whether to use binary quantization. Optional. */ protected Boolean binaryQuantized; - /** - * URL for the embedder service. - * Optional. - */ + /** URL for the embedder service. Optional. */ protected String url; - /** - * Input fields for the embedder. - * Optional. - */ + /** Input fields for the embedder. Optional. */ protected String[] inputField; - /** - * Type of input for the embedder. - * Optional. - */ + /** Type of input for the embedder. Optional. */ protected EmbedderInputType inputType; - /** - * Query for the embedder. - * Optional. - */ + /** Query for the embedder. Optional. */ protected String query; public Embedders() {} diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 6451df0f..19966d74 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -16,8 +16,8 @@ import com.meilisearch.integration.classes.AbstractIT; import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; -import com.meilisearch.sdk.model.Embedders; import com.meilisearch.sdk.model.EmbedderSource; +import com.meilisearch.sdk.model.Embedders; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; @@ -1488,21 +1488,23 @@ public void testUpdateEmbeddersSettings() throws Exception { HashMap newEmbedders = new HashMap<>(); // Test OpenAI embedder with apiKey and model - Embedders openAiEmbedder = new Embedders() - .setSource(EmbedderSource.OPEN_AI) - .setApiKey("test-api-key") - .setModel("text-embedding-ada-002") - .setDimensions(1536) - .setDocumentTemplate("OpenAI document: {{document}}") - .setDocumentTemplateMaxBytes(8000) - .setBinaryQuantized(true); + Embedders openAiEmbedder = + new Embedders() + .setSource(EmbedderSource.OPEN_AI) + .setApiKey("test-api-key") + .setModel("text-embedding-ada-002") + .setDimensions(1536) + .setDocumentTemplate("OpenAI document: {{document}}") + .setDocumentTemplateMaxBytes(8000) + .setBinaryQuantized(true); // Test HuggingFace embedder with model and revision - Embedders huggingFaceEmbedder = new Embedders() - .setSource(EmbedderSource.HUGGING_FACE) - .setModel("sentence-transformers/all-MiniLM-L6-v2") - .setRevision("main") - .setDistribution("uniform"); + Embedders huggingFaceEmbedder = + new Embedders() + .setSource(EmbedderSource.HUGGING_FACE) + .setModel("sentence-transformers/all-MiniLM-L6-v2") + .setRevision("main") + .setDistribution("uniform"); // Test REST embedder with request and response Map request = new HashMap<>(); @@ -1515,25 +1517,26 @@ public void testUpdateEmbeddersSettings() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Bearer test-token"); - Embedders restEmbedder = new Embedders() - .setSource(EmbedderSource.REST) - .setApiKey("test-rest-key") - .setRequest(request) - .setResponse(response) - .setHeaders(headers) - .setDimensions(384); + Embedders restEmbedder = + new Embedders() + .setSource(EmbedderSource.REST) + .setApiKey("test-rest-key") + .setRequest(request) + .setResponse(response) + .setHeaders(headers) + .setDimensions(384); // Test Ollama embedder - Embedders ollamaEmbedder = new Embedders() - .setSource(EmbedderSource.OLLAMA) - .setModel("llama2") - .setApiKey("test-ollama-key") - .setDimensions(4096); + Embedders ollamaEmbedder = + new Embedders() + .setSource(EmbedderSource.OLLAMA) + .setModel("llama2") + .setApiKey("test-ollama-key") + .setDimensions(4096); // Test UserProvided embedder - Embedders userProvidedEmbedder = new Embedders() - .setSource(EmbedderSource.USER_PROVIDED) - .setDimensions(768); + Embedders userProvidedEmbedder = + new Embedders().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); // Add all embedders to the map newEmbedders.put("openai", openAiEmbedder); @@ -1555,7 +1558,9 @@ public void testUpdateEmbeddersSettings() throws Exception { assertThat(retrievedOpenAi.getApiKey(), is(equalTo("test-api-key"))); assertThat(retrievedOpenAi.getModel(), is(equalTo("text-embedding-ada-002"))); assertThat(retrievedOpenAi.getDimensions(), is(equalTo(1536))); - assertThat(retrievedOpenAi.getDocumentTemplate(), is(equalTo("OpenAI document: {{document}}"))); + assertThat( + retrievedOpenAi.getDocumentTemplate(), + is(equalTo("OpenAI document: {{document}}"))); assertThat(retrievedOpenAi.getDocumentTemplateMaxBytes(), is(equalTo(8000))); assertThat(retrievedOpenAi.getBinaryQuantized(), is(equalTo(true))); @@ -1596,9 +1601,8 @@ public void testResetEmbeddersSettings() throws Exception { // Create new embedders settings HashMap newEmbedders = new HashMap<>(); - Embedders embedder = new Embedders() - .setSource(EmbedderSource.USER_PROVIDED) - .setDimensions(768); + Embedders embedder = + new Embedders().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); newEmbedders.put("test", embedder); // Update settings From d47e0f688dc4c7321894b35909485889a84dedb1 Mon Sep 17 00:00:00 2001 From: Strift Date: Wed, 12 Mar 2025 16:26:10 +0800 Subject: [PATCH 05/41] Add hybrid parameter --- .../com/meilisearch/sdk/SearchRequest.java | 7 +++ .../com/meilisearch/sdk/model/Hybrid.java | 48 ++++++++++++++ .../meilisearch/sdk/SearchRequestTest.java | 62 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 src/main/java/com/meilisearch/sdk/model/Hybrid.java diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 77650ad5..151a602c 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -1,5 +1,6 @@ package com.meilisearch.sdk; +import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -42,6 +43,7 @@ public class SearchRequest { protected Double rankingScoreThreshold; protected String[] locales; protected String distinct; + protected Hybrid hybrid; /** * Constructor for SearchRequest for building search queries with the default values: offset: 0, @@ -106,6 +108,11 @@ public String toString() { .putOpt("locales", this.locales) .putOpt("distinct", this.distinct); + // Add hybrid parameter if it exists + if (this.hybrid != null) { + jsonObject.put("hybrid", this.hybrid.toJSONObject()); + } + return jsonObject.toString(); } } diff --git a/src/main/java/com/meilisearch/sdk/model/Hybrid.java b/src/main/java/com/meilisearch/sdk/model/Hybrid.java new file mode 100644 index 00000000..62cdd1bb --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/Hybrid.java @@ -0,0 +1,48 @@ +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; + +/** Hybrid search configuration */ +@Builder +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +@Setter +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Hybrid { + /** Semantic ratio for hybrid search (between 0 and 1) */ + private Double semanticRatio; + + /** Embedder to use for hybrid search (mandatory if hybrid is set) */ + private String embedder; + + /** + * Method that returns the JSON representation of the Hybrid object + * + * @return JSONObject representation of the Hybrid object + */ + public JSONObject toJSONObject() { + return new JSONObject() + .putOpt("semanticRatio", this.semanticRatio) + .putOpt("embedder", this.embedder); + } + + /** + * Method that returns the JSON String of the Hybrid object + * + * @return JSON String of the Hybrid object + */ + @Override + public String toString() { + return toJSONObject().toString(); + } +} diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index 6eb9f850..ba350fed 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -5,6 +5,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; import org.junit.jupiter.api.Test; @@ -363,4 +364,65 @@ void toStringEveryParametersWithArrayMatchingStrategyNull() { assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); assertThat(classToTest.toString(), is(equalTo(expectedToString))); } + + @Test + void toStringWithHybrid() { + Hybrid hybrid = Hybrid.builder().semanticRatio(0.5).embedder("default").build(); + + SearchRequest classToTest = new SearchRequest("This is a Test").setHybrid(hybrid); + + String expected = + "{\"q\":\"This is a Test\",\"hybrid\":{\"semanticRatio\":0.5,\"embedder\":\"default\"}}"; + assertThat(classToTest.toString(), is(equalTo(expected))); + + // Verify getters + assertThat(classToTest.getHybrid().getSemanticRatio(), is(equalTo(0.5))); + assertThat(classToTest.getHybrid().getEmbedder(), is(equalTo("default"))); + } + + @Test + void toStringWithHybridUsingBuilder() { + SearchRequest classToTest = + SearchRequest.builder() + .q("This is a Test") + .hybrid(Hybrid.builder().semanticRatio(0.5).embedder("default").build()) + .build(); + + String expected = + "{\"q\":\"This is a Test\",\"hybrid\":{\"semanticRatio\":0.5,\"embedder\":\"default\"}}"; + assertThat(classToTest.toString(), is(equalTo(expected))); + + // Verify getters + assertThat(classToTest.getHybrid().getSemanticRatio(), is(equalTo(0.5))); + assertThat(classToTest.getHybrid().getEmbedder(), is(equalTo("default"))); + } + + @Test + void toStringWithHybridAndOtherParameters() { + SearchRequest classToTest = + SearchRequest.builder() + .q("This is a Test") + .offset(200) + .limit(900) + .hybrid( + Hybrid.builder() + .semanticRatio(0.7) + .embedder("custom-embedder") + .build()) + .build(); + + String expected = + "{\"q\":\"This is a Test\",\"hybrid\":{\"semanticRatio\":0.7,\"embedder\":\"custom-embedder\"},\"offset\":200,\"limit\":900}"; + assertThat(classToTest.toString(), is(equalTo(expected))); + } + + @Test + void toStringWithHybridOnlyEmbedder() { + SearchRequest classToTest = + new SearchRequest("This is a Test") + .setHybrid(Hybrid.builder().embedder("default").build()); + + String expected = "{\"q\":\"This is a Test\",\"hybrid\":{\"embedder\":\"default\"}}"; + assertThat(classToTest.toString(), is(equalTo(expected))); + } } From 426f605205510735d821c04f069b959baa03f34e Mon Sep 17 00:00:00 2001 From: Strift Date: Wed, 12 Mar 2025 16:48:30 +0800 Subject: [PATCH 06/41] Fix null embedder test --- src/main/java/com/meilisearch/sdk/SettingsHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/meilisearch/sdk/SettingsHandler.java b/src/main/java/com/meilisearch/sdk/SettingsHandler.java index 2018cedb..63cd9ae7 100644 --- a/src/main/java/com/meilisearch/sdk/SettingsHandler.java +++ b/src/main/java/com/meilisearch/sdk/SettingsHandler.java @@ -798,7 +798,7 @@ TaskInfo updateEmbedders(String uid, Map embedders) throws MeilisearchException { return httpClient.patch( settingsPath(uid).addSubroute("embedders").getURL(), - embedders == null ? httpClient.jsonHandler.encode(embedders) : embedders, + embedders == null ? null : httpClient.jsonHandler.encode(embedders), TaskInfo.class); } From a209989fd9e8e6dfd925d9888396f3aa3380b524 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 09:41:37 +0800 Subject: [PATCH 07/41] Remove devcontainer --- .devcontainer/devcontainer.json | 25 ------------------------- .devcontainer/docker-compose.yml | 24 ------------------------ 2 files changed, 49 deletions(-) delete mode 100644 .devcontainer/devcontainer.json delete mode 100644 .devcontainer/docker-compose.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 6bf11e58..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "Meilisearch Java", - // "image": "mcr.microsoft.com/devcontainers/java:8", - "dockerComposeFile": "./docker-compose.yml", - "service": "package", - "workspaceFolder": "/workspace", - "shutdownAction": "stopCompose", - "customizations": { - "vscode": { - "extensions": [ - "vscjava.vscode-java-pack" - ] - } - }, - "features": { - "ghcr.io/devcontainers/features/java:1": { - "version": "none", - "installGradle": "true", - "installMaven": "true" - } - } - // "forwardPorts": [ - // 8080 - // ] -} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml deleted file mode 100644 index 7cb94ade..00000000 --- a/.devcontainer/docker-compose.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: "3.8" - -services: - package: - image: mcr.microsoft.com/devcontainers/java:8 - tty: true - stdin_open: true - working_dir: /workspace - environment: - - MEILISEARCH_HOST=http://meilisearch:7700 - depends_on: - - meilisearch - links: - - meilisearch - volumes: - - ../:/workspace - - meilisearch: - image: getmeili/meilisearch:latest - ports: - - "7700" - environment: - - MEILI_MASTER_KEY=masterKey - - MEILI_NO_ANALYTICS=true From 08a7684065b5133a03f6b4a0a80c6ca22b3abe77 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 09:52:24 +0800 Subject: [PATCH 08/41] Rename embedder and add EmbedderDistirbution class --- src/main/java/com/meilisearch/sdk/Index.java | 4 +- .../com/meilisearch/sdk/SettingsHandler.java | 8 +-- .../model/{Embedders.java => Embedder.java} | 6 +- .../sdk/model/EmbedderDistribution.java | 56 +++++++++++++++++++ .../com/meilisearch/sdk/model/Settings.java | 2 +- .../meilisearch/integration/SearchTest.java | 4 +- .../meilisearch/integration/SettingsTest.java | 52 ++++++++--------- 7 files changed, 94 insertions(+), 38 deletions(-) rename src/main/java/com/meilisearch/sdk/model/{Embedders.java => Embedder.java} (95%) create mode 100644 src/main/java/com/meilisearch/sdk/model/EmbedderDistribution.java diff --git a/src/main/java/com/meilisearch/sdk/Index.java b/src/main/java/com/meilisearch/sdk/Index.java index 584010c2..828fbe68 100644 --- a/src/main/java/com/meilisearch/sdk/Index.java +++ b/src/main/java/com/meilisearch/sdk/Index.java @@ -1258,7 +1258,7 @@ public SimilarDocumentsResults searchSimilarDocuments(SimilarDocumentRequest que * @see API * specification */ - public Map getEmbeddersSettings() throws MeilisearchException { + public Map getEmbeddersSettings() throws MeilisearchException { return this.settingsHandler.getEmbedders(this.uid); } @@ -1271,7 +1271,7 @@ public Map getEmbeddersSettings() throws MeilisearchException * @see API * specification */ - public TaskInfo updateEmbeddersSettings(Map embedders) + public TaskInfo updateEmbeddersSettings(Map embedders) throws MeilisearchException { return this.settingsHandler.updateEmbedders(this.uid, embedders); } diff --git a/src/main/java/com/meilisearch/sdk/SettingsHandler.java b/src/main/java/com/meilisearch/sdk/SettingsHandler.java index 63cd9ae7..9ee73a3a 100644 --- a/src/main/java/com/meilisearch/sdk/SettingsHandler.java +++ b/src/main/java/com/meilisearch/sdk/SettingsHandler.java @@ -2,7 +2,7 @@ import com.meilisearch.sdk.exceptions.MeilisearchException; import com.meilisearch.sdk.http.URLBuilder; -import com.meilisearch.sdk.model.Embedders; +import com.meilisearch.sdk.model.Embedder; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; import com.meilisearch.sdk.model.Pagination; @@ -778,12 +778,12 @@ public TaskInfo resetNonSeparatorTokensSettings(String uid) { * @return a Map that contains all embedders settings * @throws MeilisearchException if an error occurs */ - Map getEmbedders(String uid) throws MeilisearchException { + Map getEmbedders(String uid) throws MeilisearchException { return httpClient.get( settingsPath(uid).addSubroute("embedders").getURL(), Map.class, String.class, - Embedders.class); + Embedder.class); } /** @@ -794,7 +794,7 @@ Map getEmbedders(String uid) throws MeilisearchException { * @return TaskInfo instance * @throws MeilisearchException if an error occurs */ - TaskInfo updateEmbedders(String uid, Map embedders) + TaskInfo updateEmbedders(String uid, Map embedders) throws MeilisearchException { return httpClient.patch( settingsPath(uid).addSubroute("embedders").getURL(), diff --git a/src/main/java/com/meilisearch/sdk/model/Embedders.java b/src/main/java/com/meilisearch/sdk/model/Embedder.java similarity index 95% rename from src/main/java/com/meilisearch/sdk/model/Embedders.java rename to src/main/java/com/meilisearch/sdk/model/Embedder.java index f9c15dfd..7179428d 100644 --- a/src/main/java/com/meilisearch/sdk/model/Embedders.java +++ b/src/main/java/com/meilisearch/sdk/model/Embedder.java @@ -11,7 +11,7 @@ @Setter @Accessors(chain = true) @JsonInclude(JsonInclude.Include.NON_NULL) -public class Embedders { +public class Embedder { /** Source of the embedder. Accepts: ollama, rest, openAI, huggingFace and userProvided */ protected EmbedderSource source; @@ -37,7 +37,7 @@ public class Embedders { protected Integer dimensions; /** Distribution configuration. Optional. */ - protected String distribution; + protected EmbedderDistribution distribution; /** Request configuration. Mandatory only when using rest embedder, optional otherwise. */ protected Map request; @@ -69,5 +69,5 @@ public class Embedders { /** Query for the embedder. Optional. */ protected String query; - public Embedders() {} + public Embedder() {} } diff --git a/src/main/java/com/meilisearch/sdk/model/EmbedderDistribution.java b/src/main/java/com/meilisearch/sdk/model/EmbedderDistribution.java new file mode 100644 index 00000000..e99480bb --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/EmbedderDistribution.java @@ -0,0 +1,56 @@ +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; + +/** + * Describes the natural distribution of search results for embedders. Contains mean and sigma + * values, each between 0 and 1. + */ +@Builder +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@NoArgsConstructor(access = AccessLevel.PUBLIC) +@Getter +@Setter +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class EmbedderDistribution { + /** Mean value of the distribution, between 0 and 1 */ + private Double mean; + + /** Sigma (standard deviation) value of the distribution, between 0 and 1 */ + private Double sigma; + + /** + * Creates a uniform distribution with default values + * + * @return An EmbedderDistribution instance with mean=0.5 and sigma=0.5 + */ + public static EmbedderDistribution uniform() { + return new EmbedderDistribution().setMean(0.5).setSigma(0.5); + } + + /** + * Creates a custom distribution with specified mean and sigma values + * + * @param mean Mean value between 0 and 1 + * @param sigma Sigma value between 0 and 1 + * @return An EmbedderDistribution instance with the specified values + * @throws IllegalArgumentException if mean or sigma are outside the valid range + */ + public static EmbedderDistribution custom(double mean, double sigma) { + if (mean < 0 || mean > 1) { + throw new IllegalArgumentException("Mean must be between 0 and 1"); + } + if (sigma < 0 || sigma > 1) { + throw new IllegalArgumentException("Sigma must be between 0 and 1"); + } + return new EmbedderDistribution().setMean(mean).setSigma(sigma); + } +} diff --git a/src/main/java/com/meilisearch/sdk/model/Settings.java b/src/main/java/com/meilisearch/sdk/model/Settings.java index 2a4233b6..419bd09f 100644 --- a/src/main/java/com/meilisearch/sdk/model/Settings.java +++ b/src/main/java/com/meilisearch/sdk/model/Settings.java @@ -31,7 +31,7 @@ public class Settings { protected Integer searchCutoffMs; protected String[] separatorTokens; protected String[] nonSeparatorTokens; - protected HashMap embedders; + protected HashMap embedders; protected LocalizedAttribute[] localizedAttributes; public Settings() {} diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index 86c17d92..5d81a40d 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -1090,9 +1090,9 @@ public void testMultiSearchWithMergeFacets() { public void testSimilarDocuments() throws Exception { String indexUid = "SimilarDocuments"; Index index = client.index(indexUid); - HashMap embedders = new HashMap<>(); + HashMap embedders = new HashMap<>(); embedders.put( - "manual", new Embedders().setSource(EmbedderSource.USER_PROVIDED).setDimensions(3)); + "manual", new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(3)); Settings settings = new Settings(); settings.setEmbedders(embedders); diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 19966d74..bb10c070 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -17,7 +17,7 @@ import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; import com.meilisearch.sdk.model.EmbedderSource; -import com.meilisearch.sdk.model.Embedders; +import com.meilisearch.sdk.model.Embedder; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; @@ -1473,7 +1473,7 @@ public void testResetNonSeparatorTokensSettings() throws Exception { public void testGetEmbeddersSettings() throws Exception { Index index = createIndex("testGetEmbeddersSettings"); Settings initialSettings = index.getSettings(); - Map initialEmbedders = index.getEmbeddersSettings(); + Map initialEmbedders = index.getEmbeddersSettings(); assertThat(initialEmbedders, is(equalTo(initialSettings.getEmbedders()))); } @@ -1482,14 +1482,14 @@ public void testGetEmbeddersSettings() throws Exception { @DisplayName("Test update embedders settings") public void testUpdateEmbeddersSettings() throws Exception { Index index = createIndex("testUpdateEmbeddersSettings"); - Map initialEmbedders = index.getEmbeddersSettings(); + Map initialEmbedders = index.getEmbeddersSettings(); // Create new embedders settings - HashMap newEmbedders = new HashMap<>(); + HashMap newEmbedders = new HashMap<>(); // Test OpenAI embedder with apiKey and model - Embedders openAiEmbedder = - new Embedders() + Embedder openAiEmbedder = + new Embedder() .setSource(EmbedderSource.OPEN_AI) .setApiKey("test-api-key") .setModel("text-embedding-ada-002") @@ -1499,8 +1499,8 @@ public void testUpdateEmbeddersSettings() throws Exception { .setBinaryQuantized(true); // Test HuggingFace embedder with model and revision - Embedders huggingFaceEmbedder = - new Embedders() + Embedder huggingFaceEmbedder = + new Embedder() .setSource(EmbedderSource.HUGGING_FACE) .setModel("sentence-transformers/all-MiniLM-L6-v2") .setRevision("main") @@ -1517,8 +1517,8 @@ public void testUpdateEmbeddersSettings() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Bearer test-token"); - Embedders restEmbedder = - new Embedders() + Embedder restEmbedder = + new Embedder() .setSource(EmbedderSource.REST) .setApiKey("test-rest-key") .setRequest(request) @@ -1527,16 +1527,16 @@ public void testUpdateEmbeddersSettings() throws Exception { .setDimensions(384); // Test Ollama embedder - Embedders ollamaEmbedder = - new Embedders() + Embedder ollamaEmbedder = + new Embedder() .setSource(EmbedderSource.OLLAMA) .setModel("llama2") .setApiKey("test-ollama-key") .setDimensions(4096); // Test UserProvided embedder - Embedders userProvidedEmbedder = - new Embedders().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); + Embedder userProvidedEmbedder = + new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); // Add all embedders to the map newEmbedders.put("openai", openAiEmbedder); @@ -1547,13 +1547,13 @@ public void testUpdateEmbeddersSettings() throws Exception { // Update settings index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); - Map updatedEmbedders = index.getEmbeddersSettings(); + Map updatedEmbedders = index.getEmbeddersSettings(); // Verify results assertThat(updatedEmbedders.size(), is(equalTo(5))); // Check OpenAI embedder - Embedders retrievedOpenAi = updatedEmbedders.get("openai"); + Embedder retrievedOpenAi = updatedEmbedders.get("openai"); assertThat(retrievedOpenAi.getSource(), is(equalTo(EmbedderSource.OPEN_AI))); assertThat(retrievedOpenAi.getApiKey(), is(equalTo("test-api-key"))); assertThat(retrievedOpenAi.getModel(), is(equalTo("text-embedding-ada-002"))); @@ -1565,14 +1565,14 @@ public void testUpdateEmbeddersSettings() throws Exception { assertThat(retrievedOpenAi.getBinaryQuantized(), is(equalTo(true))); // Check HuggingFace embedder - Embedders retrievedHf = updatedEmbedders.get("huggingface"); + Embedder retrievedHf = updatedEmbedders.get("huggingface"); assertThat(retrievedHf.getSource(), is(equalTo(EmbedderSource.HUGGING_FACE))); assertThat(retrievedHf.getModel(), is(equalTo("sentence-transformers/all-MiniLM-L6-v2"))); assertThat(retrievedHf.getRevision(), is(equalTo("main"))); assertThat(retrievedHf.getDistribution(), is(equalTo("uniform"))); // Check REST embedder - Embedders retrievedRest = updatedEmbedders.get("rest"); + Embedder retrievedRest = updatedEmbedders.get("rest"); assertThat(retrievedRest.getSource(), is(equalTo(EmbedderSource.REST))); assertThat(retrievedRest.getApiKey(), is(equalTo("test-rest-key"))); assertThat(retrievedRest.getRequest(), is(notNullValue())); @@ -1581,14 +1581,14 @@ public void testUpdateEmbeddersSettings() throws Exception { assertThat(retrievedRest.getDimensions(), is(equalTo(384))); // Check Ollama embedder - Embedders retrievedOllama = updatedEmbedders.get("ollama"); + Embedder retrievedOllama = updatedEmbedders.get("ollama"); assertThat(retrievedOllama.getSource(), is(equalTo(EmbedderSource.OLLAMA))); assertThat(retrievedOllama.getModel(), is(equalTo("llama2"))); assertThat(retrievedOllama.getApiKey(), is(equalTo("test-ollama-key"))); assertThat(retrievedOllama.getDimensions(), is(equalTo(4096))); // Check UserProvided embedder - Embedders retrievedUser = updatedEmbedders.get("user"); + Embedder retrievedUser = updatedEmbedders.get("user"); assertThat(retrievedUser.getSource(), is(equalTo(EmbedderSource.USER_PROVIDED))); assertThat(retrievedUser.getDimensions(), is(equalTo(768))); } @@ -1597,21 +1597,21 @@ public void testUpdateEmbeddersSettings() throws Exception { @DisplayName("Test reset embedders settings") public void testResetEmbeddersSettings() throws Exception { Index index = createIndex("testResetEmbeddersSettings"); - Map initialEmbedders = index.getEmbeddersSettings(); + Map initialEmbedders = index.getEmbeddersSettings(); // Create new embedders settings - HashMap newEmbedders = new HashMap<>(); - Embedders embedder = - new Embedders().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); + HashMap newEmbedders = new HashMap<>(); + Embedder embedder = + new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); newEmbedders.put("test", embedder); // Update settings index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); - Map updatedEmbedders = index.getEmbeddersSettings(); + Map updatedEmbedders = index.getEmbeddersSettings(); // Reset settings index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); - Map resetEmbedders = index.getEmbeddersSettings(); + Map resetEmbedders = index.getEmbeddersSettings(); // Verify results assertThat(updatedEmbedders.size(), is(equalTo(1))); From 2ba68af9a56ddd4bdb3eaf21fb2ca2fe6f0bfc0e Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 10:07:14 +0800 Subject: [PATCH 09/41] Update embedders distribution test --- src/test/java/com/meilisearch/integration/SettingsTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index bb10c070..e9f3a24e 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -18,6 +18,7 @@ import com.meilisearch.sdk.Index; import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.Embedder; +import com.meilisearch.sdk.model.EmbedderDistribution; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; @@ -1504,7 +1505,7 @@ public void testUpdateEmbeddersSettings() throws Exception { .setSource(EmbedderSource.HUGGING_FACE) .setModel("sentence-transformers/all-MiniLM-L6-v2") .setRevision("main") - .setDistribution("uniform"); + .setDistribution(EmbedderDistribution.uniform()); // Test REST embedder with request and response Map request = new HashMap<>(); @@ -1569,7 +1570,8 @@ public void testUpdateEmbeddersSettings() throws Exception { assertThat(retrievedHf.getSource(), is(equalTo(EmbedderSource.HUGGING_FACE))); assertThat(retrievedHf.getModel(), is(equalTo("sentence-transformers/all-MiniLM-L6-v2"))); assertThat(retrievedHf.getRevision(), is(equalTo("main"))); - assertThat(retrievedHf.getDistribution(), is(equalTo("uniform"))); + assertThat(retrievedHf.getDistribution().getMean(), is(equalTo(0.5))); + assertThat(retrievedHf.getDistribution().getSigma(), is(equalTo(0.5))); // Check REST embedder Embedder retrievedRest = updatedEmbedders.get("rest"); From 807a2b6f588e4e0d4e9c2123a2f731b790948c04 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 10:23:51 +0800 Subject: [PATCH 10/41] Lint --- src/test/java/com/meilisearch/integration/SettingsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index e9f3a24e..c5d4317a 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -16,9 +16,9 @@ import com.meilisearch.integration.classes.AbstractIT; import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; -import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.Embedder; import com.meilisearch.sdk.model.EmbedderDistribution; +import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; import com.meilisearch.sdk.model.LocalizedAttribute; From 6b4a620fe87cb38f9bf4abac2c9037b26a2e0178 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:09:36 +0800 Subject: [PATCH 11/41] Update test --- .../java/com/meilisearch/integration/SettingsTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index c5d4317a..0ac8654a 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1602,7 +1602,7 @@ public void testResetEmbeddersSettings() throws Exception { Map initialEmbedders = index.getEmbeddersSettings(); // Create new embedders settings - HashMap newEmbedders = new HashMap<>(); + Map newEmbedders = new HashMap<>(); Embedder embedder = new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); newEmbedders.put("test", embedder); @@ -1611,15 +1611,13 @@ public void testResetEmbeddersSettings() throws Exception { index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); Map updatedEmbedders = index.getEmbeddersSettings(); - // Reset settings - index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); - Map resetEmbedders = index.getEmbeddersSettings(); - // Verify results assertThat(updatedEmbedders.size(), is(equalTo(1))); assertThat(updatedEmbedders.containsKey("test"), is(true)); - // After reset, should be back to initial state + // Reset settings + index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); + Map resetEmbedders = index.getEmbeddersSettings(); if (initialEmbedders == null) { assertThat(resetEmbedders == null || resetEmbedders.isEmpty(), is(true)); } else { From de3a46df75c3ce8792808c9e133e9cb100397076 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:12:28 +0800 Subject: [PATCH 12/41] Temporarily add more info to tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 530085b3..bc3cefd0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: - name: Meilisearch (latest) setup with Docker run: docker run -d -p 7700:7700 getmeili/meilisearch:latest meilisearch --master-key=masterKey --no-analytics - name: Build and run unit and integration tests - run: ./gradlew build integrationTest + run: ./gradlew build integrationTest --info - name: Archive test report uses: actions/upload-artifact@v4 if: failure() From 132e19120ebf623061a53e3f1c774a3fb50e00d0 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:20:09 +0800 Subject: [PATCH 13/41] Remove document template edition --- .../java/com/meilisearch/integration/SettingsTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 0ac8654a..04c59e86 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1495,8 +1495,6 @@ public void testUpdateEmbeddersSettings() throws Exception { .setApiKey("test-api-key") .setModel("text-embedding-ada-002") .setDimensions(1536) - .setDocumentTemplate("OpenAI document: {{document}}") - .setDocumentTemplateMaxBytes(8000) .setBinaryQuantized(true); // Test HuggingFace embedder with model and revision @@ -1559,11 +1557,6 @@ public void testUpdateEmbeddersSettings() throws Exception { assertThat(retrievedOpenAi.getApiKey(), is(equalTo("test-api-key"))); assertThat(retrievedOpenAi.getModel(), is(equalTo("text-embedding-ada-002"))); assertThat(retrievedOpenAi.getDimensions(), is(equalTo(1536))); - assertThat( - retrievedOpenAi.getDocumentTemplate(), - is(equalTo("OpenAI document: {{document}}"))); - assertThat(retrievedOpenAi.getDocumentTemplateMaxBytes(), is(equalTo(8000))); - assertThat(retrievedOpenAi.getBinaryQuantized(), is(equalTo(true))); // Check HuggingFace embedder Embedder retrievedHf = updatedEmbedders.get("huggingface"); From 405a0e9d2f23c7205417cd5ea6cc79723604194d Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:23:09 +0800 Subject: [PATCH 14/41] Update reset embedder test --- .../com/meilisearch/integration/SettingsTest.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 04c59e86..1dde1e2f 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1597,24 +1597,22 @@ public void testResetEmbeddersSettings() throws Exception { // Create new embedders settings Map newEmbedders = new HashMap<>(); Embedder embedder = - new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); + new Embedder() + .setSource(EmbedderSource.OPEN_AI) + .setApiKey("test-api-key") + .setModel("text-embedding-ada-002") + .setDimensions(1536); newEmbedders.put("test", embedder); // Update settings index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); Map updatedEmbedders = index.getEmbeddersSettings(); - - // Verify results assertThat(updatedEmbedders.size(), is(equalTo(1))); assertThat(updatedEmbedders.containsKey("test"), is(true)); // Reset settings index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); Map resetEmbedders = index.getEmbeddersSettings(); - if (initialEmbedders == null) { - assertThat(resetEmbedders == null || resetEmbedders.isEmpty(), is(true)); - } else { - assertThat(resetEmbedders.size(), is(equalTo(initialEmbedders.size()))); - } + assertThat(resetEmbedders.size(), is(equalTo(initialEmbedders.size()))); } } From c52fc85d7e0d9e67657320984dbceb58a7dc0f07 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:27:46 +0800 Subject: [PATCH 15/41] Update rest embedder test --- src/test/java/com/meilisearch/integration/SettingsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 1dde1e2f..9ed8049f 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1507,11 +1507,11 @@ public void testUpdateEmbeddersSettings() throws Exception { // Test REST embedder with request and response Map request = new HashMap<>(); - request.put("url", "https://api.example.com/embeddings"); - request.put("method", "POST"); + request.put("model", "MODEL_NAME"); + request.put("input", "{{text}}"); Map response = new HashMap<>(); - response.put("embeddingsPath", "embeddings"); + response.put("result", "{{embedding}}"); Map headers = new HashMap<>(); headers.put("Authorization", "Bearer test-token"); From 551472213093d1034c025f15aa0edead2d4c949b Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:36:09 +0800 Subject: [PATCH 16/41] Create RestEmbedder class --- .../com/meilisearch/sdk/model/Embedder.java | 12 ------- .../meilisearch/sdk/model/RestEmbedder.java | 31 +++++++++++++++++++ .../meilisearch/integration/SettingsTest.java | 8 ++--- 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/meilisearch/sdk/model/RestEmbedder.java diff --git a/src/main/java/com/meilisearch/sdk/model/Embedder.java b/src/main/java/com/meilisearch/sdk/model/Embedder.java index 7179428d..a02c08be 100644 --- a/src/main/java/com/meilisearch/sdk/model/Embedder.java +++ b/src/main/java/com/meilisearch/sdk/model/Embedder.java @@ -39,27 +39,15 @@ public class Embedder { /** Distribution configuration. Optional. */ protected EmbedderDistribution distribution; - /** Request configuration. Mandatory only when using rest embedder, optional otherwise. */ - protected Map request; - - /** Response configuration. Mandatory only when using rest embedder, optional otherwise. */ - protected Map response; - /** Maximum bytes for document template. Optional. */ protected Integer documentTemplateMaxBytes; /** Revision identifier. Optional: Only applicable for huggingFace. */ protected String revision; - /** HTTP headers. Optional: Only applicable for rest. */ - protected Map headers; - /** Whether to use binary quantization. Optional. */ protected Boolean binaryQuantized; - /** URL for the embedder service. Optional. */ - protected String url; - /** Input fields for the embedder. Optional. */ protected String[] inputField; diff --git a/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java b/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java new file mode 100644 index 00000000..d2bfb1e7 --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java @@ -0,0 +1,31 @@ +package com.meilisearch.sdk.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Map; +import lombok.*; +import lombok.experimental.Accessors; + +@Builder +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +@Setter +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class RestEmbedder extends Embedder { + /** Request configuration. Mandatory for REST embedder. */ + private Map request; + + /** Response configuration. Mandatory for REST embedder. */ + private Map response; + + /** HTTP headers. Optional. */ + private Map headers; + + /** URL for the embedder service. */ + private String url; + + public RestEmbedder() { + super(); + this.source = EmbedderSource.rest; + } +} diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 9ed8049f..c42408d6 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1517,13 +1517,11 @@ public void testUpdateEmbeddersSettings() throws Exception { headers.put("Authorization", "Bearer test-token"); Embedder restEmbedder = - new Embedder() - .setSource(EmbedderSource.REST) - .setApiKey("test-rest-key") + new RestEmbedder() + .setUrl("https://api.example.com/embeddings") .setRequest(request) .setResponse(response) - .setHeaders(headers) - .setDimensions(384); + .setHeaders(headers); // Test Ollama embedder Embedder ollamaEmbedder = From 930aa3998585f7a87284b40b468fcf714ec23803 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 13:39:31 +0800 Subject: [PATCH 17/41] Delete RestEmbedder class for consistency --- .../com/meilisearch/sdk/model/Embedder.java | 12 +++++++ .../meilisearch/sdk/model/RestEmbedder.java | 31 ------------------- .../meilisearch/integration/SettingsTest.java | 3 +- 3 files changed, 14 insertions(+), 32 deletions(-) delete mode 100644 src/main/java/com/meilisearch/sdk/model/RestEmbedder.java diff --git a/src/main/java/com/meilisearch/sdk/model/Embedder.java b/src/main/java/com/meilisearch/sdk/model/Embedder.java index a02c08be..7179428d 100644 --- a/src/main/java/com/meilisearch/sdk/model/Embedder.java +++ b/src/main/java/com/meilisearch/sdk/model/Embedder.java @@ -39,15 +39,27 @@ public class Embedder { /** Distribution configuration. Optional. */ protected EmbedderDistribution distribution; + /** Request configuration. Mandatory only when using rest embedder, optional otherwise. */ + protected Map request; + + /** Response configuration. Mandatory only when using rest embedder, optional otherwise. */ + protected Map response; + /** Maximum bytes for document template. Optional. */ protected Integer documentTemplateMaxBytes; /** Revision identifier. Optional: Only applicable for huggingFace. */ protected String revision; + /** HTTP headers. Optional: Only applicable for rest. */ + protected Map headers; + /** Whether to use binary quantization. Optional. */ protected Boolean binaryQuantized; + /** URL for the embedder service. Optional. */ + protected String url; + /** Input fields for the embedder. Optional. */ protected String[] inputField; diff --git a/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java b/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java deleted file mode 100644 index d2bfb1e7..00000000 --- a/src/main/java/com/meilisearch/sdk/model/RestEmbedder.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.meilisearch.sdk.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import java.util.Map; -import lombok.*; -import lombok.experimental.Accessors; - -@Builder -@AllArgsConstructor(access = AccessLevel.PACKAGE) -@Getter -@Setter -@Accessors(chain = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class RestEmbedder extends Embedder { - /** Request configuration. Mandatory for REST embedder. */ - private Map request; - - /** Response configuration. Mandatory for REST embedder. */ - private Map response; - - /** HTTP headers. Optional. */ - private Map headers; - - /** URL for the embedder service. */ - private String url; - - public RestEmbedder() { - super(); - this.source = EmbedderSource.rest; - } -} diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index c42408d6..acfb0a77 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1517,7 +1517,8 @@ public void testUpdateEmbeddersSettings() throws Exception { headers.put("Authorization", "Bearer test-token"); Embedder restEmbedder = - new RestEmbedder() + new Embedder() + .setSource(EmbedderSource.REST) .setUrl("https://api.example.com/embeddings") .setRequest(request) .setResponse(response) From dc7ba8dd68322c67fc1e02412a4b0297ac3524fa Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 15:23:36 +0800 Subject: [PATCH 18/41] Remove error prones embedders --- .../meilisearch/integration/SettingsTest.java | 91 +------------------ 1 file changed, 3 insertions(+), 88 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index acfb0a77..d979d333 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1487,102 +1487,17 @@ public void testUpdateEmbeddersSettings() throws Exception { // Create new embedders settings HashMap newEmbedders = new HashMap<>(); - - // Test OpenAI embedder with apiKey and model - Embedder openAiEmbedder = - new Embedder() - .setSource(EmbedderSource.OPEN_AI) - .setApiKey("test-api-key") - .setModel("text-embedding-ada-002") - .setDimensions(1536) - .setBinaryQuantized(true); - - // Test HuggingFace embedder with model and revision - Embedder huggingFaceEmbedder = - new Embedder() - .setSource(EmbedderSource.HUGGING_FACE) - .setModel("sentence-transformers/all-MiniLM-L6-v2") - .setRevision("main") - .setDistribution(EmbedderDistribution.uniform()); - - // Test REST embedder with request and response - Map request = new HashMap<>(); - request.put("model", "MODEL_NAME"); - request.put("input", "{{text}}"); - - Map response = new HashMap<>(); - response.put("result", "{{embedding}}"); - - Map headers = new HashMap<>(); - headers.put("Authorization", "Bearer test-token"); - - Embedder restEmbedder = - new Embedder() - .setSource(EmbedderSource.REST) - .setUrl("https://api.example.com/embeddings") - .setRequest(request) - .setResponse(response) - .setHeaders(headers); - - // Test Ollama embedder - Embedder ollamaEmbedder = - new Embedder() - .setSource(EmbedderSource.OLLAMA) - .setModel("llama2") - .setApiKey("test-ollama-key") - .setDimensions(4096); - - // Test UserProvided embedder Embedder userProvidedEmbedder = new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); - - // Add all embedders to the map - newEmbedders.put("openai", openAiEmbedder); - newEmbedders.put("huggingface", huggingFaceEmbedder); - newEmbedders.put("rest", restEmbedder); - newEmbedders.put("ollama", ollamaEmbedder); - newEmbedders.put("user", userProvidedEmbedder); + newEmbedders.put("custom", userProvidedEmbedder); // Update settings index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); Map updatedEmbedders = index.getEmbeddersSettings(); // Verify results - assertThat(updatedEmbedders.size(), is(equalTo(5))); - - // Check OpenAI embedder - Embedder retrievedOpenAi = updatedEmbedders.get("openai"); - assertThat(retrievedOpenAi.getSource(), is(equalTo(EmbedderSource.OPEN_AI))); - assertThat(retrievedOpenAi.getApiKey(), is(equalTo("test-api-key"))); - assertThat(retrievedOpenAi.getModel(), is(equalTo("text-embedding-ada-002"))); - assertThat(retrievedOpenAi.getDimensions(), is(equalTo(1536))); - - // Check HuggingFace embedder - Embedder retrievedHf = updatedEmbedders.get("huggingface"); - assertThat(retrievedHf.getSource(), is(equalTo(EmbedderSource.HUGGING_FACE))); - assertThat(retrievedHf.getModel(), is(equalTo("sentence-transformers/all-MiniLM-L6-v2"))); - assertThat(retrievedHf.getRevision(), is(equalTo("main"))); - assertThat(retrievedHf.getDistribution().getMean(), is(equalTo(0.5))); - assertThat(retrievedHf.getDistribution().getSigma(), is(equalTo(0.5))); - - // Check REST embedder - Embedder retrievedRest = updatedEmbedders.get("rest"); - assertThat(retrievedRest.getSource(), is(equalTo(EmbedderSource.REST))); - assertThat(retrievedRest.getApiKey(), is(equalTo("test-rest-key"))); - assertThat(retrievedRest.getRequest(), is(notNullValue())); - assertThat(retrievedRest.getResponse(), is(notNullValue())); - assertThat(retrievedRest.getHeaders(), is(notNullValue())); - assertThat(retrievedRest.getDimensions(), is(equalTo(384))); - - // Check Ollama embedder - Embedder retrievedOllama = updatedEmbedders.get("ollama"); - assertThat(retrievedOllama.getSource(), is(equalTo(EmbedderSource.OLLAMA))); - assertThat(retrievedOllama.getModel(), is(equalTo("llama2"))); - assertThat(retrievedOllama.getApiKey(), is(equalTo("test-ollama-key"))); - assertThat(retrievedOllama.getDimensions(), is(equalTo(4096))); - - // Check UserProvided embedder - Embedder retrievedUser = updatedEmbedders.get("user"); + assertThat(updatedEmbedders.size(), is(equalTo(1))); + Embedder retrievedUser = updatedEmbedders.get("custom"); assertThat(retrievedUser.getSource(), is(equalTo(EmbedderSource.USER_PROVIDED))); assertThat(retrievedUser.getDimensions(), is(equalTo(768))); } From b7b850613ccfefb2f87f543f22d8dcc925652ff8 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 16:36:49 +0800 Subject: [PATCH 19/41] Clean up tests --- .../meilisearch/integration/SettingsTest.java | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index d979d333..c6f343ad 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1482,20 +1482,18 @@ public void testGetEmbeddersSettings() throws Exception { @Test @DisplayName("Test update embedders settings") public void testUpdateEmbeddersSettings() throws Exception { - Index index = createIndex("testUpdateEmbeddersSettings"); - Map initialEmbedders = index.getEmbeddersSettings(); + Index index = createEmptyIndex("testUpdateEmbeddersSettings"); - // Create new embedders settings + // Update settings HashMap newEmbedders = new HashMap<>(); Embedder userProvidedEmbedder = new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); newEmbedders.put("custom", userProvidedEmbedder); - - // Update settings - index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); - Map updatedEmbedders = index.getEmbeddersSettings(); + TaskInfo task = index.updateEmbeddersSettings(newEmbedders); + index.waitForTask(task.getTaskUid()); // Verify results + Map updatedEmbedders = index.getEmbeddersSettings(); assertThat(updatedEmbedders.size(), is(equalTo(1))); Embedder retrievedUser = updatedEmbedders.get("custom"); assertThat(retrievedUser.getSource(), is(equalTo(EmbedderSource.USER_PROVIDED))); @@ -1505,28 +1503,24 @@ public void testUpdateEmbeddersSettings() throws Exception { @Test @DisplayName("Test reset embedders settings") public void testResetEmbeddersSettings() throws Exception { - Index index = createIndex("testResetEmbeddersSettings"); - Map initialEmbedders = index.getEmbeddersSettings(); - - // Create new embedders settings - Map newEmbedders = new HashMap<>(); - Embedder embedder = - new Embedder() - .setSource(EmbedderSource.OPEN_AI) - .setApiKey("test-api-key") - .setModel("text-embedding-ada-002") - .setDimensions(1536); - newEmbedders.put("test", embedder); + // Create and set new embedders + Index index = createEmptyIndex("testResetEmbeddersSettings"); + HashMap embedders = new HashMap<>(); + Embedder userProvidedEmbedder = + new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); + embedders.put("custom", userProvidedEmbedder); // Update settings - index.waitForTask(index.updateEmbeddersSettings(newEmbedders).getTaskUid()); + TaskInfo updateTask = index.updateEmbeddersSettings(embedders); + index.waitForTask(updateTask.getTaskUid()); Map updatedEmbedders = index.getEmbeddersSettings(); assertThat(updatedEmbedders.size(), is(equalTo(1))); - assertThat(updatedEmbedders.containsKey("test"), is(true)); + assertThat(updatedEmbedders.containsKey("custom"), is(true)); // Reset settings - index.waitForTask(index.resetEmbeddersSettings().getTaskUid()); + TaskInfo resetTask = index.resetEmbeddersSettings(); + index.waitForTask(resetTask.getTaskUid()); Map resetEmbedders = index.getEmbeddersSettings(); - assertThat(resetEmbedders.size(), is(equalTo(initialEmbedders.size()))); + assertThat(resetEmbedders.size(), is(equalTo(0))); } } From 3c53bcae3becc6498163c6b2c033b079efc81ed5 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 16:45:11 +0800 Subject: [PATCH 20/41] Lint --- src/test/java/com/meilisearch/integration/SettingsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index c6f343ad..10979242 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -17,7 +17,6 @@ import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; import com.meilisearch.sdk.model.Embedder; -import com.meilisearch.sdk.model.EmbedderDistribution; import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; From 6bb31060d473fd871f958985b74bec48d10d666d Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 18:50:33 +0800 Subject: [PATCH 21/41] Add vector search test --- .../com/meilisearch/sdk/SearchRequest.java | 5 ++-- .../meilisearch/integration/SearchTest.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 151a602c..23459aea 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -44,7 +44,7 @@ public class SearchRequest { protected String[] locales; protected String distinct; protected Hybrid hybrid; - + protected Double[] vector; /** * Constructor for SearchRequest for building search queries with the default values: offset: 0, * limit: 20, attributesToRetrieve: ["*"], attributesToCrop: null, cropLength: 200, @@ -106,7 +106,8 @@ public String toString() { .putOpt("showRankingScoreDetails", this.showRankingScoreDetails) .putOpt("rankingScoreThreshold", this.rankingScoreThreshold) .putOpt("locales", this.locales) - .putOpt("distinct", this.distinct); + .putOpt("distinct", this.distinct) + .putOpt("vector", this.vector); // Add hybrid parameter if it exists if (this.hybrid != null) { diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index 5d81a40d..dfd9f343 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -1116,6 +1116,36 @@ public void testSimilarDocuments() throws Exception { assertThat(hits.get(3).get("title"), is("Shazam!")); } + /** Test vector search */ + @Test + public void testVectorSearch() throws Exception { + String indexUid = "testVectorSearch"; + Index index = client.index(indexUid); + HashMap embedders = new HashMap<>(); + embedders.put( + "manual", new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(3)); + + Settings settings = new Settings(); + settings.setEmbedders(embedders); + + index.updateSettings(settings); + + TestData testData = this.getTestData(VECTOR_MOVIES, Movie.class); + TaskInfo task = index.addDocuments(testData.getRaw()); + + index.waitForTask(task.getTaskUid()); + + SearchRequest searchRequest = + SearchRequest.builder().vector(new Double[] {0.1, 0.6, 0.8}).build(); + + SearchResult searchResult = (SearchResult) index.search(searchRequest); + + assertThat(searchResult.getHits(), hasSize(5)); + // The most similar document should be "Escape Room" since its vector [0.1, 0.6, 0.8] + assertThat(searchResult.getHits().get(0).get("id"), is("522681")); + assertThat(searchResult.getHits().get(0).get("title"), is("Escape Room")); + } + /** Test Search with locales */ @Test public void testSearchWithLocales() throws Exception { From 9c76f88de611240bc5603e6170ff25a9bda4c1be Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 18 Mar 2025 19:00:16 +0800 Subject: [PATCH 22/41] Add hybrid --- src/test/java/com/meilisearch/integration/SearchTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index dfd9f343..67e82047 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -1136,7 +1136,10 @@ public void testVectorSearch() throws Exception { index.waitForTask(task.getTaskUid()); SearchRequest searchRequest = - SearchRequest.builder().vector(new Double[] {0.1, 0.6, 0.8}).build(); + SearchRequest.builder() + .vector(new Double[] {0.1, 0.6, 0.8}) + .hybrid(Hybrid.builder().semanticRatio(0.5).embedder("manual").build()) + .build(); SearchResult searchResult = (SearchResult) index.search(searchRequest); From 40fa2431e9b9e6daa640c499c266830ba39a5d13 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 8 Apr 2025 14:33:10 +0800 Subject: [PATCH 23/41] Fix tasks test --- .../com/meilisearch/integration/TasksTest.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/meilisearch/integration/TasksTest.java b/src/test/java/com/meilisearch/integration/TasksTest.java index 0eec58d1..2690c8d9 100644 --- a/src/test/java/com/meilisearch/integration/TasksTest.java +++ b/src/test/java/com/meilisearch/integration/TasksTest.java @@ -138,6 +138,22 @@ public void testClientGetTaskErrorWhenAddingDocuments() throws Exception { /** Test Get Tasks with limit and from */ @Test public void testClientGetTasksLimitAndFrom() throws Exception { + // Create several indexes to make sure we have enough tasks + String indexUid1 = "GetClientTasksLimitFrom1"; + String indexUid2 = "GetClientTasksLimitFrom2"; + String indexUid3 = "GetClientTasksLimitFrom3"; + String indexUid4 = "GetClientTasksLimitFrom4"; + + // Create indexes to generate tasks + TaskInfo response1 = client.createIndex(indexUid1); + client.waitForTask(response1.getTaskUid()); + TaskInfo response2 = client.createIndex(indexUid2); + client.waitForTask(response2.getTaskUid()); + TaskInfo response3 = client.createIndex(indexUid3); + client.waitForTask(response3.getTaskUid()); + TaskInfo response4 = client.createIndex(indexUid4); + client.waitForTask(response4.getTaskUid()); + int limit = 2; int from = 2; TasksQuery query = new TasksQuery().setLimit(limit).setFrom(from); @@ -147,7 +163,7 @@ public void testClientGetTasksLimitAndFrom() throws Exception { assertThat(result.getFrom(), is(equalTo(from))); assertThat(result.getFrom(), is(notNullValue())); assertThat(result.getNext(), is(notNullValue())); - assertThat(result.getResults().length, is(notNullValue())); + assertThat(result.getResults().length, is(equalTo(limit))); } /** Test Get Tasks with uid as filter */ From cefaf251ca5c4c26a8fc5622b4ac26fe34a28f9b Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 8 Apr 2025 14:45:50 +0800 Subject: [PATCH 24/41] Add retrieveVectors --- .../meilisearch/sdk/IndexSearchRequest.java | 6 ++- .../com/meilisearch/sdk/SearchRequest.java | 10 +++-- .../meilisearch/integration/SearchTest.java | 42 +++++++++++++++++++ .../meilisearch/sdk/SearchRequestTest.java | 10 +++++ 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java index 3ba8eef4..8e35ab3e 100644 --- a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java @@ -38,13 +38,14 @@ public class IndexSearchRequest { private FederationOptions federationOptions; protected String[] locales; protected String distinct; + protected Boolean retrieveVectors; /** * Constructor for MultiSearchRequest 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 - * distinct: null + * distinct: null, retrieveVectors: false * * @param indexUid uid of the requested index String */ @@ -106,7 +107,8 @@ public String toString() { .putOpt("rankingScoreThreshold", this.rankingScoreThreshold) .putOpt("attributesToSearchOn", this.attributesToSearchOn) .putOpt("locales", this.locales) - .putOpt("distinct", this.distinct); + .putOpt("distinct", this.distinct) + .putOpt("retrieveVectors", this.retrieveVectors); return jsonObject.toString(); } diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 23459aea..812a935b 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -45,11 +45,13 @@ public class SearchRequest { protected String distinct; protected Hybrid hybrid; protected Double[] vector; + protected Boolean retrieveVectors; /** * 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 + * null, showRankingScore: false, showRankingScoreDetails: false, rankingScoreThreshold: null, + * retrieveVectors: false * * @param q Query String */ @@ -107,11 +109,11 @@ public String toString() { .putOpt("rankingScoreThreshold", this.rankingScoreThreshold) .putOpt("locales", this.locales) .putOpt("distinct", this.distinct) - .putOpt("vector", this.vector); + .putOpt("vector", this.vector) + .putOpt("retrieveVectors", this.retrieveVectors); - // Add hybrid parameter if it exists if (this.hybrid != null) { - jsonObject.put("hybrid", this.hybrid.toJSONObject()); + jsonObject.put("hybrid", new JSONObject(this.hybrid.toString())); } return jsonObject.toString(); diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index 67e82047..e4c25da3 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -1149,6 +1149,48 @@ public void testVectorSearch() throws Exception { assertThat(searchResult.getHits().get(0).get("title"), is("Escape Room")); } + /** Test vector search with retrieveVectors option */ + @Test + public void testVectorSearchWithRetrieveVectors() throws Exception { + String indexUid = "testVectorSearchWithRetrieveVectors"; + Index index = client.index(indexUid); + HashMap embedders = new HashMap<>(); + embedders.put( + "manual", new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(3)); + + Settings settings = new Settings(); + settings.setEmbedders(embedders); + + index.updateSettings(settings); + + TestData testData = this.getTestData(VECTOR_MOVIES, Movie.class); + TaskInfo task = index.addDocuments(testData.getRaw()); + + index.waitForTask(task.getTaskUid()); + + SearchRequest searchRequest = + SearchRequest.builder() + .vector(new Double[] {0.1, 0.6, 0.8}) + .hybrid(Hybrid.builder().semanticRatio(0.5).embedder("manual").build()) + .retrieveVectors(true) + .build(); + + SearchResult searchResult = (SearchResult) index.search(searchRequest); + + assertThat(searchResult.getHits(), hasSize(5)); + // The most similar document should be "Escape Room" since its vector [0.1, 0.6, 0.8] + assertThat(searchResult.getHits().get(0).get("id"), is("522681")); + assertThat(searchResult.getHits().get(0).get("title"), is("Escape Room")); + + // Verify that vectors are returned in the response + Map escapeRoomHit = searchResult.getHits().get(0); + assertThat(escapeRoomHit.containsKey("_vectors"), is(true)); + + @SuppressWarnings("unchecked") + Map vectors = (Map) escapeRoomHit.get("_vectors"); + assertThat(vectors.containsKey("manual"), is(true)); + } + /** Test Search with locales */ @Test public void testSearchWithLocales() throws Exception { diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index ba350fed..dea8634d 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -8,6 +8,7 @@ import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; import org.junit.jupiter.api.Test; +import org.json.JSONObject; class SearchRequestTest { @@ -425,4 +426,13 @@ void toStringWithHybridOnlyEmbedder() { String expected = "{\"q\":\"This is a Test\",\"hybrid\":{\"embedder\":\"default\"}}"; assertThat(classToTest.toString(), is(equalTo(expected))); } + + @Test + void toStringWithRetrieveVectors() { + SearchRequest searchRequest = new SearchRequest("test") + .setRetrieveVectors(true); + String result = searchRequest.toString(); + JSONObject json = new JSONObject(result); + assertThat(json.getBoolean("retrieveVectors"), is(true)); + } } From 43063082cf58f8046271b83d061cdd18dc950564 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 8 Apr 2025 15:12:48 +0800 Subject: [PATCH 25/41] Spotless --- src/test/java/com/meilisearch/sdk/SearchRequestTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index dea8634d..ca004a30 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -7,8 +7,8 @@ import com.meilisearch.sdk.model.Hybrid; import com.meilisearch.sdk.model.MatchingStrategy; -import org.junit.jupiter.api.Test; import org.json.JSONObject; +import org.junit.jupiter.api.Test; class SearchRequestTest { @@ -429,8 +429,7 @@ void toStringWithHybridOnlyEmbedder() { @Test void toStringWithRetrieveVectors() { - SearchRequest searchRequest = new SearchRequest("test") - .setRetrieveVectors(true); + SearchRequest searchRequest = new SearchRequest("test").setRetrieveVectors(true); String result = searchRequest.toString(); JSONObject json = new JSONObject(result); assertThat(json.getBoolean("retrieveVectors"), is(true)); From b8b3c88acf33b6a3cbb02f0bff04863dc9dcf787 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 8 Apr 2025 15:52:18 +0800 Subject: [PATCH 26/41] Add check for optional _vectors --- .../meilisearch/sdk/model/SearchResult.java | 1 + .../meilisearch/integration/SearchTest.java | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/main/java/com/meilisearch/sdk/model/SearchResult.java b/src/main/java/com/meilisearch/sdk/model/SearchResult.java index a77f30a5..ef8c424a 100644 --- a/src/main/java/com/meilisearch/sdk/model/SearchResult.java +++ b/src/main/java/com/meilisearch/sdk/model/SearchResult.java @@ -22,6 +22,7 @@ public class SearchResult implements Searchable { int offset; int limit; int estimatedTotalHits; + HashMap _vectors; public SearchResult() {} } diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index e4c25da3..c89a752d 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -1266,4 +1266,45 @@ public void testMultiSearchWithLocales() throws Exception { assertThat(results[0].getHits().size(), is(7)); assertThat(results[1].getHits().size(), is(2)); } + + /** Test search with retrieveVectors parameter */ + @Test + public void testSearchWithRetrieveVectors() throws Exception { + String indexUid = "testSearchWithRetrieveVectors"; + Index index = client.index(indexUid); + HashMap embedders = new HashMap<>(); + embedders.put( + "manual", new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(3)); + + Settings settings = new Settings(); + settings.setEmbedders(embedders); + + index.updateSettings(settings); + + TestData testData = this.getTestData(VECTOR_MOVIES, Movie.class); + TaskInfo task = index.addDocuments(testData.getRaw()); + + index.waitForTask(task.getTaskUid()); + + // First search without retrieveVectors + SearchRequest searchRequestWithout = SearchRequest.builder().q("").build(); + SearchResult searchResultWithout = (SearchResult) index.search(searchRequestWithout); + + assertThat(searchResultWithout.getHits(), hasSize(5)); + Map hitWithout = searchResultWithout.getHits().get(0); + assertThat(hitWithout.containsKey("_vectors"), is(false)); + + // Then search with retrieveVectors + SearchRequest searchRequestWith = + SearchRequest.builder().q("").retrieveVectors(true).build(); + SearchResult searchResultWith = (SearchResult) index.search(searchRequestWith); + + assertThat(searchResultWith.getHits(), hasSize(5)); + Map hitWith = searchResultWith.getHits().get(0); + assertThat(hitWith.containsKey("_vectors"), is(true)); + + @SuppressWarnings("unchecked") + Map vectors = (Map) hitWith.get("_vectors"); + assertThat(vectors.containsKey("manual"), is(true)); + } } From 22482fbf0aef9645abdc0c36884de7e59932c700 Mon Sep 17 00:00:00 2001 From: Strift Date: Tue, 8 Apr 2025 17:19:36 +0800 Subject: [PATCH 27/41] Add tests for similar documents --- .../sdk/SimilarDocumentRequest.java | 23 ++- .../sdk/SimilarDocumentRequestTest.java | 184 ++++++++++++++++++ 2 files changed, 195 insertions(+), 12 deletions(-) create mode 100644 src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java diff --git a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java index 99ad5f46..a8dc1191 100644 --- a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java +++ b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java @@ -31,18 +31,17 @@ public SimilarDocumentRequest() {} @Override public String toString() { - JSONObject jsonObject = - new JSONObject() - .put("id", this.id) - .put("embedder", this.embedder) - .put("attributesToRetrieve", this.attributesToRetrieve) - .put("offset", this.offset) - .put("limit", this.limit) - .put("filter", this.filter) - .put("showRankingScore", this.showRankingScore) - .put("showRankingScoreDetails", this.showRankingScoreDetails) - .put("rankingScoreThreshold", this.rankingScoreThreshold) - .put("retrieveVectors", this.retrieveVectors); + JSONObject jsonObject = new JSONObject(); + jsonObject.putOpt("id", this.id); + jsonObject.putOpt("embedder", this.embedder); + jsonObject.putOpt("attributesToRetrieve", this.attributesToRetrieve); + jsonObject.putOpt("offset", this.offset); + jsonObject.putOpt("limit", this.limit); + jsonObject.putOpt("filter", this.filter); + jsonObject.putOpt("showRankingScore", this.showRankingScore); + jsonObject.putOpt("showRankingScoreDetails", this.showRankingScoreDetails); + jsonObject.putOpt("rankingScoreThreshold", this.rankingScoreThreshold); + jsonObject.putOpt("retrieveVectors", this.retrieveVectors); return jsonObject.toString(); } diff --git a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java new file mode 100644 index 00000000..52435b82 --- /dev/null +++ b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java @@ -0,0 +1,184 @@ +package com.meilisearch.sdk; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +import org.json.JSONObject; +import org.junit.jupiter.api.Test; + +class SimilarDocumentRequestTest { + + @Test + void toStringSimpleRequest() { + SimilarDocumentRequest classToTest = new SimilarDocumentRequest().setId("123"); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + } + + @Test + void toStringWithEmbedder() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setEmbedder("custom"); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getString("embedder"), is(equalTo("custom"))); + } + + @Test + void toStringWithAttributesToRetrieve() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest() + .setId("123") + .setAttributesToRetrieve(new String[] {"title", "description"}); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat( + jsonObject.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); + assertThat( + jsonObject.getJSONArray("attributesToRetrieve").getString(1), + is(equalTo("description"))); + } + + @Test + void toStringWithOffsetAndLimit() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setOffset(10).setLimit(20); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getInt("offset"), is(equalTo(10))); + assertThat(jsonObject.getInt("limit"), is(equalTo(20))); + } + + @Test + void toStringWithFilter() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setFilter("genre = 'action'"); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getString("filter"), is(equalTo("genre = 'action'"))); + } + + @Test + void toStringWithShowRankingScore() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setShowRankingScore(true); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getBoolean("showRankingScore"), is(equalTo(true))); + } + + @Test + void toStringWithShowRankingScoreDetails() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setShowRankingScoreDetails(true); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getBoolean("showRankingScoreDetails"), is(equalTo(true))); + } + + @Test + void toStringWithRankingScoreThreshold() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setRankingScoreThreshold(0.5); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getDouble("rankingScoreThreshold"), is(equalTo(0.5))); + } + + @Test + void toStringWithRetrieveVectors() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest().setId("123").setRetrieveVectors(true); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getBoolean("retrieveVectors"), is(equalTo(true))); + } + + @Test + void toStringWithAllParameters() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest() + .setId("123") + .setEmbedder("custom") + .setAttributesToRetrieve(new String[] {"title", "description"}) + .setOffset(10) + .setLimit(20) + .setFilter("genre = 'action'") + .setShowRankingScore(true) + .setShowRankingScoreDetails(true) + .setRankingScoreThreshold(0.5) + .setRetrieveVectors(true); + + JSONObject jsonObject = new JSONObject(classToTest.toString()); + assertThat(jsonObject.getString("id"), is(equalTo("123"))); + assertThat(jsonObject.getString("embedder"), is(equalTo("custom"))); + assertThat( + jsonObject.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); + assertThat( + jsonObject.getJSONArray("attributesToRetrieve").getString(1), + is(equalTo("description"))); + assertThat(jsonObject.getInt("offset"), is(equalTo(10))); + assertThat(jsonObject.getInt("limit"), is(equalTo(20))); + assertThat(jsonObject.getString("filter"), is(equalTo("genre = 'action'"))); + assertThat(jsonObject.getBoolean("showRankingScore"), is(equalTo(true))); + assertThat(jsonObject.getBoolean("showRankingScoreDetails"), is(equalTo(true))); + assertThat(jsonObject.getDouble("rankingScoreThreshold"), is(equalTo(0.5))); + assertThat(jsonObject.getBoolean("retrieveVectors"), is(equalTo(true))); + } + + @Test + void gettersAndSetters() { + SimilarDocumentRequest classToTest = + new SimilarDocumentRequest() + .setId("123") + .setEmbedder("custom") + .setAttributesToRetrieve(new String[] {"title", "description"}) + .setOffset(10) + .setLimit(20) + .setFilter("genre = 'action'") + .setShowRankingScore(true) + .setShowRankingScoreDetails(true) + .setRankingScoreThreshold(0.5) + .setRetrieveVectors(true); + + assertThat(classToTest.getId(), is(equalTo("123"))); + assertThat(classToTest.getEmbedder(), is(equalTo("custom"))); + assertThat( + classToTest.getAttributesToRetrieve(), + is(equalTo(new String[] {"title", "description"}))); + assertThat(classToTest.getOffset(), is(equalTo(10))); + assertThat(classToTest.getLimit(), is(equalTo(20))); + assertThat(classToTest.getFilter(), is(equalTo("genre = 'action'"))); + assertThat(classToTest.getShowRankingScore(), is(equalTo(true))); + assertThat(classToTest.getShowRankingScoreDetails(), is(equalTo(true))); + assertThat(classToTest.getRankingScoreThreshold(), is(equalTo(0.5))); + assertThat(classToTest.getRetrieveVectors(), is(equalTo(true))); + } + + @Test + void defaultValues() { + SimilarDocumentRequest classToTest = new SimilarDocumentRequest(); + + assertThat(classToTest.getId(), is(nullValue())); + assertThat(classToTest.getEmbedder(), is(nullValue())); + assertThat(classToTest.getAttributesToRetrieve(), is(nullValue())); + assertThat(classToTest.getOffset(), is(nullValue())); + assertThat(classToTest.getLimit(), is(nullValue())); + assertThat(classToTest.getFilter(), is(nullValue())); + assertThat(classToTest.getShowRankingScore(), is(nullValue())); + assertThat(classToTest.getShowRankingScoreDetails(), is(nullValue())); + assertThat(classToTest.getRankingScoreThreshold(), is(nullValue())); + assertThat(classToTest.getRetrieveVectors(), is(nullValue())); + } +} From 35d1ec73be6c40bdb23eb461f656c5e58f47e288 Mon Sep 17 00:00:00 2001 From: Laurent Cazanove Date: Thu, 24 Apr 2025 08:23:23 +0200 Subject: [PATCH 28/41] Update src/main/java/com/meilisearch/sdk/SearchRequest.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/main/java/com/meilisearch/sdk/SearchRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 812a935b..43e043cc 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -113,7 +113,7 @@ public String toString() { .putOpt("retrieveVectors", this.retrieveVectors); if (this.hybrid != null) { - jsonObject.put("hybrid", new JSONObject(this.hybrid.toString())); + jsonObject.put("hybrid", this.hybrid.toJSONObject()); } return jsonObject.toString(); From 93c73f59bfb554788ca73c2e90053fb79bc3530e Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 24 Apr 2025 14:15:50 +0800 Subject: [PATCH 29/41] Add javadoc --- src/main/java/com/meilisearch/sdk/Index.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/meilisearch/sdk/Index.java b/src/main/java/com/meilisearch/sdk/Index.java index 828fbe68..ab5244ce 100644 --- a/src/main/java/com/meilisearch/sdk/Index.java +++ b/src/main/java/com/meilisearch/sdk/Index.java @@ -1242,6 +1242,15 @@ public TaskInfo resetSearchCutoffMsSettings() throws MeilisearchException { return this.settingsHandler.resetSearchCutoffMsSettings(this.uid); } + /** + * Retrieves documents that are semantically similar to a given document + * + * @param query SimilarDocumentRequest containing parameters for the similar documents search + * @return SimilarDocumentsResults containing the search results + * @throws MeilisearchException if an error occurs + * @see API + * specification + */ public SimilarDocumentsResults searchSimilarDocuments(SimilarDocumentRequest query) throws MeilisearchException { return this.config.httpClient.post( From 875d73d06a2ec48a0ac48c2b6eed08b9a8014f83 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:03:27 +0800 Subject: [PATCH 30/41] Remove unnecessary test --- .../com/meilisearch/sdk/SearchRequestTest.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index ca004a30..e32ecd9f 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -366,21 +366,6 @@ void toStringEveryParametersWithArrayMatchingStrategyNull() { assertThat(classToTest.toString(), is(equalTo(expectedToString))); } - @Test - void toStringWithHybrid() { - Hybrid hybrid = Hybrid.builder().semanticRatio(0.5).embedder("default").build(); - - SearchRequest classToTest = new SearchRequest("This is a Test").setHybrid(hybrid); - - String expected = - "{\"q\":\"This is a Test\",\"hybrid\":{\"semanticRatio\":0.5,\"embedder\":\"default\"}}"; - assertThat(classToTest.toString(), is(equalTo(expected))); - - // Verify getters - assertThat(classToTest.getHybrid().getSemanticRatio(), is(equalTo(0.5))); - assertThat(classToTest.getHybrid().getEmbedder(), is(equalTo("default"))); - } - @Test void toStringWithHybridUsingBuilder() { SearchRequest classToTest = From fc83d3d1fba2f82e4183d5bdda7587b33cc93e8d Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:14:34 +0800 Subject: [PATCH 31/41] Replace repetitive code by loop --- .../meilisearch/integration/TasksTest.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/TasksTest.java b/src/test/java/com/meilisearch/integration/TasksTest.java index 2690c8d9..391b57ca 100644 --- a/src/test/java/com/meilisearch/integration/TasksTest.java +++ b/src/test/java/com/meilisearch/integration/TasksTest.java @@ -139,20 +139,11 @@ public void testClientGetTaskErrorWhenAddingDocuments() throws Exception { @Test public void testClientGetTasksLimitAndFrom() throws Exception { // Create several indexes to make sure we have enough tasks - String indexUid1 = "GetClientTasksLimitFrom1"; - String indexUid2 = "GetClientTasksLimitFrom2"; - String indexUid3 = "GetClientTasksLimitFrom3"; - String indexUid4 = "GetClientTasksLimitFrom4"; - - // Create indexes to generate tasks - TaskInfo response1 = client.createIndex(indexUid1); - client.waitForTask(response1.getTaskUid()); - TaskInfo response2 = client.createIndex(indexUid2); - client.waitForTask(response2.getTaskUid()); - TaskInfo response3 = client.createIndex(indexUid3); - client.waitForTask(response3.getTaskUid()); - TaskInfo response4 = client.createIndex(indexUid4); - client.waitForTask(response4.getTaskUid()); + int numIndexes = 4; + for (int i = 1; i <= numIndexes; i++) { + String indexUid = "GetClientTasksLimitFrom" + i; + TaskInfo response = client.createIndex(indexUid); + } int limit = 2; int from = 2; From 44adc3fac61e0c1f5144a451ec4f714986ecbb30 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:15:45 +0800 Subject: [PATCH 32/41] Add comment on annotations --- src/main/java/com/meilisearch/sdk/model/Hybrid.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/meilisearch/sdk/model/Hybrid.java b/src/main/java/com/meilisearch/sdk/model/Hybrid.java index 62cdd1bb..1f561149 100644 --- a/src/main/java/com/meilisearch/sdk/model/Hybrid.java +++ b/src/main/java/com/meilisearch/sdk/model/Hybrid.java @@ -1,5 +1,6 @@ package com.meilisearch.sdk.model; +// @brunoocasali: I don't think we should use the fasterxml.jackson annotations across the library, since this should be customizable 🤔 import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AccessLevel; import lombok.AllArgsConstructor; From b923f5e37f49a172afd72ccbea8534a8ae2f73fc Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:21:10 +0800 Subject: [PATCH 33/41] id and embedder are not optional fields --- src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java index a8dc1191..7d6a7f7a 100644 --- a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java +++ b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java @@ -32,8 +32,8 @@ public SimilarDocumentRequest() {} @Override public String toString() { JSONObject jsonObject = new JSONObject(); - jsonObject.putOpt("id", this.id); - jsonObject.putOpt("embedder", this.embedder); + jsonObject.put("id", this.id); + jsonObject.put("embedder", this.embedder); jsonObject.putOpt("attributesToRetrieve", this.attributesToRetrieve); jsonObject.putOpt("offset", this.offset); jsonObject.putOpt("limit", this.limit); From f873afebe2527be8860bfa3e43d5ca0c77727eb1 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:22:42 +0800 Subject: [PATCH 34/41] Remove unnecessary tests --- .../sdk/SimilarDocumentRequestTest.java | 225 +++++------------- 1 file changed, 63 insertions(+), 162 deletions(-) diff --git a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java index 52435b82..19cb8292 100644 --- a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java @@ -11,174 +11,75 @@ class SimilarDocumentRequestTest { @Test - void toStringSimpleRequest() { - SimilarDocumentRequest classToTest = new SimilarDocumentRequest().setId("123"); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - } - - @Test - void toStringWithEmbedder() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setEmbedder("custom"); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getString("embedder"), is(equalTo("custom"))); - } - - @Test - void toStringWithAttributesToRetrieve() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest() - .setId("123") - .setAttributesToRetrieve(new String[] {"title", "description"}); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat( - jsonObject.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); - assertThat( - jsonObject.getJSONArray("attributesToRetrieve").getString(1), - is(equalTo("description"))); - } - - @Test - void toStringWithOffsetAndLimit() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setOffset(10).setLimit(20); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getInt("offset"), is(equalTo(10))); - assertThat(jsonObject.getInt("limit"), is(equalTo(20))); - } - - @Test - void toStringWithFilter() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setFilter("genre = 'action'"); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getString("filter"), is(equalTo("genre = 'action'"))); + void toStringDefaultValues() { + SimilarDocumentRequest request = new SimilarDocumentRequest(); + JSONObject json = new JSONObject(request.toString()); + + // only id and embedder should be absent (null) by default + assertThat(json.has("id"), is(false)); + assertThat(json.has("embedder"), is(false)); + assertThat(json.has("attributesToRetrieve"), is(false)); + assertThat(json.has("offset"), is(false)); + assertThat(json.has("limit"), is(false)); + assertThat(json.has("filter"), is(false)); + assertThat(json.has("showRankingScore"), is(false)); + assertThat(json.has("showRankingScoreDetails"), is(false)); + assertThat(json.has("rankingScoreThreshold"), is(false)); + assertThat(json.has("retrieveVectors"), is(false)); } @Test - void toStringWithShowRankingScore() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setShowRankingScore(true); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getBoolean("showRankingScore"), is(equalTo(true))); - } - - @Test - void toStringWithShowRankingScoreDetails() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setShowRankingScoreDetails(true); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getBoolean("showRankingScoreDetails"), is(equalTo(true))); - } - - @Test - void toStringWithRankingScoreThreshold() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setRankingScoreThreshold(0.5); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getDouble("rankingScoreThreshold"), is(equalTo(0.5))); - } - - @Test - void toStringWithRetrieveVectors() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest().setId("123").setRetrieveVectors(true); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getBoolean("retrieveVectors"), is(equalTo(true))); - } - - @Test - void toStringWithAllParameters() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest() - .setId("123") - .setEmbedder("custom") - .setAttributesToRetrieve(new String[] {"title", "description"}) - .setOffset(10) - .setLimit(20) - .setFilter("genre = 'action'") - .setShowRankingScore(true) - .setShowRankingScoreDetails(true) - .setRankingScoreThreshold(0.5) - .setRetrieveVectors(true); - - JSONObject jsonObject = new JSONObject(classToTest.toString()); - assertThat(jsonObject.getString("id"), is(equalTo("123"))); - assertThat(jsonObject.getString("embedder"), is(equalTo("custom"))); - assertThat( - jsonObject.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); - assertThat( - jsonObject.getJSONArray("attributesToRetrieve").getString(1), - is(equalTo("description"))); - assertThat(jsonObject.getInt("offset"), is(equalTo(10))); - assertThat(jsonObject.getInt("limit"), is(equalTo(20))); - assertThat(jsonObject.getString("filter"), is(equalTo("genre = 'action'"))); - assertThat(jsonObject.getBoolean("showRankingScore"), is(equalTo(true))); - assertThat(jsonObject.getBoolean("showRankingScoreDetails"), is(equalTo(true))); - assertThat(jsonObject.getDouble("rankingScoreThreshold"), is(equalTo(0.5))); - assertThat(jsonObject.getBoolean("retrieveVectors"), is(equalTo(true))); + void toStringAllParameters() { + SimilarDocumentRequest request = new SimilarDocumentRequest() + .setId("123") + .setEmbedder("custom") + .setAttributesToRetrieve(new String[]{"title", "description"}) + .setOffset(10) + .setLimit(20) + .setFilter("genre = 'action'") + .setShowRankingScore(true) + .setShowRankingScoreDetails(true) + .setRankingScoreThreshold(0.5) + .setRetrieveVectors(true); + + JSONObject json = new JSONObject(request.toString()); + assertThat(json.getString("id"), is(equalTo("123"))); + assertThat(json.getString("embedder"), is(equalTo("custom"))); + assertThat(json.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); + assertThat(json.getJSONArray("attributesToRetrieve").getString(1), is(equalTo("description"))); + assertThat(json.getInt("offset"), is(equalTo(10))); + assertThat(json.getInt("limit"), is(equalTo(20))); + assertThat(json.getString("filter"), is(equalTo("genre = 'action'"))); + assertThat(json.getBoolean("showRankingScore"), is(equalTo(true))); + assertThat(json.getBoolean("showRankingScoreDetails"), is(equalTo(true))); + assertThat(json.getDouble("rankingScoreThreshold"), is(equalTo(0.5))); + assertThat(json.getBoolean("retrieveVectors"), is(equalTo(true))); } @Test void gettersAndSetters() { - SimilarDocumentRequest classToTest = - new SimilarDocumentRequest() - .setId("123") - .setEmbedder("custom") - .setAttributesToRetrieve(new String[] {"title", "description"}) - .setOffset(10) - .setLimit(20) - .setFilter("genre = 'action'") - .setShowRankingScore(true) - .setShowRankingScoreDetails(true) - .setRankingScoreThreshold(0.5) - .setRetrieveVectors(true); - - assertThat(classToTest.getId(), is(equalTo("123"))); - assertThat(classToTest.getEmbedder(), is(equalTo("custom"))); - assertThat( - classToTest.getAttributesToRetrieve(), - is(equalTo(new String[] {"title", "description"}))); - assertThat(classToTest.getOffset(), is(equalTo(10))); - assertThat(classToTest.getLimit(), is(equalTo(20))); - assertThat(classToTest.getFilter(), is(equalTo("genre = 'action'"))); - assertThat(classToTest.getShowRankingScore(), is(equalTo(true))); - assertThat(classToTest.getShowRankingScoreDetails(), is(equalTo(true))); - assertThat(classToTest.getRankingScoreThreshold(), is(equalTo(0.5))); - assertThat(classToTest.getRetrieveVectors(), is(equalTo(true))); - } - - @Test - void defaultValues() { - SimilarDocumentRequest classToTest = new SimilarDocumentRequest(); - - assertThat(classToTest.getId(), is(nullValue())); - assertThat(classToTest.getEmbedder(), is(nullValue())); - assertThat(classToTest.getAttributesToRetrieve(), is(nullValue())); - assertThat(classToTest.getOffset(), is(nullValue())); - assertThat(classToTest.getLimit(), is(nullValue())); - assertThat(classToTest.getFilter(), is(nullValue())); - assertThat(classToTest.getShowRankingScore(), is(nullValue())); - assertThat(classToTest.getShowRankingScoreDetails(), is(nullValue())); - assertThat(classToTest.getRankingScoreThreshold(), is(nullValue())); - assertThat(classToTest.getRetrieveVectors(), is(nullValue())); + SimilarDocumentRequest request = SimilarDocumentRequest.builder() + .id("123") + .embedder("custom") + .attributesToRetrieve(new String[]{"title", "description"}) + .offset(10) + .limit(20) + .filter("genre = 'action'") + .showRankingScore(true) + .showRankingScoreDetails(true) + .rankingScoreThreshold(0.5) + .retrieveVectors(true) + .build(); + + assertThat(request.getId(), is(equalTo("123"))); + assertThat(request.getEmbedder(), is(equalTo("custom"))); + assertThat(request.getAttributesToRetrieve(), is(equalTo(new String[]{"title", "description"}))); + assertThat(request.getOffset(), is(equalTo(10))); + assertThat(request.getLimit(), is(equalTo(20))); + assertThat(request.getFilter(), is(equalTo("genre = 'action'"))); + assertThat(request.getShowRankingScore(), is(equalTo(true))); + assertThat(request.getShowRankingScoreDetails(), is(equalTo(true))); + assertThat(request.getRankingScoreThreshold(), is(equalTo(0.5))); + assertThat(request.getRetrieveVectors(), is(equalTo(true))); } } From af662a0e8551227166b5caee311c5dcc503eee4b Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:29:02 +0800 Subject: [PATCH 35/41] Lint --- src/main/java/com/meilisearch/sdk/Index.java | 3 +-- src/main/java/com/meilisearch/sdk/model/Hybrid.java | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/Index.java b/src/main/java/com/meilisearch/sdk/Index.java index ab5244ce..1eb01bec 100644 --- a/src/main/java/com/meilisearch/sdk/Index.java +++ b/src/main/java/com/meilisearch/sdk/Index.java @@ -1248,8 +1248,7 @@ public TaskInfo resetSearchCutoffMsSettings() throws MeilisearchException { * @param query SimilarDocumentRequest containing parameters for the similar documents search * @return SimilarDocumentsResults containing the search results * @throws MeilisearchException if an error occurs - * @see API - * specification + * @see API specification */ public SimilarDocumentsResults searchSimilarDocuments(SimilarDocumentRequest query) throws MeilisearchException { diff --git a/src/main/java/com/meilisearch/sdk/model/Hybrid.java b/src/main/java/com/meilisearch/sdk/model/Hybrid.java index 1f561149..a95d0ec0 100644 --- a/src/main/java/com/meilisearch/sdk/model/Hybrid.java +++ b/src/main/java/com/meilisearch/sdk/model/Hybrid.java @@ -1,6 +1,7 @@ package com.meilisearch.sdk.model; -// @brunoocasali: I don't think we should use the fasterxml.jackson annotations across the library, since this should be customizable 🤔 +// @brunoocasali: I don't think we should use the fasterxml.jackson annotations across the library, +// since this should be customizable 🤔 import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AccessLevel; import lombok.AllArgsConstructor; From 8cef5d310a0c9ecd3d026f946df3d5e069178e82 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:30:10 +0800 Subject: [PATCH 36/41] Lint --- .../sdk/SimilarDocumentRequestTest.java | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java index 19cb8292..b583700a 100644 --- a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java @@ -30,23 +30,25 @@ void toStringDefaultValues() { @Test void toStringAllParameters() { - SimilarDocumentRequest request = new SimilarDocumentRequest() - .setId("123") - .setEmbedder("custom") - .setAttributesToRetrieve(new String[]{"title", "description"}) - .setOffset(10) - .setLimit(20) - .setFilter("genre = 'action'") - .setShowRankingScore(true) - .setShowRankingScoreDetails(true) - .setRankingScoreThreshold(0.5) - .setRetrieveVectors(true); + SimilarDocumentRequest request = + new SimilarDocumentRequest() + .setId("123") + .setEmbedder("custom") + .setAttributesToRetrieve(new String[]{"title", "description"}) + .setOffset(10) + .setLimit(20) + .setFilter("genre = 'action'") + .setShowRankingScore(true) + .setShowRankingScoreDetails(true) + .setRankingScoreThreshold(0.5) + .setRetrieveVectors(true); JSONObject json = new JSONObject(request.toString()); assertThat(json.getString("id"), is(equalTo("123"))); assertThat(json.getString("embedder"), is(equalTo("custom"))); assertThat(json.getJSONArray("attributesToRetrieve").getString(0), is(equalTo("title"))); - assertThat(json.getJSONArray("attributesToRetrieve").getString(1), is(equalTo("description"))); + assertThat( + json.getJSONArray("attributesToRetrieve").getString(1), is(equalTo("description"))); assertThat(json.getInt("offset"), is(equalTo(10))); assertThat(json.getInt("limit"), is(equalTo(20))); assertThat(json.getString("filter"), is(equalTo("genre = 'action'"))); @@ -58,22 +60,25 @@ void toStringAllParameters() { @Test void gettersAndSetters() { - SimilarDocumentRequest request = SimilarDocumentRequest.builder() - .id("123") - .embedder("custom") - .attributesToRetrieve(new String[]{"title", "description"}) - .offset(10) - .limit(20) - .filter("genre = 'action'") - .showRankingScore(true) - .showRankingScoreDetails(true) - .rankingScoreThreshold(0.5) - .retrieveVectors(true) - .build(); + SimilarDocumentRequest request = + SimilarDocumentRequest.builder() + .id("123") + .embedder("custom") + .attributesToRetrieve(new String[]{"title", "description"}) + .offset(10) + .limit(20) + .filter("genre = 'action'") + .showRankingScore(true) + .showRankingScoreDetails(true) + .rankingScoreThreshold(0.5) + .retrieveVectors(true) + .build(); assertThat(request.getId(), is(equalTo("123"))); assertThat(request.getEmbedder(), is(equalTo("custom"))); - assertThat(request.getAttributesToRetrieve(), is(equalTo(new String[]{"title", "description"}))); + assertThat( + request.getAttributesToRetrieve(), + is(equalTo(new String[]{"title", "description"}))); assertThat(request.getOffset(), is(equalTo(10))); assertThat(request.getLimit(), is(equalTo(20))); assertThat(request.getFilter(), is(equalTo("genre = 'action'"))); From f0841696d9a3b3d346fd0091d17f591ce6defd75 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:32:14 +0800 Subject: [PATCH 37/41] Lint --- .../com/meilisearch/sdk/SimilarDocumentRequestTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java index b583700a..7c649d69 100644 --- a/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SimilarDocumentRequestTest.java @@ -3,7 +3,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -34,7 +33,7 @@ void toStringAllParameters() { new SimilarDocumentRequest() .setId("123") .setEmbedder("custom") - .setAttributesToRetrieve(new String[]{"title", "description"}) + .setAttributesToRetrieve(new String[] {"title", "description"}) .setOffset(10) .setLimit(20) .setFilter("genre = 'action'") @@ -64,7 +63,7 @@ void gettersAndSetters() { SimilarDocumentRequest.builder() .id("123") .embedder("custom") - .attributesToRetrieve(new String[]{"title", "description"}) + .attributesToRetrieve(new String[] {"title", "description"}) .offset(10) .limit(20) .filter("genre = 'action'") @@ -78,7 +77,7 @@ void gettersAndSetters() { assertThat(request.getEmbedder(), is(equalTo("custom"))); assertThat( request.getAttributesToRetrieve(), - is(equalTo(new String[]{"title", "description"}))); + is(equalTo(new String[] {"title", "description"}))); assertThat(request.getOffset(), is(equalTo(10))); assertThat(request.getLimit(), is(equalTo(20))); assertThat(request.getFilter(), is(equalTo("genre = 'action'"))); From 75c7d742fe38c9bb70fb4e7d4ccf7e58a9b18c4b Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 13:47:50 +0800 Subject: [PATCH 38/41] Use createIndex instead of createEmptyIndex --- src/test/java/com/meilisearch/integration/SettingsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 10979242..93b4506a 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -1481,7 +1481,7 @@ public void testGetEmbeddersSettings() throws Exception { @Test @DisplayName("Test update embedders settings") public void testUpdateEmbeddersSettings() throws Exception { - Index index = createEmptyIndex("testUpdateEmbeddersSettings"); + Index index = createIndex("testUpdateEmbeddersSettings"); // Update settings HashMap newEmbedders = new HashMap<>(); @@ -1503,7 +1503,7 @@ public void testUpdateEmbeddersSettings() throws Exception { @DisplayName("Test reset embedders settings") public void testResetEmbeddersSettings() throws Exception { // Create and set new embedders - Index index = createEmptyIndex("testResetEmbeddersSettings"); + Index index = createIndex("testResetEmbeddersSettings"); HashMap embedders = new HashMap<>(); Embedder userProvidedEmbedder = new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); From 10701eee3f9ba1ba78cb4e1cab0f0d62dade45a3 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 15 May 2025 14:00:28 +0800 Subject: [PATCH 39/41] Remove comment --- src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java index 7d6a7f7a..2d01d464 100644 --- a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java +++ b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java @@ -23,9 +23,6 @@ public class SimilarDocumentRequest { /** * Constructor for SimilarDocumentsRequest for building search request for similar documents - * with the default values: id null, embedder "default", attributesToRetrieve ["*"], offset 0, - * limit 20, filter null, showRankingScore false, showRankingScoreDetails false, - * rankingScoreThreshold null, retrieveVectors false */ public SimilarDocumentRequest() {} From 5a29190f296269fa16c145c9e31e36bcace81ccf Mon Sep 17 00:00:00 2001 From: Strift Date: Wed, 21 May 2025 14:18:11 +0800 Subject: [PATCH 40/41] lint --- src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java index 2d01d464..0e9c869c 100644 --- a/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java +++ b/src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java @@ -21,9 +21,7 @@ public class SimilarDocumentRequest { private Double rankingScoreThreshold; private Boolean retrieveVectors; - /** - * Constructor for SimilarDocumentsRequest for building search request for similar documents - */ + /** Constructor for SimilarDocumentsRequest for building search request for similar documents */ public SimilarDocumentRequest() {} @Override From 9272e767239ae760873c0afcb52b8c3debccb949 Mon Sep 17 00:00:00 2001 From: Strift Date: Thu, 5 Jun 2025 13:17:25 +0800 Subject: [PATCH 41/41] Update tests to use empty index --- .../meilisearch/integration/SettingsTest.java | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/meilisearch/integration/SettingsTest.java b/src/test/java/com/meilisearch/integration/SettingsTest.java index 93b4506a..a8dbbbe0 100644 --- a/src/test/java/com/meilisearch/integration/SettingsTest.java +++ b/src/test/java/com/meilisearch/integration/SettingsTest.java @@ -17,6 +17,7 @@ import com.meilisearch.integration.classes.TestData; import com.meilisearch.sdk.Index; import com.meilisearch.sdk.model.Embedder; +import com.meilisearch.sdk.model.EmbedderDistribution; import com.meilisearch.sdk.model.EmbedderSource; import com.meilisearch.sdk.model.FacetSortValue; import com.meilisearch.sdk.model.Faceting; @@ -1478,45 +1479,55 @@ public void testGetEmbeddersSettings() throws Exception { assertThat(initialEmbedders, is(equalTo(initialSettings.getEmbedders()))); } + public Embedder createUserProvidedEmbedder() { + return Embedder.builder() + .source(EmbedderSource.USER_PROVIDED) + .dimensions(1) + .distribution(EmbedderDistribution.builder().mean(0.7).sigma(0.3).build()) + .binaryQuantized(false) + .build(); + } + @Test @DisplayName("Test update embedders settings") public void testUpdateEmbeddersSettings() throws Exception { - Index index = createIndex("testUpdateEmbeddersSettings"); + Index index = createEmptyIndex("testUpdateEmbeddersSettings"); - // Update settings HashMap newEmbedders = new HashMap<>(); - Embedder userProvidedEmbedder = - new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); - newEmbedders.put("custom", userProvidedEmbedder); + Embedder embedder = createUserProvidedEmbedder(); + newEmbedders.put("default", embedder); TaskInfo task = index.updateEmbeddersSettings(newEmbedders); index.waitForTask(task.getTaskUid()); - // Verify results Map updatedEmbedders = index.getEmbeddersSettings(); assertThat(updatedEmbedders.size(), is(equalTo(1))); - Embedder retrievedUser = updatedEmbedders.get("custom"); - assertThat(retrievedUser.getSource(), is(equalTo(EmbedderSource.USER_PROVIDED))); - assertThat(retrievedUser.getDimensions(), is(equalTo(768))); + Embedder retrievedEmbedder = updatedEmbedders.get("default"); + assertThat(retrievedEmbedder.getSource(), is(equalTo(embedder.getSource()))); + assertThat(retrievedEmbedder.getDimensions(), is(equalTo(embedder.getDimensions()))); + assertThat( + retrievedEmbedder.getDistribution().getMean(), + is(equalTo(embedder.getDistribution().getMean()))); + assertThat( + retrievedEmbedder.getDistribution().getSigma(), + is(equalTo(embedder.getDistribution().getSigma()))); + assertThat( + retrievedEmbedder.getBinaryQuantized(), is(equalTo(embedder.getBinaryQuantized()))); } @Test @DisplayName("Test reset embedders settings") public void testResetEmbeddersSettings() throws Exception { - // Create and set new embedders - Index index = createIndex("testResetEmbeddersSettings"); - HashMap embedders = new HashMap<>(); - Embedder userProvidedEmbedder = - new Embedder().setSource(EmbedderSource.USER_PROVIDED).setDimensions(768); - embedders.put("custom", userProvidedEmbedder); + Index index = createEmptyIndex("testResetEmbeddersSettings"); - // Update settings + HashMap embedders = new HashMap<>(); + embedders.put("custom", createUserProvidedEmbedder()); TaskInfo updateTask = index.updateEmbeddersSettings(embedders); index.waitForTask(updateTask.getTaskUid()); + Map updatedEmbedders = index.getEmbeddersSettings(); assertThat(updatedEmbedders.size(), is(equalTo(1))); assertThat(updatedEmbedders.containsKey("custom"), is(true)); - // Reset settings TaskInfo resetTask = index.resetEmbeddersSettings(); index.waitForTask(resetTask.getTaskUid()); Map resetEmbedders = index.getEmbeddersSettings();