8000 fix(api): resolve indices_boost keys before searching, like ES by amartya1523 · Pull Request #2977 · xerj-org/xerj · GitHub
[go: up one dir, main page]

Skip to content

fix(api): resolve indices_boost keys before searching, like ES - #2977

Open
amartya1523 wants to merge 2 commits into
xerj-org:mainfrom
amartya1523:fix/indices-boost-missing
Open

amartya1523 wants to merge 2 commits into
xerj-org:mainfrom
amartya1523:fix/indices-boost-missing

Conversation

@amartya1523
Copy link
Copy Markdown
Contributor

AI-assisted change, run and reviewed by @amartya1523.

What this changes, and why

ES resolves every indices_boost key against the cluster before the search runs (TransportSearchAction#resolveIndexBoosts). It uses the request's own IndicesOptions, so a boost key follows the same rules as a search target:

key ES XERJ before
names no index or alias 404 index_not_found_exception, no such index [x] 200, key silently dropped
same, with ignore_unavailable=true skipped, search answers same
cluster:index (remote) 400 illegal_argument_exception, even with ignore_unavailable 200, key silently dropped
date math <name-{now/d}> boosts the index it resolves to 200, matched raw, never boosted
wildcard matching nothing allowed allowed

XERJ applied boosts after the cross-index merge and skipped any key it couldn't match. A typo in a boost answered 200 with every score unboosted, which looks like the boost "didn't matter". Two catch-lenient.txt lines are this case:

  • search/40_indices_boost.yml · Indices boost for nonexistent index/alias
  • search/40_indices_boost.yml · Remote expressions not supported in indices boost

Fix (es_compat.rs):

  • New index_boost_resolution_error runs in search_impl after target resolution, the closed-index pass and allow_no_indices handling, and before anything executes. It walks the keys in request order, as ES's loop does, so the first failing entry is the one reported:
    • A remote key returns 400 illegal_argument_exception: Cross-cluster calls are not supported in this context but remote indices were requested: [remote1:test_1]. New is_remote_index_name mirrors RemoteClusterAware#isRemoteIndexName: a : after the first character, unless the key is date math.
    • _all and wildcard keys pass, since they may match nothing.
    • Other keys are date-math resolved (resolve_date_math_index, as the target path does). They pass if an open index or an alias has that name.
    • With ignore_unavailable=true, an unknown key is skipped.
    • Otherwise, a closed index gets the existing index_closed_exception and anything else gets XerjError::index_not_found. The ApiError rendering already gives ES's no such index [x] envelope with resource.type, resource.id and index_uuid.
  • Date-math boosts: the existing apply loop now resolves date math on each key too, so <test_2> boosts test_2.

Unchanged: alias and wildcard resolution, first-match-wins across overlapping keys (putIfAbsent in ES, find here), and the object shorthand {"idx": 2.0}.

Evidence

New test module indices_boost_resolution_tests (es_compat.rs), run against main first:

# main 83c9f0d12
test es_compat::indices_boost_resolution_tests::unresolvable_boost_keys_are_refused ... FAILED
  left: 200
 right: 404
test es_compat::indices_boost_resolution_tests::resolvable_boost_keys_still_apply ... FAILED
  left: Number(1.0)      <- the `<test_2>` date-math boost was dropped
 right: 2.0

# this branch
test es_compat::indices_boost_resolution_tests::resolvable_boost_keys_still_apply ... ok
test es_compat::indices_boost_resolution_tests::unresolvable_boost_keys_are_refused ... ok
  • First test: [{nonexistent}, {test_1}] asserts the 404, the type and no such index [nonexistent]. [{nonexistent}, {remote1:test_1}] with ignore_unavailable=true asserts the 400, the type and the exact reason.

  • Second test: four requests:

    • an unknown key under ignore_unavailable
    • a wildcard that matches nothing
    • the object form
    • an alias plus a date-math key

    Each asserts 2 hits, test_2 first, and its boosted _score of 2.0.

Checks

  • cargo fmt -p xerj-api -- --check
  • cargo test --profile quick -p xerj-api --lib: 432 passed, 0 failed
  • YAML: both existing 40_indices_boost.yml cases now enforce it; their catch-lenient lines are deleted. The other five cases in that file (names, aliases, wildcards, multiple matches) use keys that resolve, so they're unaffected. No other YAML file or integration test uses indices_boost.
  • Docs: none describe the old behaviour.

Not run locally:

  • The ES-YAML suite, --release builds, clippy and the integration binaries. Disk on this machine is at 99%; CI runs all of these.

Provenance

  • Written by: AI-assisted, run and reviewed by @amartya1523
  • Verified: the test outputs above, on macOS 26 (aarch64), quick profile, based on main 83c9f0d12.
  • Assumed:
    • The YAML only matches the remote reason's prefix; the bracketed list follows ES's Arrays.toString formatting.
    • allow_no_indices=false with a wildcard key that matches nothing is still allowed here. ES would 404 that, but it's rare and I kept this change to concrete names.
    • _msearch and _search/template don't go through search_impl's resolution, so they're not covered.

ES resolves every indices_boost key against the cluster before the
search runs (TransportSearchAction#resolveIndexBoosts), with the
request's indices options. A key that names no index or alias is a 404
index_not_found_exception, or skipped under ignore_unavailable, and a
cluster:index key is refused with illegal_argument_exception even then.
XERJ applied boosts after the merge and dropped any key it could not
match, so a typo in a boost answered 200 with every score unboosted.

A date-math key now names the index it resolves to, as the search
target already does; it was matched raw and never boosted.

Retires the two search/40_indices_boost.yml catch-lenient entries.
Unknown and remote keys are refused; names, aliases, empty wildcards, date math, the object form and unknown names under ignore_unavailable still search
8000
 with the boost applied.
@cla-bot cla-bot Bot added the cla-signed label Nov 5, 2026

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0