Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -664,3 +664,26 @@ post_render_template_1: |-
.setInput(input);

client.renderTemplate(request);


list_dynamic_search_rules_1: |-
DynamicSearchRulesQuery query = new DynamicSearchRulesQuery();
Results<DynamicSearchRule> rules = client.listDynamicSearchRules(query);
get_dynamic_search_rule_1: |-
DynamicSearchRule rule = client.getDynamicSearchRule("black-friday");
patch_dynamic_search_rule_1: |-
List<Map<String, Object>> conditions = List.of(
Map.of("scope", "query", "isEmpty", true),
Map.of("scope", "time", "start", "2025-11-28T00:00:00Z", "end", "2025-11-28T23:59:59Z"));

List<Map<String, Object>> actions = List.of(
Map.of(
"selector", Map.of("indexUid", "products", "id", "123"),
"action", Map.of("type", "pin", "position", 1)));

DynamicSearchRule rule = new DynamicSearchRule(
"black-friday", "Black Friday 2025 rules", 10, true, conditions, actions);

TaskInfo task = client.updateDynamicSearchRule("black-friday", rule);
delete_dynamic_search_rule_1: |-
TaskInfo task = client.deleteDynamicSearchRule("black-friday");
48 changes: 48 additions & 0 deletions src/main/java/com/meilisearch/sdk/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class Client {
private KeysHandler keysHandler;
private JsonHandler jsonHandler;
private WebHooksHandler webHooksHandler;
private DynamicSearchRulesHandler dynamicSearchRulesHandler;

/**
* Calls instance for Meilisearch client
Expand All @@ -35,6 +36,7 @@ public Client(Config config) {
this.keysHandler = new KeysHandler(config);
this.jsonHandler = config.jsonHandler;
this.webHooksHandler = new WebHooksHandler(config);
this.dynamicSearchRulesHandler = new DynamicSearchRulesHandler(config);
}

/**
Expand Down Expand Up @@ -624,4 +626,50 @@ private Boolean isValidUUID(String apiKeyUid) {
}
return true;
}
/**
* Get a list of all dynamic search rules.
*
* @param query Query parameters for pagination and filtering (offset, limit, filter).
* @return Results containing a list of DynamicSearchRule instances.
* @throws MeilisearchException If an error occurs.
*/
public Results<DynamicSearchRule> listDynamicSearchRules(DynamicSearchRulesQuery query)
throws MeilisearchException {
return this.dynamicSearchRulesHandler.listDynamicSearchRules(query);
}

/**
* Get a single dynamic search rule by its uid.
*
* @param uid Unique identifier of the dynamic search rule.
* @return A single DynamicSearchRule instance.
* @throws MeilisearchException If an error occurs.
*/
public DynamicSearchRule getDynamicSearchRule(String uid) throws MeilisearchException {
return this.dynamicSearchRulesHandler.getDynamicSearchRule(uid);
}

/**
* Create a new dynamic search rule, or update it if a rule with the given uid already exists.
*
* @param uid Unique identifier of the dynamic search rule.
* @param dynamicSearchRule Request body containing the rule configuration.
* @return TaskInfo instance for the enqueued upsert operation.
* @throws MeilisearchException If an error occurs.
*/
public TaskInfo updateDynamicSearchRule(String uid, DynamicSearchRule dynamicSearchRule)
throws MeilisearchException {
return this.dynamicSearchRulesHandler.updateDynamicSearchRule(uid, dynamicSearchRule);
}

/**
* Delete a dynamic search rule.
*
* @param uid Unique identifier of the dynamic search rule.
* @return TaskInfo instance for the enqueued delete operation.
* @throws MeilisearchException If an error occurs.
*/
public TaskInfo deleteDynamicSearchRule(String uid) throws MeilisearchException {
return this.dynamicSearchRulesHandler.deleteDynamicSearchRule(uid);
}
}
44 changes: 44 additions & 0 deletions src/main/java/com/meilisearch/sdk/DynamicSearchRulesHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.meilisearch.sdk;

import com.meilisearch.sdk.exceptions.MeilisearchException;
import com.meilisearch.sdk.http.URLBuilder;
import com.meilisearch.sdk.model.DynamicSearchRule;
import com.meilisearch.sdk.model.DynamicSearchRulesQuery;
import com.meilisearch.sdk.model.Results;
import com.meilisearch.sdk.model.TaskInfo;

class DynamicSearchRulesHandler {
private final HttpClient httpClient;

protected DynamicSearchRulesHandler(Config config) {
httpClient = config.httpClient;
}

Results<DynamicSearchRule> listDynamicSearchRules(DynamicSearchRulesQuery query)
throws MeilisearchException {
return httpClient.post(
dynamicSearchRulesPath().getURL(), query, Results.class, DynamicSearchRule.class);
}

DynamicSearchRule getDynamicSearchRule(String uid) throws MeilisearchException {
return httpClient.get(
dynamicSearchRulesPath().addSubroute(uid).getURL(), DynamicSearchRule.class);
}

TaskInfo updateDynamicSearchRule(String uid, DynamicSearchRule dynamicSearchRule)
throws MeilisearchException {
return httpClient.patch(
dynamicSearchRulesPath().addSubroute(uid).getURL(),
dynamicSearchRule,
TaskInfo.class);
}

TaskInfo deleteDynamicSearchRule(String uid) throws MeilisearchException {
return httpClient.delete(
dynamicSearchRulesPath().addSubroute(uid).getURL(), TaskInfo.class);
}

private URLBuilder dynamicSearchRulesPath() {
return new URLBuilder("/dynamic-search-rules");
}
}
41 changes: 41 additions & 0 deletions src/main/java/com/meilisearch/sdk/model/DynamicSearchRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.meilisearch.sdk.model;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;

/**
* Meilisearch Dynamic Search Rule.
*
* @see <a href="https://www.meilisearch.com/docs/capabilities/search_rules/overview">API
* specification</a>
*/
@Getter
@Setter
public class DynamicSearchRule implements Serializable {
protected String uid;
protected String description;
protected int priority;
protected boolean active;
protected List<Map<String, Object>> conditions;
protected List<Map<String, Object>> actions;

public DynamicSearchRule() {}

public DynamicSearchRule(
String uid,
String description,
int priority,
boolean active,
List<Map<String, Object>> conditions,
List<Map<String, Object>> actions) {
this.uid = uid;
this.description = description;
this.priority = priority;
this.active = active;
this.conditions = conditions;
this.actions = actions;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.meilisearch.sdk.model;

import java.io.Serializable;
import java.util.Map;

public class DynamicSearchRulesQuery implements Serializable {
protected Integer offset;
protected Integer limit;
protected Map<String, Object> filter;

public DynamicSearchRulesQuery() {}

public DynamicSearchRulesQuery setOffset(int offset) {
this.offset = offset;
return this;
}

public DynamicSearchRulesQuery setLimit(int limit) {
this.limit = limit;
return this;
}

public DynamicSearchRulesQuery setFilter(Map<String, Object> filter) {
this.filter = filter;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.meilisearch.integration;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import com.meilisearch.integration.classes.AbstractIT;
import com.meilisearch.sdk.exceptions.MeilisearchException;
import com.meilisearch.sdk.model.DynamicSearchRule;
import com.meilisearch.sdk.model.DynamicSearchRulesQuery;
import com.meilisearch.sdk.model.Results;
import com.meilisearch.sdk.model.TaskInfo;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Tag("integration")
public class DynamicSearchRulesTest extends AbstractIT {

@BeforeEach
public void initialize() throws MeilisearchException {
this.setUp();
client.experimentalFeatures(Collections.singletonMap("dynamicSearchRules", true));
}

@AfterAll
static void cleanMeilisearch() {
cleanup();
}

private DynamicSearchRule buildTestRule(String uid) {
Map<String, Object> queryCondition = Map.of("scope", "query", "isEmpty", true);
Map<String, Object> action =
Map.of(
"selector", Map.of("indexUid", "products"),
"action", Map.of("type", "pin", "position", 1));

return new DynamicSearchRule(
uid, "Test rule", 5, true, List.of(queryCondition), List.of(action));
}

@Test
public void testUpdateDynamicSearchRule() throws MeilisearchException {
DynamicSearchRule rule = buildTestRule("test-rule");

TaskInfo task = client.updateDynamicSearchRule("test-rule", rule);
client.waitForTask(task.getTaskUid());

DynamicSearchRule fetched = client.getDynamicSearchRule("test-rule");
assertThat(fetched.getUid(), equalTo("test-rule"));
assertThat(fetched.getDescription(), equalTo("Test rule"));
assertThat(fetched.getPriority(), equalTo(5));
assertThat(fetched.isActive(), equalTo(true));
}

@Test
public void testGetDynamicSearchRule() throws MeilisearchException {
DynamicSearchRule rule = buildTestRule("test-rule-get");
TaskInfo task = client.updateDynamicSearchRule("test-rule-get", rule);
client.waitForTask(task.getTaskUid());

DynamicSearchRule fetched = client.getDynamicSearchRule("test-rule-get");
assertThat(fetched, notNullValue());
assertThat(fetched.getUid(), equalTo("test-rule-get"));
}

@Test
public void testListDynamicSearchRules() throws MeilisearchException {
TaskInfo task1 = client.updateDynamicSearchRule("rule-one", buildTestRule("rule-one"));
client.waitForTask(task1.getTaskUid());
TaskInfo task2 = client.updateDynamicSearchRule("rule-two", buildTestRule("rule-two"));
client.waitForTask(task2.getTaskUid());

Results<DynamicSearchRule> results =
client.listDynamicSearchRules(new DynamicSearchRulesQuery());

assertThat(results.getResults().length >= 2, equalTo(true));
}

@Test
public void testDeleteDynamicSearchRule() throws MeilisearchException {
DynamicSearchRule rule = buildTestRule("test-rule-delete");
TaskInfo createTask = client.updateDynamicSearchRule("test-rule-delete", rule);
client.waitForTask(createTask.getTaskUid());

TaskInfo deleteTask = client.deleteDynamicSearchRule("test-rule-delete");
client.waitForTask(deleteTask.getTaskUid());

MeilisearchException exception =
org.junit.jupiter.api.Assertions.assertThrows(
MeilisearchException.class,
() -> client.getDynamicSearchRule("test-rule-delete"));
assertThat(exception, notNullValue());
}
}