Skip to content

fix(search): apply minimum_should_match floor to column index search - #31019

Open
mohityadav766 wants to merge 1 commit into
mainfrom
fix/column-search-min-should-match
Open

fix(search): apply minimum_should_match floor to column index search#31019
mohityadav766 wants to merge 1 commit into
mainfrom
fix/column-search-min-should-match

Conversation

@mohityadav766

Copy link
Copy Markdown
Member

Describe your changes:

Fixes open-metadata/openmetadata-collate#3851

Column search (index=tableColumn) routes through buildColumnSearchBuilderV2, which passed "0" as the multi_match fuzziness argument. minimum_should_match was only ever applied inside the !fuzziness.equals("0") branch, so the "0" sentinel silently dropped the floor — leaving a bare best_fields/OR multi_match that matches any column sharing a single token (e.g. a common parent-name token in fullyQualifiedName / table.name).

As a result, a specific-FQN column search returned the entire column index, while the dataAsset aggregation (strict builder, minimum_should_match(1)) counted only the true matches — so the Explore Columns tab count and the results list diverged (observed: tab count 1, results 7,381).

Fix: pass the existing MINIMUM_SHOULD_MATCH ("2<70%") constant to the multi_match in both the OpenSearch and Elasticsearch source-builder factories. The 9-arg overload applies minimum_should_match unconditionally (independent of fuzziness). Exact-name searches (1–2 tokens) still match; long FQN-style queries now require ~70% token overlap instead of a single shared token.

Changed:

  • openmetadata-service/.../search/opensearch/OpenSearchSourceBuilderFactory.javabuildColumnSearchBuilderV2
  • openmetadata-service/.../search/elasticsearch/ElasticSearchSourceBuilderFactory.javabuildColumnSearchBuilderV2

Type of change:

  • Bug fix

Tests:

Unit tests

  • Added SearchSourceBuilderFactoryTest.testColumnIndexSearchAppliesMinimumShouldMatchFloor — builds the column query for both OpenSearch and Elasticsearch and asserts the serialized query carries "minimum_should_match":"2<70%". Fails on the previous code (floor absent), passes with the fix.
  • SearchSourceBuilderFactoryTest: 18/18 pass locally.

Backend integration tests

  • Not applicable (no API changes). Existing ColumnSearchIndexIT asserts a column is findable by name, which this change preserves — and makes more robust, since the target column is no longer buried beyond size(10) among thousands of permissive matches.

UI screen recording / screenshots:

Not applicable (backend search-query change).

Checklist:

  • I have read the CONTRIBUTING document.
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added tests (unit) and listed them above.
  • I have added a test that covers the exact scenario we are fixing.

🤖 Generated with Claude Code

Column search (index=tableColumn) routes through buildColumnSearchBuilderV2,
which passed "0" as the multi_match fuzziness argument. minimum_should_match
was only ever set inside the `!fuzziness.equals("0")` branch, so the "0"
sentinel silently dropped the floor -- leaving a bare OR multi_match that
matched any column sharing a single token (e.g. a common parent-name token in
fullyQualifiedName / table.name). A specific-FQN search therefore returned the
whole column index while the dataAsset aggregation counted only the true
matches, so the Explore "Columns" tab count and the results diverged
(e.g. count 1 vs 7,381 results).

Pass the existing MINIMUM_SHOULD_MATCH ("2<70%") constant to the multi_match in
both the OpenSearch and Elasticsearch source-builder factories, and add a
regression test asserting the serialized column query carries the floor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mohityadav766
mohityadav766 requested a review from a team as a code owner August 5, 2026 09:17
Copilot AI review requested due to automatic review settings August 5, 2026 09:17
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • Linked issue open-metadata/openmetadata-collate#3851 does not exist or is not accessible.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Aug 5, 2026
@gitar-bot

gitar-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Applies the MINIMUM_SHOULD_MATCH floor constant to column index search queries in both OpenSearch and Elasticsearch factories to fix result count divergence. No issues found.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source

Copilot AI 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.

Pull request overview

This PR fixes an overly-permissive column-index search query by ensuring minimum_should_match is applied even when fuzziness is the "0" sentinel, preventing FQN-style column searches from matching the entire column_search_index and eliminating the mismatch between aggregation counts and returned results.

Changes:

  • Apply MINIMUM_SHOULD_MATCH ("2<70%") to the column-index multi_match query in both OpenSearch and Elasticsearch builder factories via the overload that sets minimum_should_match unconditionally.
  • Add a regression unit test asserting that both factories’ serialized queries include "minimum_should_match":"2<70%".

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchSourceBuilderFactory.java Ensure column-index multi_match applies MINIMUM_SHOULD_MATCH even with fuzziness "0".
openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchSourceBuilderFactory.java Mirror the same column-index minimum_should_match behavior for Elasticsearch.
openmetadata-service/src/test/java/org/openmetadata/service/search/SearchSourceBuilderFactoryTest.java Add regression coverage verifying the minimum_should_match floor is present for both backends.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🔴 Playwright Results — workflow failed

Validated commit a9632e5c3d2391c95cededd75b3b2d73dc5454eb in Playwright run 30992648370, attempt 1.

✅ 1023 passed · ❌ 1 failed · 🟡 2 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky

Pipeline and setup failures (1)

  • Playwright performance gate Maximum shard-job elapsed before upload failed (target ≤ 1800 s) — exceeded on 1 shard(s): chromium-02 1832 s.

Performance

Blocking targets: ❌ unmet · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 59m 56s

⏱️ Max setup 3m 11s · max shard execution 19m 17s · max shard-job elapsed before upload 30m 32s · reporting 7s

🌐 189.69 requests/attempt · 2.21 app boots/UI scenario · 13.74% common-shard skew

Optimization targets still in progress:

  • Application boot ratio was 2.21 per UI scenario (2314 boots / 1045 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
🟡 Shard chromium-01 185 0 1 0 0 0
✅ Shard chromium-02 172 0 0 0 0 0
✅ Shard chromium-03 165 0 0 0 0 0
✅ Shard chromium-04 155 0 0 0 0 0
🟡 Shard chromium-05 161 0 1 0 0 0
✅ Shard data-asset-rules-01 61 0 0 0 0 0
✅ Shard domain-isolation-01 14 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 7 0 0 0 0 0
✅ Shard ingestion-01 2 0 0 0 0 0
✅ Shard reindex-01 28 0 0 0 0 0
✅ Shard search-01 11 0 0 0 0 0
🔴 Shard search-rbac-01 28 1 0 0 0 0

Genuine Failures (failed on all attempts)

Flow/SearchRBAC.spec.tsUser with permission (shard search-rbac-01)
Error: �[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeAttached�[2m(�[22m�[2m)�[22m failed  Locator: locator('[data-testid="entity-header-display-name"]').filter({ hasText: 'user_id6bb592f0' }) Expected: attached Timeout: 15000ms Error: element(s) not found  Call log: �[2m  - Expect "toBeAttached" with timeout 15000ms�[22m �[2m  - waiting for locator('[data-testid="entity-header-display-name"]').filter({ hasText: 'user_id6bb592f0' })�[22m 
🟡 2 flaky test(s) (passed on retry)
  • Pages/ExploreBrowse.spec.tsservice type drill-down disables unrelated roots and query-panel Clear resets it (shard chromium-01, 1 retry)
  • Pages/Entity.spec.tsDomain Propagation (shard chromium-05, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

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

Labels

backend safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants