Skip to content

docs(15.9): describe how semantic search works with filters and engine-side rank fusion - #552

Merged
marevol merged 1 commit into
mainfrom
docs/semantic-search-engine-fusion
Sep 24, 2026
Merged

marevol merged 1 commit into
mainfrom
docs/semantic-search-engine-fusion

Conversation

@marevol

@marevol marevol commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Depends on: codelibs/fess#3484, codelibs/fess#3485, codelibs/fess#3487

The text describes Fess with the pending codelibs/fess fixes applied: a cluster that cannot run fused requests at all (unknown hybrid query or search pipeline processor) falls back to fusion in Fess for that search with a WARN, and the next search asks the engine again, so no restart is needed once the plugin is installed; z_score combined with geometric_mean / harmonic_mean is refused with an ERROR log and fused in Fess.

The 15.9 pages on semantic search and rank fusion described 15.8 behaviour in two places and did not document engine-side rank fusion at all:

  • search-semantic.rst said that labels, facets and the file type, site and date conditions of advanced search make semantic search skip. In 15.9 field-qualified conditions (label:, site:, filetype:, timestamp / last_modified ranges, including those added through ex_q and fields.*) are split off the query and applied to the vector search as filters.
  • The deep-paging note only described rank.fusion.window_size, which is the boundary when Fess fuses the results. With rank.fusion.engine.enabled=true the boundary is rank.fusion.pagination_depth.
  • rank.fusion.engine.*, rank.fusion.combination.*, rank.fusion.normalization.technique and rank.fusion.pagination_depth appeared only in the generated properties page, and rank-fusion.rst still said searchers run without a timeout.

Changes

<lang>/15.9/config/search-semantic.rst

  • Conditions become filters on the vector search; list what still skips semantic search: a sort order (sort: or the sort parameter), phrases / wildcards / fuzzy terms / ranges on unqualified words (so a question ending in an ASCII ? is skipped), negated or boosted words, conditions that cannot be separated as a filter (e.g. joined with OR), allintitle: / allinurl:, condition-only queries and unparsable queries. Geo and similar-document searches still skip it.
  • Deep paging: rank.fusion.window_size for fusion in Fess, rank.fusion.pagination_depth for fusion in the search engine (pages beyond it fall back to fusion in Fess).
  • Point to the new engine-side section; note that content_chunker.search.knn.k is raised to at least rank.fusion.pagination_depth in engine mode.

<lang>/15.9/config/rank-fusion.rst

  • New section "Rank Fusion in the Search Engine": requires the OpenSearch neural-search plugin (in the standard distribution and the ghcr.io/codelibs/fess-opensearch image, not in the minimal distribution); rank.fusion.engine.enabled, rank.fusion.combination.technique, rank.fusion.normalization.technique, rank.fusion.combination.weights (name:weight pairs summing to 1.0) and rank.fusion.pagination_depth; z_score normalization can only be combined with arithmetic_mean (a neural-search restriction), and Fess refuses z_score with geometric_mean / harmonic_mean, logs an ERROR naming both settings and fuses that search itself; the cases that fall back to fusion in Fess (as.* parameters, sort / geo / similar-document searches, pages beyond the pagination depth (a DEBUG log for each such search), invalid weights, the z_score combination above, and a cluster that cannot run fused requests at all - missing or too old neural-search plugin - which logs a WARN for each such search and returns to engine-side fusion by itself once the cluster can run it); any other failure of a fused request (invalid query, closed index, shard failure) affects that search only, and the next search is fused by the engine again; rank.fusion.timeout does not apply, and a slow embedding provider delays the search up to the provider's own timeout; the knn k becomes max(content_chunker.search.knn.k, rank.fusion.pagination_depth), so without content_chunker.search.min_score the total hit count can cover most visible documents; rf_score is not added.
  • Replace the "no timeout" note with rank.fusion.timeout; qualify the RRF-only note, the hit-count formula and the troubleshooting steps as applying to fusion in Fess.

All seven languages (ja, en, de, es, fr, ko, zh-cn), 15.9 tree only. The generated properties.rst / .po files are not touched.

Verification

  • Each statement checked against fess main (StructuredQuerySplitter, SemanticChunkSearcher, DefaultSearcher#isEngineFusionApplicable, RankFusionProcessor, QueryStringBuilder, fess_config.properties) and, for the fallback and z_score behaviour, against the two pending fixes.
  • Sphinx HTML build of the 15.9 tree for every language: no warnings in the two changed pages.
  • tools/check_headings.py on the changed files: no mismatches.

The ann-mode content_chunker.search.min_score note in search-semantic.rst now says the warning is logged for each such search instead of once (codelibs/fess#3487).

…e-side rank fusion

search-semantic.rst still said that labels, facets and the file type,
site and date conditions of advanced search make semantic search skip.
In 15.9 those field-qualified conditions are split off the query and
applied to the vector search as filters. List what still skips it
instead: a sort order, phrases, wildcards, fuzzy terms and ranges on
unqualified words (including a question ending in an ASCII "?"),
negated or boosted words, conditions that cannot become a filter,
allintitle:/allinurl:, condition-only and unparsable queries. Deep
paging now names both boundaries: rank.fusion.window_size when Fess
fuses, rank.fusion.pagination_depth when the search engine does.

rank-fusion.rst documented no rank.fusion.engine.* setting. Add a
section on fusing in OpenSearch: the neural-search plugin it needs,
the combination and normalization techniques, per-searcher weights,
rank.fusion.pagination_depth, the z_score/arithmetic_mean restriction
and Fess refusing z_score with the other means, when a search falls
back to fusion in Fess (a cluster that cannot run fused requests at
all falls back with a WARN on each search and is fused by the engine
again once the plugin is installed, without a restart; any other
failed fused request affects that search only; a page past the
pagination depth is logged at DEBUG each time), that rank.fusion.timeout
does not bound the query embedding, and how the knn k and the total
hit count grow with the pagination depth. Replace the note that said
searchers run without a timeout with rank.fusion.timeout, and qualify
the RRF-only note, the hit-count formula and the troubleshooting steps
as applying to fusion in Fess.

The ann-mode min_score note in search-semantic.rst now says the warning
is logged for each such search rather than once.

All seven languages, 15.9 tree only.
@marevol
marevol force-pushed the docs/semantic-search-engine-fusion branch from d0ef272 to a346e33 Compare September 24, 2026 11:56
@marevol marevol self-assigned this Sep 24, 2026
@marevol
marevol merged commit da3d7c5 into main Sep 24, 2026
2 checks passed
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.

1 participant