Skip to content

Add AI-powered search features #827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d73b322
Initial devcontainer setup
Strift Mar 13, 2025
5ddb097
Use gradle inside devcontainer
Strift Mar 13, 2025
45026c8
Add embedders settings
Strift Mar 9, 2025
74ed1f2
Run spotless
Strift Mar 12, 2025
d47e0f6
Add hybrid parameter
Strift Mar 12, 2025
426f605
Fix null embedder test
Strift Mar 12, 2025
a209989
Remove devcontainer
Strift Mar 18, 2025
08a7684
Rename embedder and add EmbedderDistirbution class
Strift Mar 18, 2025
2ba68af
Update embedders distribution test
Strift Mar 18, 2025
807a2b6
Lint
Strift Mar 18, 2025
6b4a620
Update test
Strift Mar 18, 2025
de3a46d
Temporarily add more info to tests
Strift Mar 18, 2025
132e191
Remove document template edition
Strift Mar 18, 2025
405a0e9
Update reset embedder test
Strift Mar 18, 2025
c52fc85
Update rest embedder test
Strift Mar 18, 2025
5514722
Create RestEmbedder class
Strift Mar 18, 2025
930aa39
Delete RestEmbedder class for consistency
Strift Mar 18, 2025
dc7ba8d
Remove error prones embedders
Strift Mar 18, 2025
b7b8506
Clean up tests
Strift Mar 18, 2025
3c53bca
Lint
Strift Mar 18, 2025
6bb3106
Add vector search test
Strift Mar 18, 2025
9c76f88
Add hybrid
Strift Mar 18, 2025
40fa243
Fix tasks test
Strift Apr 8, 2025
cefaf25
Add retrieveVectors
Strift Apr 8, 2025
4306308
Spotless
Strift Apr 8, 2025
b8b3c88
Add check for optional _vectors
Strift Apr 8, 2025
22482fb
Add tests for similar documents
Strift Apr 8, 2025
3c93870
Merge branch 'main' into feat/add-ai-powered-search
Strift Apr 24, 2025
35d1ec7
Update src/main/java/com/meilisearch/sdk/SearchRequest.java
Strift Apr 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/com/meilisearch/sdk/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -1249,4 +1249,42 @@ 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 <a href="https://www.meilisearch.com/docs/reference/api/settings#get-embedders">API
* specification</a>
*/
public Map<String, Embedder> 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 <a href="https://www.meilisearch.com/docs/reference/api/settings#update-embedders">API
* specification</a>
*/
public TaskInfo updateEmbeddersSettings(Map<String, Embedder> 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 <a href="https://www.meilisearch.com/docs/reference/api/settings#reset-embedders">API
* specification</a>
*/
public TaskInfo resetEmbeddersSettings() throws MeilisearchException {
return this.settingsHandler.resetEmbedders(this.uid);
}
}
6 changes: 4 additions & 2 deletions src/main/java/com/meilisearch/sdk/IndexSearchRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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();
}
Expand Down
16 changes: 13 additions & 3 deletions src/main/java/com/meilisearch/sdk/SearchRequest.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -42,12 +43,15 @@ public class SearchRequest {
protected Double rankingScoreThreshold;
protected String[] locales;
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
*/
Expand Down Expand Up @@ -104,7 +108,13 @@ 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)
.putOpt("retrieveVectors", this.retrieveVectors);

if (this.hybrid != null) {
jsonObject.put("hybrid", this.hybrid.toJSONObject());
}

return jsonObject.toString();
}
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/com/meilisearch/sdk/SettingsHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.meilisearch.sdk.exceptions.MeilisearchException;
import com.meilisearch.sdk.http.URLBuilder;
import com.meilisearch.sdk.model.Embedder;
import com.meilisearch.sdk.model.Faceting;
import com.meilisearch.sdk.model.LocalizedAttribute;
import com.meilisearch.sdk.model.Pagination;
Expand Down Expand Up @@ -769,4 +770,47 @@ 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<String, Embedder> getEmbedders(String uid) throws MeilisearchException {
return httpClient.get(
settingsPath(uid).addSubroute("embedders").getURL(),
Map.class,
String.class,
Embedder.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<String, Embedder> embedders)
throws MeilisearchException {
return httpClient.patch(
settingsPath(uid).addSubroute("embedders").getURL(),
embedders == null ? null : httpClient.jsonHandler.encode(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);
}
}
23 changes: 11 additions & 12 deletions src/main/java/com/meilisearch/sdk/SimilarDocumentRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
73 changes: 73 additions & 0 deletions src/main/java/com/meilisearch/sdk/model/Embedder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
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 Embedder {
/** 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.
*/
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 EmbedderDistribution distribution;

/** Request configuration. Mandatory only when using rest embedder, optional otherwise. */
protected Map<String, Object> request;

/** Response configuration. Mandatory only when using rest embedder, optional otherwise. */
protected Map<String, Object> 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<String, String> 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 Embedder() {}
}
56 changes: 56 additions & 0 deletions src/main/java/com/meilisearch/sdk/model/EmbedderDistribution.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
24 changes: 0 additions & 24 deletions src/main/java/com/meilisearch/sdk/model/Embedders.java

This file was deleted.

Loading