Skip to content

Add foreignKeys experimental setting support#980

Open
Monish-K0 wants to merge 1 commit into
meilisearch:mainfrom
Monish-K0:add-foreign-keys-settings
Open

Add foreignKeys experimental setting support#980
Monish-K0 wants to merge 1 commit into
meilisearch:mainfrom
Monish-K0:add-foreign-keys-settings

Conversation

@Monish-K0

@Monish-K0 Monish-K0 commented Jul 9, 2026

Copy link
Copy Markdown

Pull Request

Related issue

Fixes #978

What does this PR do?

  • Adds support for the experimental foreignKeys setting.

Changes

  • Added ForeignKey.java model class with foreignIndexUid and fieldName fields
  • Added getForeignKeysSettings(), updateForeignKeysSettings(), and resetForeignKeysSettings() methods to Index.java and SettingsHandler.java
  • Added foreignKeys field to Settings.java so the global settings methods handle it automatically
  • Added integration tests in SettingsTest.java covering get, update, and reset
  • Added get_foreign_keys_setting_1, update_foreign_keys_setting_1, and reset_foreign_keys_setting_1 code samples to .code-samples.meilisearch.yaml
  • Fixed integrationTest Gradle task to explicitly set testClassesDirs and classpath, which was causing it to silently find zero tests under Gradle 9

Testing

  • Tested against a local Meilisearch v1.48.3 instance with foreignKeys experimental feature enabled.
  • All three new tests passed:
    • Test get foreign keys settings by uid
    • Test update foreign keys settings
    • Test reset foreign keys settings
  • Linter and build also passed.

PR checklist

Please check if your PR fulfills the following requirements:

  • Did you use any AI tool while implementing this PR?
    AI disclosure: I used ChatGPT to help understand the repository structure, follow existing patterns, and generate the initial implementation. I reviewed all the code, verified field names against the official Meilisearch API docs, and confirmed everything works by running tests against a live Meilisearch instance.
  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Summary by CodeRabbit

  • New Features

    • Added support for managing foreign key settings in indexes, including viewing, updating, and resetting them.
    • Introduced a new foreign key settings model and exposed it through index settings.
  • Documentation

    • Updated code samples to show how to work with foreign key settings and refreshed webhook deletion example formatting.
  • Tests

    • Added integration coverage for fetching, updating, and resetting foreign key settings.
  • Chores

    • Updated build and Windows wrapper formatting/configuration without changing runtime behavior.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an experimental foreignKeys settings feature to the Java SDK: a new ForeignKey model, a foreignKeys field on Settings, get/update/reset methods on SettingsHandler and Index, integration tests, and documentation code samples. Also updates Gradle integrationTest task configuration and normalizes gradlew.bat formatting.

Changes

Foreign Keys Settings Feature

Layer / File(s) Summary
ForeignKey model and Settings field
src/main/java/com/meilisearch/sdk/model/ForeignKey.java, src/main/java/com/meilisearch/sdk/model/Settings.java
Adds new ForeignKey model with foreignIndexUid and fieldName fields, and a foreignKeys field on Settings.
SettingsHandler foreign-keys endpoints
src/main/java/com/meilisearch/sdk/SettingsHandler.java
Adds getForeignKeysSettings, updateForeignKeysSettings, and resetForeignKeysSettings wired to /indexes/{uid}/settings/foreign-keys.
Index public API methods
src/main/java/com/meilisearch/sdk/Index.java
Exposes getForeignKeysSettings, updateForeignKeysSettings, and resetForeignKeysSettings delegating to settingsHandler.
Integration tests and documentation samples
src/test/java/com/meilisearch/integration/SettingsTest.java, .code-samples.meilisearch.yaml
Adds tests validating get/update/reset behavior and new YAML code samples plus a webhook deletion formatting fix.

Build Tooling Formatting

Layer / File(s) Summary
Gradle integrationTest task and gradlew.bat formatting
build.gradle, gradlew.bat
Sets explicit testClassesDirs/classpath for the integrationTest task; normalizes whitespace/line-endings in gradlew.bat with no functional change.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Index
  participant SettingsHandler
  participant MeilisearchAPI

  Index->>SettingsHandler: updateForeignKeysSettings(uid, foreignKeys)
  SettingsHandler->>MeilisearchAPI: PUT /indexes/{uid}/settings/foreign-keys
  MeilisearchAPI-->>SettingsHandler: TaskInfo
  SettingsHandler-->>Index: TaskInfo
Loading

Possibly related issues

Poem

A rabbit hops through index rows,
Linking keys where data flows,
🥕 foreignKeys now settle in,
Get, update, reset — let joins begin!
Hop hop, the docs align just right,
Off I bounce into the night.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Gradle task fix and gradlew.bat formatting changes are unrelated to the foreignKeys issue scope. Split unrelated build/script changes into a separate PR unless they are required to support the new feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding experimental foreignKeys support.
Linked Issues check ✅ Passed The PR covers the requested foreignKeys endpoints, settings handling, tests, and documentation samples from issue #978.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (redundant_comments). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/test/java/com/meilisearch/integration/SettingsTest.java (1)

1662-1703: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for resetting foreignKeys via updateForeignKeysSettings(null).

Every other setting in this file (synonyms, stop-words, ranking rules, displayed/searchable/filterable attributes, distinct attribute, localized attributes) has a companion ...UsingNull test verifying the update-to-null reset path (SettingsHandler.updateForeignKeysSettings explicitly encodes null for this case). That branch is currently untested for foreignKeys.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/meilisearch/integration/SettingsTest.java` around lines
1662 - 1703, Add a null-reset coverage test for foreign keys in SettingsTest by
extending the existing test around Index.updateForeignKeysSettings and
getForeignKeysSettings. Create a companion test that calls
updateForeignKeysSettings(null), wait for the task via waitForTask, then assert
getForeignKeysSettings returns the reset/empty state and differs from the
previously configured ForeignKey[]; this should mirror the existing “UsingNull”
patterns used for other settings and exercise the null branch in
SettingsHandler.updateForeignKeysSettings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/com/meilisearch/integration/SettingsTest.java`:
- Around line 1644-1740: The foreignKeys integration tests are exercising
experimental endpoints without enabling the feature first, so they will fail on
a default server. Update the test setup used by SettingsTest/AbstractIT to opt
into experimental features before calling Index.getForeignKeysSettings,
Index.updateForeignKeysSettings, and Index.resetForeignKeysSettings, so the
foreign-key assertions run against an enabled server.

---

Nitpick comments:
In `@src/test/java/com/meilisearch/integration/SettingsTest.java`:
- Around line 1662-1703: Add a null-reset coverage test for foreign keys in
SettingsTest by extending the existing test around
Index.updateForeignKeysSettings and getForeignKeysSettings. Create a companion
test that calls updateForeignKeysSettings(null), wait for the task via
waitForTask, then assert getForeignKeysSettings returns the reset/empty state
and differs from the previously configured ForeignKey[]; this should mirror the
existing “UsingNull” patterns used for other settings and exercise the null
branch in SettingsHandler.updateForeignKeysSettings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6abda010-f5ae-4f89-9c6d-269cc9a95725

📥 Commits

Reviewing files that changed from the base of the PR and between acfe026 and 760a3ae.

📒 Files selected for processing (8)
  • .code-samples.meilisearch.yaml
  • build.gradle
  • gradlew.bat
  • src/main/java/com/meilisearch/sdk/Index.java
  • src/main/java/com/meilisearch/sdk/SettingsHandler.java
  • src/main/java/com/meilisearch/sdk/model/ForeignKey.java
  • src/main/java/com/meilisearch/sdk/model/Settings.java
  • src/test/java/com/meilisearch/integration/SettingsTest.java

Comment on lines +1644 to +1740
/** Tests of the foreignKeys setting methods (experimental feature, Meilisearch v1.39+) */
@Test
@DisplayName("Test get foreign keys settings by uid")
public void testGetForeignKeysSettings() throws Exception {
Index index = createIndex("testGetForeignKeysSettings");

// Fetch global settings and the dedicated endpoint — they must agree.
Settings initialSettings = index.getSettings();
ForeignKey[] initialForeignKeys = index.getForeignKeysSettings();

int dedicatedSize = initialForeignKeys == null ? 0 : initialForeignKeys.length;
int globalSize =
initialSettings.getForeignKeys() == null
? 0
: initialSettings.getForeignKeys().length;
assertThat(dedicatedSize, is(equalTo(globalSize)));
}

@Test
@DisplayName("Test update foreign keys settings")
public void testUpdateForeignKeysSettings() throws Exception {
Index index = createIndex("testUpdateForeignKeysSettings");

// Record what is there before we make any changes.
ForeignKey[] initialForeignKeys = index.getForeignKeysSettings();

// Build two ForeignKey entries using setters (mirrors the LocalizedAttribute pattern).
ForeignKey firstKey = new ForeignKey();
firstKey.setForeignIndexUid("authors"); // the related index uid
firstKey.setFieldName("author_id"); // the field in THIS index that holds the link

ForeignKey secondKey = new ForeignKey();
secondKey.setForeignIndexUid("genres");
secondKey.setFieldName("genre_id");

ForeignKey[] newForeignKeys = new ForeignKey[] {firstKey, secondKey};

// Push the update and wait for the async task to finish.
index.waitForTask(index.updateForeignKeysSettings(newForeignKeys).getTaskUid());

// Fetch the setting back and verify every field was stored correctly.
ForeignKey[] updatedForeignKeys = index.getForeignKeysSettings();

assertThat(updatedForeignKeys, is(arrayWithSize(newForeignKeys.length)));
assertThat(
updatedForeignKeys[0].getForeignIndexUid(),
is(equalTo(newForeignKeys[0].getForeignIndexUid())));
assertThat(
updatedForeignKeys[0].getFieldName(),
is(equalTo(newForeignKeys[0].getFieldName())));
assertThat(
updatedForeignKeys[1].getForeignIndexUid(),
is(equalTo(newForeignKeys[1].getForeignIndexUid())));
assertThat(
updatedForeignKeys[1].getFieldName(),
is(equalTo(newForeignKeys[1].getFieldName())));

// The updated setting must differ from what was there initially.
assertThat(updatedForeignKeys, is(not(equalTo(initialForeignKeys))));
}

@Test
@DisplayName("Test reset foreign keys settings")
public void testResetForeignKeysSettings() throws Exception {
Index index = createIndex("testResetForeignKeysSettings");

ForeignKey[] initialForeignKeys = index.getForeignKeysSettings();

// Apply some foreign keys first.
ForeignKey firstKey = new ForeignKey();
firstKey.setForeignIndexUid("authors");
firstKey.setFieldName("author_id");

ForeignKey secondKey = new ForeignKey();
secondKey.setForeignIndexUid("genres");
secondKey.setFieldName("genre_id");

ForeignKey[] newForeignKeys = new ForeignKey[] {firstKey, secondKey};

index.waitForTask(index.updateForeignKeysSettings(newForeignKeys).getTaskUid());
ForeignKey[] updatedForeignKeys = index.getForeignKeysSettings();

// Now reset and verify the setting returned to its initial state.
index.waitForTask(index.resetForeignKeysSettings().getTaskUid());
ForeignKey[] foreignKeysAfterReset = index.getForeignKeysSettings();

assertThat(updatedForeignKeys, is(arrayWithSize(newForeignKeys.length)));
assertThat(
updatedForeignKeys[0].getForeignIndexUid(),
is(equalTo(newForeignKeys[0].getForeignIndexUid())));
assertThat(
updatedForeignKeys[0].getFieldName(),
is(equalTo(newForeignKeys[0].getFieldName())));

// After reset the setting must differ from the updated state.
assertThat(foreignKeysAfterReset, is(not(equalTo(updatedForeignKeys))));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Look for experimental-features enablement in test setup / CI config
rg -n -i "experimental" src/test/java/com/meilisearch/integration/AbstractIT.java 2>/dev/null
fd -i "AbstractIT.java"
rg -n -i "experimental-feature|experimentalFeatures" -g '*.java' -g '*.yml' -g '*.yaml'

Repository: meilisearch/meilisearch-java

Length of output: 232


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== AbstractIT outline ==\n'
ast-grep outline src/test/java/com/meilisearch/integration/classes/AbstractIT.java --view expanded || true

printf '\n== AbstractIT excerpt ==\n'
sed -n '1,260p' src/test/java/com/meilisearch/integration/classes/AbstractIT.java

printf '\n== CI/test config mentions of experimental features ==\n'
rg -n -i "experimental-feature|experimentalFeatures|PATCH /experimental-features|foreignKeys|experimental" .github src/test/java src/test/resources . 2>/dev/null || true

Repository: meilisearch/meilisearch-java

Length of output: 22060


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Files in integration test area ==\n'
git ls-files 'src/test/java/com/meilisearch/integration/**' | sed -n '1,120p'

printf '\n== Search for foreignKeys feature enablement ==\n'
rg -n -i "foreignKeys|experimental-features|experimentalFeatures|PATCH /experimental-features" src/test/java .github . 2>/dev/null || true

Repository: meilisearch/meilisearch-java

Length of output: 14480


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Integration test base class ==\n'
sed -n '1,260p' src/test/java/com/meilisearch/integration/classes/AbstractIT.java

printf '\n== Test/CI config files ==\n'
git ls-files '.github/**' 'pom.xml' 'build.gradle*' 'gradle.properties' 'docker-compose*' 'src/test/resources/**' | sed -n '1,200p'

printf '\n== Experimental feature env/config search ==\n'
rg -n -i "MEILI_EXPERIMENTAL|experimental-features|experimentalFeatures|foreignKeys|meilisearch.*test|docker.*meilisearch|AbstractIT" .github pom.xml build.gradle* gradle.properties docker-compose* src/test/resources src/test/java 2>/dev/null || true

Repository: meilisearch/meilisearch-java

Length of output: 17192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== AbstractIT ==" 
sed -n '1,260p' src/test/java/com/meilisearch/integration/classes/AbstractIT.java

echo
echo "== Workflow / CI files referencing Meilisearch =="
git ls-files '.github/workflows/**' '.github/**' 'pom.xml' 'docker-compose*' 'src/test/resources/**' | sed -n '1,200p'

echo
echo "== Grep for feature enablement / test launcher =="
rg -n -i "experimental-features|experimentalFeatures|MEILI_EXPERIMENTAL|foreignKeys|meilisearch" \
  .github/workflows .github pom.xml docker-compose* src/test/resources src/test/java 2>/dev/null || true

Repository: meilisearch/meilisearch-java

Length of output: 45028


Enable foreignKeys in the integration-test setup
AbstractIT and the CI workflows start Meilisearch without any /experimental-features opt-in, so these tests will hit feature_not_enabled on a default server. Add the enablement before exercising the foreign-key endpoints.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/meilisearch/integration/SettingsTest.java` around lines
1644 - 1740, The foreignKeys integration tests are exercising experimental
endpoints without enabling the feature first, so they will fail on a default
server. Update the test setup used by SettingsTest/AbstractIT to opt into
experimental features before calling Index.getForeignKeysSettings,
Index.updateForeignKeysSettings, and Index.resetForeignKeysSettings, so the
foreign-key assertions run against an enabled server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Meilisearch v1.48.0] Add document relations (experimental)

1 participant