Skip to content

Fixes #34954: keep the parent of every glossary search match in the hierarchy - #35221

Merged
yan-3005 merged 1 commit into
mainfrom
fix/glossary-hierarchy-search-missing-parents
Oct 12, 2026
Merged

yan-3005 merged 1 commit into
mainfrom
fix/glossary-hierarchy-search-missing-parents

Conversation

@sonika-shah

Copy link
Copy Markdown
Collaborator

Describe your changes:

Fixes #34954

Glossary term search with getHierarchy=true (used by the glossary term picker) can return a glossary with no terms under it, even though terms matched.

Why: the page (e.g. 25) holds the matches and the parent terms needed to draw the tree, ranked together. With more matches than the page holds, the parents rank below the cut. buildGlossaryTermSearchHierarchy only attaches a term whose parent is in the response, so every match is dropped and the glossary comes back as children: [].

What changed:

  • Missing parents are fetched after the cut. One exact-FQN lookup for the parents of the page's matches (Approved only, same as the search). It runs only when a parent is missing; if it fails, it logs and falls back to the previous behaviour.
  • Parents no longer take page slots from matches. For glossary terms the parent-term clauses score 0, so the page is filled by the best matches by relevance; parents fill leftover slots and the rest are fetched as above. The fqnParts aggregation flow is unchanged. Domain search is unchanged.
  • Same change in ElasticSearchSearchManager and OpenSearchSearchManager.

The parent lookup builds on the backfill from #34955 (2.0). That PR keeps the picker's UI changes; this PR carries the backend fix for main, to be backported to 2.0.

Type of change:

  • Bug fix

Tests:

  • GlossaryTermResourceIT#test_hierarchySearchKeepsParentOfEveryMatchOnThePage: one parent that doesn't match + 30 matching children, searched with size=25&getHierarchy=true. Asserts the parent is returned with all 25 matches under it.
    • Without the fix: fails (Parent of the matches should be returned even though it ranks last, glossary has no children).
    • With the fix: passes (MySQL + Elasticsearch 9.3).
Details

Scoring. Each match also matches its own exact-FQN clause, so normally matches outrank pure parents. But the fqnParts aggregation is capped at 1000 buckets ordered by doc count; with many matches in deep glossaries, a leaf's own-FQN bucket (count 1) is cut first, the match loses that clause, and a parent can outrank it. Wrapping the parent clauses in constant_score with boost: 0 removes parents from ranking entirely. Checked on Elasticsearch 9.3 and OpenSearch 3.4: matches come back ordered by relevance, the parent last with score 0.

Parent lookup. Parents are derived from each hit's FQN (term level only; the glossary root still comes from each hit's glossary field) and fetched with a terms query on fullyQualifiedName (lowercase-normalized keyword). One query, bounded by page size × depth.

Not in scope. Matches ranked below the page are still not returned; that needs paging in the picker's search mode.

…ierarchy

Hierarchy search (getHierarchy=true) ranks matches and their parent terms
in one page. With more matches than the page holds, the parents rank below
the cut and buildGlossaryTermSearchHierarchy drops every match whose parent
is missing, so the glossary comes back with no children.

- Fetch the missing parents of the page's matches in one exact-FQN lookup
  after the cut (Approved only, same as the search). On failure, log and
  fall back to the previous behaviour.
- Score the parent-term clauses 0 for glossary terms, so parents never take
  a page slot from a real match. Domain search is unchanged.

Same change in the Elasticsearch and OpenSearch managers, plus an IT that
fails without it.
@sonika-shah
sonika-shah requested a review from a team as a code owner October 12, 2026 05:42
@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Oct 12, 2026
@gitar-bot

gitar-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Code Review ✅ Approved

🟡 Medium risk · Zero-scoring glossary parent clauses and fetching missing ancestors change search results; failed lookups could leave returned matches detached from the hierarchy.

Fixes glossary term search with getHierarchy=true returning glossaries with no terms under them when matches overflow the page. Missing parent terms are now fetched after the page cut, and parent-term clauses are scored at 0 so parents no longer take slots from matches, in both the Elasticsearch and OpenSearch search managers. No issues found.

Verification

Rules No rules evaluated

Functional validation Not enabled

Set up

Auto-approval Not enabled

Set up

Options

Display: compact → Counting what did not apply, without listing it.

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

Compact
gitar display:verbose         

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

@yan-3005
yan-3005 added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit cda0297 Oct 12, 2026
72 checks passed
@yan-3005
yan-3005 deleted the fix/glossary-hierarchy-search-missing-parents branch October 12, 2026 22:34
sonika-shah added a commit that referenced this pull request Oct 13, 2026
… the hierarchy (#35221, #35284) (#35287)

* Fixes #34954: keep the parent of every glossary search match in the hierarchy (#35221)

Hierarchy search (getHierarchy=true) ranks matches and their parent terms
in one page. With more matches than the page holds, the parents rank below
the cut and buildGlossaryTermSearchHierarchy drops every match whose parent
is missing, so the glossary comes back with no children.

- Fetch the missing parents of the page's matches in one exact-FQN lookup
  after the cut (Approved only, same as the search). On failure, log and
  fall back to the previous behaviour.
- Score the parent-term clauses 0 for glossary terms, so parents never take
  a page slot from a real match. Domain search is unchanged.

Same change in the Elasticsearch and OpenSearch managers, plus an IT that
fails without it.

(cherry picked from commit cda0297)

* Fixes #34954: make the glossary hierarchy search IT independent of other tests

The hierarchy search IT waited for "search(word) total == 30" over the
whole shared index. Glossary search matches fuzzily and on name n-grams,
so other tests' terms counted too and it failed in the parallel lane with
33. Its page and child-count checks had the same exposure, and it never
cleaned up its terms.

- No wait or global count: entity create indexes synchronously with a
  refresh, so the terms are searchable when create returns.
- Every search is post-filtered to the test's own glossary.
- The search word uses letters absent from all generated names, so
  parents can never match it or take a page slot from a match.
- The glossary is hard-deleted recursively in finally.
- Adds the same check for matches nested four levels deep.

(cherry picked from commit 72b7051)

* Hold the search-settings read lock and make cleanup best-effort in hierarchy ITs

The hierarchy search ITs depend on the shared glossary-term search
settings, so take SEARCH_SETTINGS in READ mode: they never overlap a test
that rewrites the settings under the READ_WRITE lock, and still run
alongside other readers. A failed cleanup delete no longer fails a test
whose assertions passed; the glossary is namespace-scoped.

(cherry picked from commit 9bcc2ce)
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.

[2.0] Glossary term picker search hides nested matches and returns empty glossaries

2 participants