Skip to content

Conversation

@8byr0
Copy link
Contributor

@8byr0 8byr0 commented Jan 17, 2025

Pull Request

Related issue

Fixes #1361

What does this PR do?

  • Allow configuring meilisearchParams for each index individually (multi search)

From :

const client = instantMeiliSearch(
      "host",
      "key",
      {
        meiliSearchParams: {
          matchingStrategy: MatchingStrategies.ALL,
        },
      },
    ).searchClient;

To :

const client = instantMeiliSearch("host", "key", {
  meiliSearchParams: {
    indexesOverrides: {
      products: { matchingStrategy: MatchingStrategies.ALL },
      categories: { matchingStrategy: MatchingStrategies.LAST },
    },
  },
}).searchClient

PR checklist

Please check if your PR fulfills the following requirements:

  • 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?

Thank you so much for contributing to Meilisearch!

Summary by CodeRabbit

  • New Features

    • Per-index overrides for Meilisearch parameters via an indexesOverrides option (per-index precedence across highlighting, sorting, matching strategy, hybrid/vector, distinct, ranking thresholds, facets, retrievable/searchable attributes). Merging of nested indexesOverrides when updating params.
  • Documentation

    • Added example showing global parameters with index-specific overrides (e.g., customizing highlighting for a “movies” index).
  • Types

    • Updated parameter types to include indexesOverrides for safer per-index configuration.
  • Tests

    • Expanded tests validating per-index override precedence across many parameters.

@changeset-bot
Copy link

changeset-bot bot commented Jan 17, 2025

⚠️ No Changeset found

Latest commit: 7502e75

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@8byr0 8byr0 marked this pull request as ready for review January 17, 2025 16:29
@8byr0
Copy link
Contributor Author

8byr0 commented Jan 17, 2025

My initial proposal in #1364 was to be able to override directly like :

const client = instantMeiliSearch(
      "host",
      "key",
      {
        meiliSearchParams: {
          products: { matchingStrategy: MatchingStrategies.ALL },
          categories: { matchingStrategy: MatchingStrategies.LAST },
        },
      },
    ).searchClient;

Unfortunately as far as I've seen it's not possible using typescript

This one works fine for accessing the values

export type OverridableMeiliSearchSearchParameters = BaseMeiliSearchSearchParameters & {
  [K in Exclude<string, keyof BaseMeiliSearchSearchParameters>]?: BaseMeiliSearchSearchParameters;
};
// No TS errors
const res = myobject[indexName].attributesToRetrieve;

// TS error
const meiliSearchParams: OverridableMeiliSearchSearchParameters = {
      attributesToHighlight: ['movies', 'genres'],
      highlightPreTag: '<em>',
      highlightPostTag: '</em>',
      matchingStrategy: MatchingStrategies.ALL,
    }

This one works fine for declaring values

export type OverridableMeiliSearchSearchParameters =
  | BaseMeiliSearchSearchParameters
  | (BaseMeiliSearchSearchParameters & {
      [K in Exclude<
        string,
        keyof BaseMeiliSearchSearchParameters
      >]?: BaseMeiliSearchSearchParameters
    })
// TS errors
const res = myobject[indexName].attributesToRetrieve;

// No TS errors
const meiliSearchParams: OverridableMeiliSearchSearchParameters = {
      attributesToHighlight: ['movies', 'genres'],
      highlightPreTag: '<em>',
      highlightPostTag: '</em>',
      matchingStrategy: MatchingStrategies.ALL,
    }

Open to discuss it if anyone has another approach in mind

@Strift Strift added enhancement New feature or request instant-meilisearch labels Jan 21, 2025
@Strift Strift self-requested a review January 21, 2025 05:08
@Strift
Copy link
Collaborator

Strift commented Jan 21, 2025

Thank you for opening this PR, I will take a look and review it ASAP.

@8byr0
Copy link
Contributor Author

8byr0 commented Jan 21, 2025

Just realised the override mechanism was not setup for filters and facets arguments so I added it in the same way as others (latest commit)

@8byr0
Copy link
Contributor Author

8byr0 commented Feb 14, 2025

@Strift any update on this ?

Copy link
Member

@brunoocasali brunoocasali left a comment

Choose a reason for hiding this comment

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

Hey there @Strift, I looked at the code and it seems very nice! I will wait for your final call, but it looks good, apparently!
PS: I didn't run it!

Thanks a lot @8byr0 for your first contribution! <3

@coderabbitai
Copy link

coderabbitai bot commented Aug 28, 2025

Walkthrough

Adds per-index meiliSearchParams: types now allow an indexesOverrides map, the search-params adapter resolves per-index values before global ones for many MeiliSearch parameters, client merging of indexesOverrides is added, and tests + README updated. No public function signatures changed.

Changes

Cohort / File(s) Summary
Docs
packages/instant-meilisearch/README.md
Adds documentation and an example demonstrating meiliSearchParams.indexesOverrides for per-index parameter overrides.
Types
packages/instant-meilisearch/src/types/types.ts
Introduces BaseOverridableMeiliSearchSearchParameters and updates OverridableMeiliSearchSearchParameters to include optional indexesOverrides?: Record<string, BaseOverridableMeiliSearchSearchParameters>.
Adapter Logic
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts
Implements per-index precedence for many params: resolves overrideParams?.indexesOverrides?.[indexUid]?.<param> ?? overrideParams?.<param> ?? source/default for numerous MeiliSearch params (facets, attributesToCrop, cropLength, cropMarker, filter, attributesToRetrieve, attributesToHighlight, highlightPreTag, highlightPostTag, showMatchesPosition, matchingStrategy, showRankingScore, attributesToSearchOn, hybrid, vector, distinct, rankingScoreThreshold, etc.).
Client Merge
packages/instant-meilisearch/src/client/instant-meilisearch-client.ts
setMeiliSearchParams now merges existing and new indexesOverrides objects so per-index overrides are combined rather than replaced.
Tests: Adapter
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts
Adds unit tests asserting per-index override precedence across multiple parameters (highlight tags, matchingStrategy, hybrid, vector, rankingScoreThreshold, distinct, filters behavior).
Tests: Integration
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts
Adds integration tests for per-index highlight tag overrides and that per-index sort overrides global sort.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as InstantSearch UI
  participant IMS as instantMeiliSearch Client
  participant SPA as SearchParamsAdapter
  participant MS as Meilisearch

  UI->>IMS: search({ indexUid, query })
  IMS->>SPA: buildSearchParams(indexUid, baseParams)
  rect rgb(239,248,255)
    note right of SPA: Resolution order: per-index → global → source/default
    SPA->>SPA: value = overrideParams?.indexesOverrides?.[indexUid]?.param
    alt value undefined
      SPA->>SPA: value = overrideParams?.param
    end
    SPA->>SPA: fallback = original/source/default
  end
  SPA-->>IMS: resolved per-index meiliSearchParams
  IMS->>MS: multi-search(requests with per-index params)
  MS-->>IMS: results
  IMS-->>UI: render results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Assessment against linked issues

Objective Addressed Explanation
Add per-index meiliSearchParams for multi search (#1361)
Update types to support per-index overrides (#1361)
Apply per-index handling for relevant params in adapter (#1361)

I hop through indexes, one by one,
I tweak the tags, I make it fun.
Per-index rules, precise and neat,
Each query gets its proper seat.
Rabbit cheers — overrides complete! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/instant-meilisearch/src/types/types.ts (1)

44-74: Type includes fields not currently honored by adapter (sort, hitsPerPage).

Either wire these into the adapter (preferred for consistency) or remove them from the overridable type to avoid confusion.

Would you like me to provide the adapter patch to honor meiliSearchParams.sort and clarify how hitsPerPage should interact with pagination?

packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

194-198: Honor meiliSearchParams.sort (global/per-index) to match types.

Types allow overriding sort, but the adapter ignores it. Apply the same precedence as other params.

-    addSort() {
-      if (sort?.length) {
-        meiliSearchParams.sort = Array.isArray(sort) ? sort : [sort]
-      }
-    },
+    addSort() {
+      const overrideSort =
+        overrideParams?.indexesOverrides?.[indexUid]?.sort ??
+        overrideParams?.sort
+
+      const value = overrideSort ?? sort
+      if (value && (Array.isArray(value) ? value.length : true)) {
+        meiliSearchParams.sort = Array.isArray(value) ? value : [value]
+      }
+    },

Consider adding tests mirroring the other per-index precedence checks.

🧹 Nitpick comments (3)
packages/instant-meilisearch/README.md (1)

299-301: Fix typos and casing in the new paragraph.

Use correct spelling/casing and remove the space before the colon.

-When using multi search, meilisearchParams can be overriden for specific indexes :
+When using multi-search, meiliSearchParams can be overridden for specific indexes:
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (1)

227-242: Rename test to be explicit.

The test name is truncated; append “index”.

-test('distinct search configuration can be set via search parameters for a specific', () => {
+test('distinct search configuration can be set via search parameters for a specific index', () => {
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

99-107: Reduce duplication with a small getter for override precedence.

A helper cuts repetition and centralizes precedence logic.

+    // helper to resolve per-index/global override with default
+    function pick<T extends keyof MeiliSearchMultiSearchParams>(
+      key: T,
+      fallback?: MeiliSearchMultiSearchParams[T]
+    ): MeiliSearchMultiSearchParams[T] | undefined {
+      return (
+        overrideParams?.indexesOverrides?.[indexUid]?.[key] ??
+        overrideParams?.[key] ??
+        fallback
+      )
+    }

Then replace patterns like:

const value = pick('facets', facets as any)

Apply similarly for cropLength, cropMarker, attributesToRetrieve, highlight tags, showMatchesPosition, matchingStrategy, attributesToSearchOn, hybrid, vector, distinct, rankingScoreThreshold, etc.

Also applies to: 110-117, 119-125, 127-134, 143-151, 153-171, 223-229, 231-237, 239-245, 247-257, 259-265, 267-273, 275-281, 283-289

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between eda46e3 and 78769d4.

📒 Files selected for processing (5)
  • packages/instant-meilisearch/README.md (1 hunks)
  • packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1 hunks)
  • packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (5 hunks)
  • packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (3 hunks)
  • packages/instant-meilisearch/src/types/types.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (2)
packages/instant-meilisearch/src/types/types.ts (1)
  • OverridableMeiliSearchSearchParameters (67-73)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
  • adaptSearchParams (300-327)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
packages/instant-meilisearch/src/types/types.ts (1)
  • Mutable (14-14)
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1)
packages/instant-meilisearch/__tests__/assets/utils.ts (1)
  • Movies (211-229)
🪛 LanguageTool
packages/instant-meilisearch/README.md

[grammar] ~299-~299: Ensure spelling is correct
Context: ... multi search, meilisearchParams can be overriden for specific indexes : ```js instantMe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (2)
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1)

51-62: LGTM: verifies per-index highlight tag overrides take precedence.

Solid coverage validating the new indexesOverrides.movies behavior.

packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (1)

83-116: LGTM: comprehensive precedence tests for per-index overrides.

Good assertions for attributesToHighlight, highlight tags, matchingStrategy, hybrid, vector, and rankingScoreThreshold.

Also applies to: 134-155, 170-182, 197-212

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

203-224: Bug: geo filter overwrites string filters instead of merging.

If filter is a string (from overrides), geo block replaces it with [geo] and drops the string. Merge instead: [geo, string].

-      if (filter !== undefined) {
-        if (Array.isArray(meiliSearchParams.filter)) {
-          meiliSearchParams.filter.unshift(filter)
-        } else {
-          meiliSearchParams.filter = [filter]
-        }
-      }
+      if (filter !== undefined) {
+        const existing = meiliSearchParams.filter
+        if (existing === undefined) {
+          meiliSearchParams.filter = [filter]
+        } else if (Array.isArray(existing)) {
+          meiliSearchParams.filter.unshift(filter)
+        } else {
+          // existing is a string; preserve it
+          meiliSearchParams.filter = [filter, existing]
+        }
+      }

Please add tests as suggested in the test file comment.

♻️ Duplicate comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

136-145: Fix confirmed: override-only filters now respected.

Logic now applies per-index/global override even when IS filters are empty. Matches intended precedence.

🧹 Nitpick comments (4)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (3)

134-155: Use value equality to avoid brittle identity coupling.

Switch toEqual for objects so tests don’t depend on adapter returning the exact same reference.

-    expect(searchParams.hybrid).toBe(specificHybridSearchConfig)
+    expect(searchParams.hybrid).toEqual(specificHybridSearchConfig)

169-182: Same here: prefer toEqual for arrays.

Avoid relying on reference equality for vector.

-    expect(searchParams.vector).toBe(indexVector)
+    expect(searchParams.vector).toEqual(indexVector)

227-242: Fix the test name (add missing word).

Minor wording nit.

-  test('distinct search configuration can be set via search parameters for a specific', () => {
+  test('distinct search configuration can be set via search parameters for a specific index', () => {
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

99-107: Reduce duplication: cache per-index overrides.

The repeated override resolution can be simplified for readability.

 export function MeiliParamsCreator(searchContext: SearchContext) {
@@
   const meiliSearchParams: MeiliSearchMultiSearchParams = { indexUid }
+  const perIndex = overrideParams?.indexesOverrides?.[indexUid]
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.facets ??
-        overrideParams?.facets ??
+      const value =
+        perIndex?.facets ??
+        overrideParams?.facets ??
         <Mutable<typeof facets>>facets
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.attributesToCrop ??
+      const value =
+        perIndex?.attributesToCrop ??
         overrideParams?.attributesToCrop ??
         <Mutable<typeof attributesToSnippet>>attributesToSnippet
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.cropLength ??
-        overrideParams?.cropLength
+      const value = perIndex?.cropLength ?? overrideParams?.cropLength
@@
-      meiliSearchParams.highlightPreTag =
-        overrideParams?.indexesOverrides?.[indexUid]?.highlightPreTag ??
+      meiliSearchParams.highlightPreTag =
+        perIndex?.highlightPreTag ??
         overrideParams?.highlightPreTag ??
         highlightPreTag ??
         '__ais-highlight__'
@@
-      meiliSearchParams.highlightPostTag =
-        overrideParams?.indexesOverrides?.[indexUid]?.highlightPostTag ??
+      meiliSearchParams.highlightPostTag =
+        perIndex?.highlightPostTag ??
         overrideParams?.highlightPostTag ??
         highlightPostTag ??
         '__/ais-highlight__'
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.showMatchesPosition ??
-        overrideParams?.showMatchesPosition
+      const value = perIndex?.showMatchesPosition ?? overrideParams?.showMatchesPosition
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.matchingStrategy ??
-        overrideParams?.matchingStrategy
+      const value = perIndex?.matchingStrategy ?? overrideParams?.matchingStrategy
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.showRankingScore ??
-        overrideParams?.showRankingScore
+      const value = perIndex?.showRankingScore ?? overrideParams?.showRankingScore
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.attributesToSearchOn ??
-        overrideParams?.attributesToSearchOn ??
+      const value =
+        perIndex?.attributesToSearchOn ??
+        overrideParams?.attributesToSearchOn ??
         <Mutable<typeof restrictSearchableAttributes>>(
           restrictSearchableAttributes
         )
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.hybrid ??
-        overrideParams?.hybrid
+      const value = perIndex?.hybrid ?? overrideParams?.hybrid
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.vector ??
-        overrideParams?.vector
+      const value = perIndex?.vector ?? overrideParams?.vector
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.distinct ??
-        overrideParams?.distinct
+      const value = perIndex?.distinct ?? overrideParams?.distinct
@@
-      const value =
-        overrideParams?.indexesOverrides?.[indexUid]?.rankingScoreThreshold ??
-        overrideParams?.rankingScoreThreshold
+      const value =
+        perIndex?.rankingScoreThreshold ?? overrideParams?.rankingScoreThreshold

Also applies to: 110-117, 119-131, 161-167, 169-174, 226-229, 234-239, 242-247, 250-256, 262-265, 270-275, 278-283, 286-291

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 78769d4 and 9fa4780.

📒 Files selected for processing (2)
  • packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (5 hunks)
  • packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
packages/instant-meilisearch/src/types/types.ts (1)
  • Mutable (14-14)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (2)
packages/instant-meilisearch/src/types/types.ts (1)
  • OverridableMeiliSearchSearchParameters (67-73)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
  • adaptSearchParams (303-330)
🔇 Additional comments (3)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/search-params.test.ts (3)

83-116: Per-index overrides precedence is correct.

Assertions validate that per-index values win over globals for highlight tags and matchingStrategy. Good coverage.


197-212: LGTM: per-index rankingScoreThreshold override takes precedence.


244-275: Great: covers override-only filter when IS filters are empty (global and per-index). Add geo+override combo case.

Add a test ensuring geo filters are merged with string overrides (not overwritten).

@@
 describe('Geo filter adapter', () => {
+  test('geo filter is combined with global override string filter', () => {
+    const searchParams = adaptSearchParams({
+      ...DEFAULT_CONTEXT,
+      insideBoundingBox: '0,0,0,0',
+      meiliSearchParams: { filter: 'status = "active"' },
+    })
+    expect(searchParams.filter).toEqual([
+      '_geoBoundingBox([0, 0], [0, 0])',
+      'status = "active"',
+    ])
+  })
+
+  test('geo filter is combined with per-index override string filter', () => {
+    const searchParams = adaptSearchParams({
+      ...DEFAULT_CONTEXT,
+      insideBoundingBox: '0,0,0,0',
+      meiliSearchParams: { indexesOverrides: { test: { filter: 'category = "books"' } } },
+    })
+    expect(searchParams.filter).toEqual([
+      '_geoBoundingBox([0, 0], [0, 0])',
+      'category = "books"',
+    ])
+  })

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (2)

222-228: Do not drop existing filters when adding geo filter

If an override sets filter to a string (or any non-array), addGeoSearchFilter replaces it with [geoFilter], losing the existing filter. Combine instead of replace.

Apply:

-      if (filter !== undefined) {
-        if (Array.isArray(meiliSearchParams.filter)) {
-          meiliSearchParams.filter.unshift(filter)
-        } else {
-          meiliSearchParams.filter = [filter]
-        }
-      }
+      if (filter !== undefined) {
+        const existing = meiliSearchParams.filter
+        if (Array.isArray(existing)) {
+          meiliSearchParams.filter = [filter, ...existing]
+        } else if (existing !== undefined) {
+          meiliSearchParams.filter = [filter, existing]
+        } else {
+          meiliSearchParams.filter = [filter]
+        }
+      }

175-196: Pagination gating ignores override-only filters

isPaginationRequired uses meilisearchFilters only. When the user provides only override filters (global or per-index), pagination can be incorrectly disabled (hitsPerPage/limit set to 0). Use the effective filter (override or IS).

Apply:

-      const paginationRequired = isPaginationRequired(
-        meilisearchFilters,
-        query,
-        placeholderSearch
-      )
+      const effectiveFilter =
+        (meiliSearchParams.filter as Filter | undefined) ??
+        (meilisearchFilters as unknown as Filter)
+      const paginationRequired = isPaginationRequired(
+        effectiveFilter as Filter,
+        query,
+        placeholderSearch
+      )
♻️ Duplicate comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

136-145: Fix confirmed: override filter is now respected with empty IS filters

Per the earlier review, overrideParams.filter (global or per-index) now applies even when meilisearchFilters is empty. Good precedence and no regression risk spotted here.

🧹 Nitpick comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

322-325: Optional: consider adding geo filter before computing pagination

If you want geo-only queries (no text, placeholderSearch=false) to still run, move addGeoSearchFilter() before addPagination() so geo filters are considered in pagination gating.

-  meiliSearchParams.addPagination()
-  meiliSearchParams.addSort()
-  meiliSearchParams.addGeoSearchFilter()
+  meiliSearchParams.addGeoSearchFilter()
+  meiliSearchParams.addPagination()
+  meiliSearchParams.addSort()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9fa4780 and e01ea71.

📒 Files selected for processing (2)
  • packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1 hunks)
  • packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/instant-meilisearch/tests/overridden-meilisearch-parameters.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
packages/instant-meilisearch/src/types/types.ts (1)
  • Mutable (14-14)
🔇 Additional comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)

99-103: Consistent per-index > global > source precedence looks good

Overrides are applied uniformly across facets, crop options, tags, sorting, visibility, matching, vector/hybrid, distinct, ranking threshold, and attributesToSearchOn. Facets coercion to array is a nice touch.

Also applies to: 111-116, 119-125, 127-134, 147-153, 156-160, 162-167, 169-174, 198-205, 231-236, 239-245, 247-253, 256-264, 268-272, 276-280, 284-288, 292-296

Copy link

@coderabbitai coderabbitai bot left a comment

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 (3)
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (3)

65-72: Use a suite-unique index UID to avoid cross-file collisions

Other tests may also use the "movies" UID; if tests run in parallel this can flake. Prefer a file-specific UID (e.g., "movies_overridden_params") and reuse it throughout this file.


101-106: Remove redundant global sort in the second setMeiliSearchParams call

You already set sort: ['title:asc'] at instantiation; re-setting it here adds noise.

-    setMeiliSearchParams({
-      sort: ['title:asc'],
-      indexesOverrides: {
-        movies: { sort: ['title:desc'] },
-      },
-    })
+    setMeiliSearchParams({
+      indexesOverrides: {
+        movies: { sort: ['title:desc'] },
+      },
+    })

65-116: Add coverage for filters/facets and multi-index override behavior

The PR mentions filters and facets were added to overrides; add one test that issues a multi-index search where only one index has per-index filters/facets overrides to assert isolation and precedence.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e01ea71 and 5666325.

📒 Files selected for processing (1)
  • packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (2)
packages/instant-meilisearch/__tests__/assets/utils.ts (3)
  • searchClient (245-245)
  • Movies (211-229)
  • meilisearchClient (249-249)
packages/instant-meilisearch/src/client/instant-meilisearch-client.ts (1)
  • instantMeiliSearch (46-208)
🔇 Additional comments (1)
packages/instant-meilisearch/__tests__/overridden-meilisearch-parameters.test.ts (1)

108-116: LGTM: precedence assertion is clear and robust

This correctly proves per-index sort overrides the global setting.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/instant-meilisearch/src/client/instant-meilisearch-client.ts (1)

98-101: Deep-merge per-index overrides to avoid clobbering existing keys.

Current merge replaces the whole object for an index (e.g., products), dropping previously set fields when new params only provide a subset. Prefer merging objects per index key so new fields override, but unmatched fields persist.

Confirm intended semantics: replace vs merge per index. If merge is desired, apply:

-              indexesOverrides: {
-                ...(meiliSearchParams.indexesOverrides || {}),
-                ...(params.indexesOverrides || {}),
-              },
+              indexesOverrides: Object.fromEntries(
+                Object.keys({
+                  ...(meiliSearchParams.indexesOverrides ?? {}),
+                  ...(params.indexesOverrides ?? {}),
+                }).map((k) => [
+                  k,
+                  {
+                    ...(meiliSearchParams.indexesOverrides?.[k] ?? {}),
+                    ...(params.indexesOverrides?.[k] ?? {}),
+                  },
+                ])
+              ),

Optional nit: if you want to avoid materializing an empty indexesOverrides when neither side provides it, wrap the property creation with a conditional and spread an empty object otherwise.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5666325 and 7502e75.

📒 Files selected for processing (1)
  • packages/instant-meilisearch/src/client/instant-meilisearch-client.ts (1 hunks)

@Strift Strift merged commit 8d9c32a into meilisearch:main Aug 31, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add per index meilisearchParams (for multi search)

3 participants