diff --git a/de/15.9/config/rank-fusion.rst b/de/15.9/config/rank-fusion.rst index d9681515e..8dc9bb004 100644 --- a/de/15.9/config/rank-fusion.rst +++ b/de/15.9/config/rank-fusion.rst @@ -48,10 +48,11 @@ Formel:: .. note:: - Der Fusionsalgorithmus ist fest auf RRF eingestellt; es gibt keine Einstellung, um auf einen - anderen Algorithmus umzuschalten. Ebenso wird keine Gewichtung einzelner Sucher unterstützt — - der Beitrag jedes Suchers geht mit demselben Gewicht in die Summe ein. Die einzige - Stellschraube für die Ranking-Tendenz ist ``rank.fusion.rank_constant``. + Führt |Fess| die Fusion durch (Standard), ist der Algorithmus fest auf RRF eingestellt und es + wird keine Gewichtung einzelner Sucher unterstützt — der Beitrag jedes Suchers geht mit + demselben Gewicht in die Summe ein, und die einzige Stellschraube für die Ranking-Tendenz ist + ``rank.fusion.rank_constant``. Führt die Suchmaschine die Fusion durch, stehen andere + Kombinationsverfahren und Gewichte pro Sucher zur Verfügung (siehe :ref:`rank-fusion-engine`). Einstellungen ============= @@ -157,6 +158,101 @@ Diese Eigenschaft verhält sich wie folgt: ``semantic_chunk`` hinzu. Siehe „Migration von 15.7 oder früheren Versionen" in :doc:`search-semantic` für Details. +.. _rank-fusion-engine: + +Rank Fusion in der Suchmaschine +=============================== + +Mit ``rank.fusion.engine.enabled=true`` führt OpenSearch statt |Fess| die Fusion durch. Die +Anfragen der Sucher werden zu einer einzigen Suchanfrage (einer ``hybrid``-Abfrage) +zusammengefasst, und eine OpenSearch-Such-Pipeline normalisiert und kombiniert die Scores. Da die +Fusion in einer einzigen Anfrage erfolgt, beziehen sich auch die Gesamttrefferzahl und die +Facettenzahlen auf die fusionierte Ergebnismenge. + +Dafür ist das OpenSearch-Plugin neural-search erforderlich. Es ist in der Standarddistribution +von OpenSearch und im Image ``ghcr.io/codelibs/fess-opensearch`` enthalten, nicht jedoch in der +Minimaldistribution. + +Die Einstellungen gehören in ``fess_config.properties`` (eine Änderung erfordert einen Neustart +von |Fess|):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - Eigenschaft + - Standard + - Beschreibung + * - ``rank.fusion.engine.enabled`` + - ``false`` + - Bei ``true`` führt die Suchmaschine die Fusion durch. + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - Wie die Scores kombiniert werden: ``rrf``, ``arithmetic_mean``, ``geometric_mean`` oder ``harmonic_mean``. Bei ``rrf`` wird ``rank.fusion.rank_constant`` als Konstante ``k`` verwendet, sodass sich dieselbe Formel ergibt wie bei der Fusion durch |Fess|. + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - Wie die Scores vor dem Kombinieren normalisiert werden: ``min_max``, ``l2`` oder ``z_score``. Wird von ``rrf`` nicht verwendet. + * - ``rank.fusion.combination.weights`` + - (leer) + - Gewicht pro Sucher als kommagetrennte ``name:weight``-Paare (zum Beispiel ``default:0.7,semantic_chunk:0.3``). Jedes Gewicht muss zwischen ``0.0`` und ``1.0`` liegen, die Gewichte müssen in der Summe ``1.0`` ergeben, und jeder an der Fusion beteiligte Sucher muss genannt werden. Bei leerem Wert werden die Sucher gleich gewichtet. Ein Wert, der diese Regeln nicht erfüllt, wird mit einer ERROR-Meldung protokolliert, und diese Suche wird von |Fess| fusioniert. + * - ``rank.fusion.pagination_depth`` + - ``200`` + - Wie viele Ergebnisse jeder Sucher pro Shard zur Fusion beiträgt. Der Wert begrenzt, wie tief ein Client blättern kann, sowie die Menge der fusionierten Dokumente. + +.. note:: + + Die Normalisierung ``z_score`` lässt sich nur mit ``arithmetic_mean`` kombinieren. Dies ist eine + Einschränkung des Plugins neural-search. Wird sie mit ``geometric_mean`` oder ``harmonic_mean`` + kombiniert, lehnt |Fess| diese Kombination ab, protokolliert eine ERROR-Meldung, die beide + Einstellungen nennt, und fusioniert diese Suche selbst. + +In den folgenden Fällen führt die Suchmaschine die Fusion nicht durch, und stattdessen fusioniert +|Fess| die Ergebnisse. + +- Eine Suche mit Parametern der erweiterten Suche (``as.*``) +- Eine Suche mit Angabe einer Sortierreihenfolge, eine Geolokalisierungssuche oder eine Suche nach + ähnlichen Dokumenten. Diese überspringen die semantische Suche vollständig, sodass nur + Ergebnisse der Schlüsselwortsuche zurückgegeben werden (siehe :doc:`search-semantic`). +- Eine Seite, bei der Startposition plus Seitengröße ``rank.fusion.pagination_depth`` überschreitet + (für jede solche Suche wird eine DEBUG-Meldung protokolliert). Die Fusion durch |Fess| wendet dann die + Grenze von ``rank.fusion.window_size`` an, sodass mit den Standardeinstellungen nur Ergebnisse + der Schlüsselwortsuche zurückgegeben werden. +- Ein Wert von ``rank.fusion.combination.weights``, der die obigen Regeln nicht erfüllt +- Die Normalisierung ``z_score`` in Kombination mit ``geometric_mean`` oder ``harmonic_mean`` (eine + ERROR-Meldung nennt beide Einstellungen) +- Die Suchmaschine kann fusionierte Anfragen überhaupt nicht ausführen: Sie kennt die + ``hybrid``-Abfrage oder den Prozessor der Such-Pipeline nicht, zum Beispiel weil das Plugin + neural-search fehlt oder zu alt ist. Für jede solche Suche wird eine WARN-Meldung protokolliert. + Die nächste Suche wird wieder an die Suchmaschine gerichtet, sodass die Fusion in der Suchmaschine + ohne Neustart von |Fess| wieder aufgenommen wird, sobald das Plugin installiert oder aktualisiert ist. + +Jeder andere Fehler einer fusionierten Anfrage (eine ungültige Abfrage, ein geschlossener Index, ein +Shard-Fehler usw.) wird nur für diese Suche gemeldet, genau wie ohne Fusion in der Suchmaschine, und +die nächste Suche wird wieder von der Suchmaschine fusioniert. + +Beachten Sie Folgendes, wenn die Suchmaschine die Fusion durchführt. + +- ``rank.fusion.timeout`` gilt nicht. Das Embedding der Anfrage wird synchron berechnet, bevor die + Suchanfrage gesendet wird; ein langsamer oder nicht antwortender Embedding-Anbieter verzögert + die Suche daher bis zum Timeout des Anbieters selbst (zum Beispiel + ``content_chunker.embedding.ollama.timeout``). +- ``rank.fusion.window_size`` und ``rank.fusion.threads`` werden nur verwendet, wenn |Fess| die + Fusion durchführt. +- Das ``k`` der knn-Abfrage des semantischen Suchers (die Anzahl der Nachbarn pro Shard) wird zum + größeren der Werte ``content_chunker.search.knn.k`` und ``rank.fusion.pagination_depth``. Eine + Vektorsuche liefert Nachbarn auch dann, wenn ihre Ähnlichkeit gering ist; ohne + ``content_chunker.search.min_score`` enthält die Gesamttrefferzahl daher diese Vektortreffer, + und bei einem kleinen Index kann sie die meisten für den Benutzer sichtbaren Dokumente umfassen. + Setzen Sie ``content_chunker.search.min_score``, um sie einzugrenzen (siehe + :doc:`search-semantic`). +- Das Feld ``searcher`` wird den Ergebnissen wie gewohnt hinzugefügt, ``rf_score`` jedoch nicht. + Integration mit Hybridsuche ============================ @@ -211,7 +307,7 @@ neu:: Auswirkungen auf die Trefferzahl ================================ -Wird Rank Fusion ausgeführt, entspricht die zurückgegebene Gesamttrefferzahl nicht unverändert +Führt |Fess| Rank Fusion durch, entspricht die zurückgegebene Gesamttrefferzahl nicht unverändert der Trefferzahl des Hauptsuchers (des an erster Stelle registrierten ``default``-Suchers), sondern wird wie folgt korrigiert:: @@ -226,6 +322,8 @@ Hybridsuche aktiviert ist oder nicht. Wird die Gesamttrefferzahl des Hauptsuchers als Näherungswert (Untergrenze) zurückgegeben, findet diese Korrektur nicht statt. +Führt die Suchmaschine die Fusion durch, ist die Gesamttrefferzahl die der fusionierten +Ergebnismenge (siehe :ref:`rank-fusion-engine`). Anwendungsbeispiele =================== @@ -294,8 +392,12 @@ Verarbeitungszeit .. note:: - Für die Ausführung der Sucher ist kein Timeout konfiguriert. Antwortet ein Sucher nicht, - wartet die Suchanfrage, bis dieser abgeschlossen ist. + Führt |Fess| die Fusion durch, wird auf andere Sucher als den Hauptsucher bis zu + ``rank.fusion.timeout`` Millisekunden (Standard ``10000``) gewartet. Ein Sucher, der bis dahin + nicht geantwortet hat, wird bei dieser Suche ausgelassen, und die Ergebnisse werden als + unvollständig (Zeitüberschreitung) gekennzeichnet. Auf den Hauptsucher wird stets gewartet. + Bei ``0`` oder kleiner wird ohne Begrenzung gewartet. Diese Einstellung gilt nicht, wenn die + Suchmaschine die Fusion durchführt (siehe :ref:`rank-fusion-engine`). Verhalten bei Fehlern eines Suchers =================================== @@ -327,18 +429,19 @@ Suchergebnisse weichen von Erwartungen ab 1. Prüfen Sie das Feld ``searcher`` (siehe „Fusionsergebnisse überprüfen"). Enthält es bei allen Dokumenten nur ``["default"]``, liefert der semantische Sucher keine Ergebnisse. -2. Prüfen Sie, ob die semantische Suche übersprungen wird. Neben Anfragen, die Suchsyntax - enthalten (etwa ``"``, ``:`` oder ``AND``), liefert der semantische Sucher auch beim - Eingrenzen über Labels, Sortierung oder Facetten sowie bei der Geolokalisierungssuche und der - Suche nach ähnlichen Dokumenten keine Ergebnisse; zurückgegeben werden dann nur die - Ergebnisse der Schlüsselwortsuche. Einzelheiten zu den Bedingungen für das Überspringen - finden Sie unter :doc:`search-semantic`. +2. Prüfen Sie, ob die semantische Suche übersprungen wird. Neben Anfragen, die Suchsyntax wie + Phrasen oder Platzhalter enthalten, liefert der semantische Sucher auch bei sortierten Suchen, + bei der Geolokalisierungssuche und bei der Suche nach ähnlichen Dokumenten keine Ergebnisse; + zurückgegeben werden dann nur die Ergebnisse der Schlüsselwortsuche. Einzelheiten zu den + Bedingungen für das Überspringen finden Sie unter :doc:`search-semantic`. 3. Ergebnisse jedes Suchtyps einzeln überprüfen 4. Den Wert von ``rank.fusion.rank_constant`` anpassen 5. Bei tiefen Seiten (wo ``Startposition × 2`` größer oder gleich ``rank.fusion.window_size`` ist, standardmäßig also ab dem 101. Ergebnis) wird keine Fusion durchgeführt und nur der Hauptsucher wird verwendet. Wenn Sie auf mehr Seiten fusionierte Ergebnisse wünschen, erhöhen - Sie ``rank.fusion.window_size``. + Sie ``rank.fusion.window_size``. Führt die Suchmaschine die Fusion durch, wird eine Seite, bei + der Startposition plus Seitengröße ``rank.fusion.pagination_depth`` überschreitet, stattdessen + von |Fess| fusioniert; erhöhen Sie daher auch ``rank.fusion.pagination_depth``. Suche ist langsam ----------------- diff --git a/de/15.9/config/search-semantic.rst b/de/15.9/config/search-semantic.rst index d54ac5842..5bed6c52d 100644 --- a/de/15.9/config/search-semantic.rst +++ b/de/15.9/config/search-semantic.rst @@ -231,7 +231,8 @@ Einstellungen in system.properties * - ``content_chunker.search.knn.k`` - ``100`` - Anzahl der pro ANN-Abfrage abgerufenen Nachbarn (wird für Deep Paging automatisch - vergrößert) + vergrößert; mindestens ``rank.fusion.pagination_depth``, wenn die Suchmaschine die Fusion + durchführt) * - ``content_chunker.search.knn.param.ef_search`` - (nicht gesetzt) - Der Parameter ``ef_search`` für ANN-Abfragen @@ -526,7 +527,9 @@ Verhalten der semantischen Suche Das Setzen von ``content_chunker.search.enabled=true`` registriert den semantischen Sucher bei Rank Fusion, das dann die Ergebnisse der Schlüsselwortsuche mit denen der Vektorsuche -zusammenführt. (Siehe :doc:`rank-fusion` für die Funktionsweise von Rank Fusion.) +zusammenführt. (Siehe :doc:`rank-fusion` für die Funktionsweise von Rank Fusion.) Standardmäßig +führt |Fess| die Fusion selbst durch; mit ``rank.fusion.engine.enabled=true`` übernimmt dies +stattdessen OpenSearch (siehe :ref:`rank-fusion-engine`). Zur Suchzeit wird zusätzlich ``content_chunker.enabled`` ausgewertet: Bei ``content_chunker.enabled=false`` oder ``content_chunker.embedding.name=none`` findet keine semantische Suche statt, auch wenn der Sucher registriert ist (diese Prüfung erfolgt pro Anfrage, @@ -589,34 +592,50 @@ umgerechnet). Dieser Cutoff wird nur angewendet, wenn ``content_chunker.search.knn.space_type`` auf ``cosinesimil`` (dem Standard) steht. Bei einem Index im Modus ``ann`` mit ``innerproduct`` oder ``l2`` lässt sich keine Kosinusähnlichkeit definieren; der Cutoff wird dann übersprungen, - nachdem einmalig eine Warnung protokolliert wurde. + und für jede solche Suche wird eine Warnung protokolliert. Einschränkungen ------------------ -- **Die semantische Suche wird bei Anfragen mit Suchsyntax übersprungen**, und es läuft nur die - Schlüsselwortsuche. Die Prüfung erfolgt an der **fertig zusammengesetzten** Anfragezeichenkette - und greift, sobald diese eines der Zeichen ``"`` ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` ``}`` - ``^`` ``~`` ``*`` ``?`` ``\``, die Folgen ``&&`` oder ``||``, ein ``+`` bzw. ``-`` am Anfang - oder direkt nach einem Leerzeichen oder eines der Großbuchstabenwörter ``AND`` / ``OR`` / - ``NOT`` / ``TO`` enthält. Auch ohne dass Nutzende selbst Suchsyntax eingeben, wird die - semantische Suche daher bei den folgenden Vorgängen übersprungen. - - - Auswahl eines Labels (intern wird ``label:"..."`` angehängt) - - Angabe einer Sortierbedingung (intern wird ``sort:...`` angehängt) - - Eingrenzung über Facetten (intern wird z. B. ``filetype:...`` angehängt) - - Phrasensuche, Ausschlusswörter, Dateityp, Site und Zeitraum in der erweiterten Suche - - Suchbegriffe mit hinterlegten verwandten Anfragen (intern zu ``("A" OR "B")`` expandiert) - - Da auch das ASCII-Zeichen ``?`` dazugehört, wird ein natürlichsprachlicher Satz, der mit einem - ASCII-Fragezeichen endet (etwa „Was ist ...?"), übersprungen (das Vollbreiten-``?`` zählt - nicht dazu). +- Feldbezogene Bedingungen in der Anfrage (``label:``, ``site:``, ``filetype:``, Bereiche auf + ``timestamp`` / ``last_modified`` usw.) werden vom einzubettenden Text getrennt und als Filter + auf die Vektorsuche angewendet. Die Anfrage wird **nach** ihrer Zusammensetzung untersucht; + Vorgänge, die solche Bedingungen intern anhängen — die Auswahl eines Labels, die Eingrenzung + über Facetten oder Dateityp, Site und Zeitraum der erweiterten Suche, einschließlich + Bedingungen, die über die Parameter ``ex_q`` und ``fields.*`` übergeben werden —, führen die + semantische Suche daher weiterhin aus, eingegrenzt durch dieselben Bedingungen wie die + Schlüsselwortsuche. +- **Die semantische Suche wird** bei den folgenden Anfragen **übersprungen**, und es läuft nur die + Schlüsselwortsuche. + + - Eine Sortierbedingung (das Pseudofeld ``sort:`` oder der Parameter ``sort``, der intern + ebenfalls als ``sort:...`` angehängt wird) + - Eine Phrase (``"..."``), ein Platzhalter (``*`` ``?``), eine unscharfe Suche (``~``) oder ein + Bereich auf Wörtern ohne Feldangabe, einschließlich der Phrase der erweiterten Suche. Das + ASCII-Zeichen ``?`` wird als Platzhalter gelesen, daher wird auch ein natürlichsprachlicher + Satz, der mit einem ASCII-Fragezeichen endet (etwa „Was ist ...?"), übersprungen (das + Vollbreiten-``?`` zählt nicht dazu). + - Das Ausschließen eines Wortes (``-wort``, ``NOT wort``, einschließlich der Ausschlusswörter + der erweiterten Suche) oder dessen Gewichtung (``wort^2``) + - Eine Anfrage, deren Bedingungen sich nicht als Filter abtrennen lassen, etwa ein Wort und eine + Bedingung, die mit ``OR`` verknüpft sind + - ``allintitle:`` / ``allinurl:`` + - Eine Anfrage, die nur Bedingungen und keine einzubettenden Wörter enthält + - Eine Anfrage, die sich nicht parsen lässt + - Sie wird ebenfalls übersprungen, wenn sie mit der Geolokalisierungssuche (einem Geo-Filter) oder der Suche nach ähnlichen Dokumenten kombiniert wird. -- Auf tiefen Ergebnisseiten wird Rank Fusion selbst deaktiviert, sodass nur Ergebnisse der - Schlüsselwortsuche zurückgegeben werden. Die Grenze bestimmt - ``rank.fusion.window_size`` (Standard ``200``); damit betrifft dies standardmäßig alle Treffer - ab dem 101. Suchergebnis. +- Auf tiefen Ergebnisseiten wird Rank Fusion selbst deaktiviert. + + - Führt |Fess| die Fusion durch (Standard), bestimmt ``rank.fusion.window_size`` (Standard + ``200``) die Grenze; standardmäßig werden alle Treffer ab dem 101. Suchergebnis nur aus der + Schlüsselwortsuche geliefert. + - Führt die Suchmaschine die Fusion durch (``rank.fusion.engine.enabled=true``), ist die Grenze + ``rank.fusion.pagination_depth`` (Standard ``200``). Eine Seite, bei der Startposition plus + Seitengröße diesen Wert überschreitet, wird stattdessen von |Fess| fusioniert, und es gilt die + obige Grenze von ``rank.fusion.window_size``. + + Siehe :doc:`rank-fusion` für Details. - Ist der Embedding-Anbieter nicht erreichbar oder tritt ein Suchfehler auf, fällt |Fess| automatisch auf reine Schlüsselwortergebnisse zurück (die Suche selbst schlägt dadurch nie fehl). diff --git a/en/15.9/config/rank-fusion.rst b/en/15.9/config/rank-fusion.rst index 6724bc746..ff0b66e56 100644 --- a/en/15.9/config/rank-fusion.rst +++ b/en/15.9/config/rank-fusion.rst @@ -48,10 +48,11 @@ Formula:: .. note:: - The fusion algorithm is fixed to RRF; there is no setting to switch to a different algorithm. - Per-searcher weighting is not supported either: every searcher contributes with the same weight - when the scores are summed. ``rank.fusion.rank_constant`` is the only setting that lets you - adjust the ranking behavior. + When |Fess| performs the fusion (the default), the algorithm is fixed to RRF and per-searcher + weighting is not supported: every searcher contributes with the same weight when the scores are + summed, and ``rank.fusion.rank_constant`` is the only setting that lets you adjust the ranking + behavior. When the search engine performs the fusion, other combination techniques and + per-searcher weights are available (see :ref:`rank-fusion-engine`). Settings ======== @@ -154,6 +155,94 @@ This property behaves as follows: ``default,semantic``, either remove this setting or add ``semantic_chunk`` to it. See "Migrating from 15.7 or Earlier" in :doc:`search-semantic` for details. +.. _rank-fusion-engine: + +Rank Fusion in the Search Engine +================================ + +Setting ``rank.fusion.engine.enabled=true`` has OpenSearch, rather than |Fess|, perform the fusion. +The searchers' queries are combined into a single search request (a ``hybrid`` query), and an +OpenSearch search pipeline normalizes and combines the scores. Because the fusion happens in one +request, the total hit count and the facet counts also describe the fused result set. + +This requires the OpenSearch neural-search plugin. It is included in the standard OpenSearch +distribution and in the ``ghcr.io/codelibs/fess-opensearch`` image, but not in the minimal +distribution. + +The settings go in ``fess_config.properties`` (a change requires a restart of |Fess|):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - Property + - Default + - Description + * - ``rank.fusion.engine.enabled`` + - ``false`` + - ``true`` has the search engine perform the fusion. + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - How the scores are combined: ``rrf``, ``arithmetic_mean``, ``geometric_mean`` or ``harmonic_mean``. For ``rrf``, ``rank.fusion.rank_constant`` is used as the constant ``k``, giving the same formula as when |Fess| performs the fusion. + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - How the scores are normalized before they are combined: ``min_max``, ``l2`` or ``z_score``. Not used by ``rrf``. + * - ``rank.fusion.combination.weights`` + - (empty) + - Weight per searcher, as comma-separated ``name:weight`` pairs (for example ``default:0.7,semantic_chunk:0.3``). Each weight must be between ``0.0`` and ``1.0``, the weights must sum to ``1.0``, and every searcher taking part in the fusion must be named. Empty weights the searchers equally. A value that does not meet these rules is reported with an ERROR log, and that search is fused by |Fess|. + * - ``rank.fusion.pagination_depth`` + - ``200`` + - How many results each searcher contributes to the fusion per shard. It bounds how deep a client can page and the set of documents that are fused. + +.. note:: + + ``z_score`` normalization can only be combined with ``arithmetic_mean``. This is a restriction of + the neural-search plugin. If it is combined with ``geometric_mean`` or ``harmonic_mean``, |Fess| + refuses the combination, writes an ERROR log naming both settings, and fuses that search itself. + +In the following cases the search engine does not perform the fusion, and |Fess| fuses the results +instead. + +- A search that includes advanced search parameters (``as.*``) +- A search that specifies a sort order, a geolocation search or a similar-document search. These + skip semantic search altogether, so the results are keyword-only (see :doc:`search-semantic`). +- A page whose start position plus page size exceeds ``rank.fusion.pagination_depth`` (a DEBUG log + is written for each such search). Fusion in |Fess| then applies the ``rank.fusion.window_size`` + boundary, so with the default settings the results are keyword-only. +- A ``rank.fusion.combination.weights`` value that does not meet the rules above +- ``z_score`` normalization combined with ``geometric_mean`` or ``harmonic_mean`` (an ERROR log + names both settings) +- The search engine cannot run fused requests at all: it does not know the ``hybrid`` query or the + search pipeline processor, for example because the neural-search plugin is missing or too old. A + WARN log is written for each such search, and the next search asks the search engine again, so + engine-side fusion resumes on its own once the plugin is installed or upgraded, without + restarting |Fess|. + +Any other failure of a fused request (an invalid query, a closed index, a shard failure, and so on) +is reported for that search only, as it would be without engine-side fusion, and the next search is +fused by the search engine again. + +Keep the following in mind when the search engine performs the fusion. + +- ``rank.fusion.timeout`` does not apply. The query embedding is computed synchronously before the + search request is sent, so a slow or unresponsive embedding provider delays the search up to the + provider's own timeout (for example ``content_chunker.embedding.ollama.timeout``). +- ``rank.fusion.window_size`` and ``rank.fusion.threads`` are used only when |Fess| performs the + fusion. +- The ``k`` of the semantic searcher's knn query (the number of neighbors per shard) becomes the + larger of ``content_chunker.search.knn.k`` and ``rank.fusion.pagination_depth``. A vector search + returns neighbors even when their similarity is low, so without + ``content_chunker.search.min_score`` the total hit count includes those vector hits, and on a + small index it can cover most of the documents the user can see. Set + ``content_chunker.search.min_score`` to narrow it (see :doc:`search-semantic`). +- The ``searcher`` field is added to the results as usual, but ``rf_score`` is not. + Integration with Hybrid Search =============================== @@ -204,7 +293,7 @@ following to ``fess_config.properties`` and restart |Fess|:: Impact on Hit Counts ==================== -When Rank Fusion runs, the total hit count that is returned is not the count from the main +When |Fess| performs Rank Fusion, the total hit count that is returned is not the count from the main searcher (the ``default`` searcher registered first) as-is; it is adjusted as follows:: total hits = total hits of the main searcher + adjustment @@ -217,6 +306,8 @@ enabled. Note that this adjustment is not applied when the total hit count of the main searcher is returned as an approximate (lower-bound) value. +When the search engine performs the fusion, the total hit count is that of the fused result set +(see :ref:`rank-fusion-engine`). Usage Examples ============== @@ -284,8 +375,11 @@ Processing Time .. note:: - No timeout is applied to searcher execution. If a searcher never responds, the search request - waits until it completes. + When |Fess| performs the fusion, searchers other than the main one are waited for up to + ``rank.fusion.timeout`` milliseconds (default ``10000``). A searcher that has not answered by + then is left out of that search, and the results are flagged as partial (timed out). The main + searcher is always waited for. ``0`` or less waits without a limit. This setting does not apply + when the search engine performs the fusion (see :ref:`rank-fusion-engine`). Behavior When a Searcher Fails ============================== @@ -317,15 +411,17 @@ Search Results Differ from Expectations 1. Check the ``searcher`` field (see "Verifying Fusion Results"). If every document has only ``["default"]``, the semantic searcher is not returning any results. 2. Check whether semantic search is being skipped. The semantic searcher returns no results, so - only keyword search results are used, for queries that contain search syntax (such as ``"``, - ``:``, or ``AND``), as well as for narrowing by label, sort, or facet, for geo searches, and - for similar-document searches. See :doc:`search-semantic` for details on the skip conditions. + only keyword search results are used, for queries that contain search syntax such as phrases or + wildcards, as well as for sorted searches, geo searches, and similar-document searches. See + :doc:`search-semantic` for details on the skip conditions. 3. Verify the results of each search type individually 4. Adjust the ``rank.fusion.rank_constant`` value 5. On deep pages (where ``start position × 2`` is greater than or equal to ``rank.fusion.window_size``, which by default means from the 101st result onward), fusion is not performed and only the main searcher is used. If you want fused results on more pages, - increase ``rank.fusion.window_size``. + increase ``rank.fusion.window_size``. When the search engine performs the fusion, a page whose + start position plus page size exceeds ``rank.fusion.pagination_depth`` is fused by |Fess| + instead, so increase ``rank.fusion.pagination_depth`` as well. Slow Search ----------- diff --git a/en/15.9/config/search-semantic.rst b/en/15.9/config/search-semantic.rst index 34d63dbc5..8e313da9d 100644 --- a/en/15.9/config/search-semantic.rst +++ b/en/15.9/config/search-semantic.rst @@ -221,7 +221,8 @@ system.properties Settings requires recreating the index) * - ``content_chunker.search.knn.k`` - ``100`` - - Number of neighbors retrieved per ANN query (automatically enlarged for deep paging) + - Number of neighbors retrieved per ANN query (automatically enlarged for deep paging; at + least ``rank.fusion.pagination_depth`` when the search engine performs the fusion) * - ``content_chunker.search.knn.param.ef_search`` - (unset) - The ``ef_search`` parameter for ANN queries @@ -497,7 +498,9 @@ How Semantic Search Behaves Setting ``content_chunker.search.enabled=true`` registers the semantic searcher with Rank Fusion, which then merges keyword search results with vector search results. (See :doc:`rank-fusion` for -how Rank Fusion works.) +how Rank Fusion works.) By default |Fess| performs the fusion itself; setting +``rank.fusion.engine.enabled=true`` has OpenSearch perform it instead (see +:ref:`rank-fusion-engine`). Note that ``content_chunker.enabled`` is also consulted at search time: when ``content_chunker.enabled=false`` or ``content_chunker.embedding.name=none``, semantic search does not run even though the searcher is registered. (This is evaluated per request, so no restart is @@ -556,31 +559,47 @@ converted internally to each mode's score scale. This cutoff is applied only when ``content_chunker.search.knn.space_type`` is ``cosinesimil`` (the default). On an ``ann``-mode index that uses ``innerproduct`` or ``l2``, a cosine - similarity cannot be defined, so the cutoff is skipped after logging a warning once. + similarity cannot be defined, so the cutoff is skipped and a warning is logged for each such search. Limitations ------------- -- **Semantic search is skipped for queries that contain search syntax**, and only keyword search - runs. The check is performed on the query string **after** it has been assembled, and it trips - whenever that string contains any of ``"`` ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` ``}`` ``^`` ``~`` - ``*`` ``?`` ``\``, ``&&``, ``||``, a ``+`` or ``-`` at the start or immediately after - whitespace, or the uppercase words ``AND`` / ``OR`` / ``NOT`` / ``TO``. As a result, the - following operations are skipped too, even when the user typed no search syntax at all. - - - Specifying a label (``label:"..."`` is appended internally) - - Specifying a sort order (``sort:...`` is appended internally) - - Drilling down with a facet (``filetype:...`` and the like are appended internally) - - Advanced search: phrase search, excluded terms, file type, site, and date range - - A search term that has related queries configured (expanded internally to ``("A" OR "B")``) - - The ASCII ``?`` is on that list, so a natural-language question ending in an ASCII question mark - — "what is ...?" — is skipped as well. (The full-width ``?`` is not affected.) +- Field-qualified conditions in the query (``label:``, ``site:``, ``filetype:``, ranges on + ``timestamp`` / ``last_modified``, and so on) are separated from the text to embed and applied + to the vector search as filters. The query is examined **after** it has been assembled, so + operations that append such conditions internally - specifying a label, drilling down with a + facet, or the file type, site and date range of advanced search, including conditions passed + through the ``ex_q`` and ``fields.*`` parameters - still run semantic search, narrowed by the + same conditions as the keyword search. +- **Semantic search is skipped** for the following queries, and only keyword search runs. + + - A sort order (the ``sort:`` pseudo field, or the ``sort`` parameter, which is also appended + internally as ``sort:...``) + - A phrase (``"..."``), wildcard (``*`` ``?``), fuzzy search (``~``) or range on words that name + no field, including the phrase of advanced search. The ASCII ``?`` is read as a wildcard, so a + natural-language question ending in an ASCII question mark - "what is ...?" - is skipped as + well. (The full-width ``?`` is not affected.) + - Excluding a word (``-word``, ``NOT word``, including the excluded words of advanced search) or + boosting one (``word^2``) + - A query whose conditions cannot be separated out as a filter, such as a word and a condition + joined with ``OR`` + - ``allintitle:`` / ``allinurl:`` + - A query that has conditions only, with no words to embed + - A query that cannot be parsed + - It is also skipped when combined with geolocation search (a geo filter) or similar-document search. -- On deep result pages, Rank Fusion itself is disabled and you get keyword-only results. The - boundary is determined by ``rank.fusion.window_size`` (default ``200``), which by default means - everything from result 101 onward. +- On deep result pages, Rank Fusion itself is disabled. + + - When |Fess| performs the fusion (the default), the boundary is determined by + ``rank.fusion.window_size`` (default ``200``); by default everything from result 101 onward + is keyword-only. + - When the search engine performs the fusion (``rank.fusion.engine.enabled=true``), the + boundary is ``rank.fusion.pagination_depth`` (default ``200``). A page whose start position + plus page size exceeds it is fused by |Fess| instead, and the ``rank.fusion.window_size`` + boundary above applies. + + See :doc:`rank-fusion` for details. - If the embedding provider is unreachable or a search error occurs, |Fess| automatically falls back to keyword-only results (the search itself never fails as a result). - Role- and virtual-host-based access control applies to semantic search results as well. diff --git a/es/15.9/config/rank-fusion.rst b/es/15.9/config/rank-fusion.rst index df0b88b72..1536ca3e3 100644 --- a/es/15.9/config/rank-fusion.rst +++ b/es/15.9/config/rank-fusion.rst @@ -48,10 +48,11 @@ Fórmula:: .. note:: - El algoritmo de fusión es siempre RRF; no existe ningún ajuste para cambiar a otro algoritmo. - Tampoco se admite la ponderación por buscador: la contribución de cada buscador se suma con - el mismo peso. El único ajuste que permite modificar la tendencia del ranking es - ``rank.fusion.rank_constant``. + Cuando la fusión la realiza |Fess| (el comportamiento predeterminado), el algoritmo es siempre + RRF y no se admite la ponderación por buscador: la contribución de cada buscador se suma con el + mismo peso, y ``rank.fusion.rank_constant`` es el único ajuste que permite modificar la + tendencia del ranking. Cuando la fusión la realiza el motor de búsqueda, se dispone de otras + técnicas de combinación y de pesos por buscador (consulte :ref:`rank-fusion-engine`). Configuración ============= @@ -157,6 +158,100 @@ Esta propiedad se comporta de la siguiente manera: ``default,semantic``, elimine este ajuste o añada ``semantic_chunk``. Consulte "Migración desde la versión 15.7 o anterior" en :doc:`search-semantic` para más detalles. +.. _rank-fusion-engine: + +Rank Fusion en el motor de búsqueda +=================================== + +Si establece ``rank.fusion.engine.enabled=true``, la fusión la realiza OpenSearch en lugar de +|Fess|. Las consultas de los buscadores se combinan en una única solicitud de búsqueda (una +consulta ``hybrid``), y un search pipeline de OpenSearch normaliza y combina las puntuaciones. +Como la fusión se realiza en una sola solicitud, el número total de resultados y los recuentos de +las facetas también corresponden al conjunto de resultados fusionado. + +Esto requiere el plugin neural-search de OpenSearch. Está incluido en la distribución estándar de +OpenSearch y en la imagen ``ghcr.io/codelibs/fess-opensearch``, pero no en la distribución +mínima. + +Los ajustes se escriben en ``fess_config.properties`` (un cambio requiere reiniciar |Fess|):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - Propiedad + - Valor predeterminado + - Descripción + * - ``rank.fusion.engine.enabled`` + - ``false`` + - ``true`` hace que la fusión la realice el motor de búsqueda. + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - Cómo se combinan las puntuaciones: ``rrf``, ``arithmetic_mean``, ``geometric_mean`` o ``harmonic_mean``. Con ``rrf``, se utiliza ``rank.fusion.rank_constant`` como la constante ``k``, lo que da la misma fórmula que cuando la fusión la realiza |Fess|. + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - Cómo se normalizan las puntuaciones antes de combinarlas: ``min_max``, ``l2`` o ``z_score``. No se utiliza con ``rrf``. + * - ``rank.fusion.combination.weights`` + - (vacío) + - Peso de cada buscador, como pares ``nombre:peso`` separados por comas (por ejemplo, ``default:0.7,semantic_chunk:0.3``). Cada peso debe estar entre ``0.0`` y ``1.0``, los pesos deben sumar ``1.0`` y deben indicarse todos los buscadores que participan en la fusión. Si está vacío, los buscadores tienen el mismo peso. Un valor que no cumple estas reglas se notifica con un registro ERROR, y esa búsqueda la fusiona |Fess|. + * - ``rank.fusion.pagination_depth`` + - ``200`` + - Cuántos resultados aporta cada buscador a la fusión por shard. Limita la profundidad hasta la que un cliente puede paginar y el conjunto de documentos que se fusionan. + +.. note:: + + La normalización ``z_score`` solo puede combinarse con ``arithmetic_mean``. Se trata de una + restricción del plugin neural-search. Si se combina con ``geometric_mean`` o ``harmonic_mean``, + |Fess| rechaza la combinación, escribe un registro ERROR que nombra ambas configuraciones y + fusiona esa búsqueda por sí mismo. + +En los siguientes casos el motor de búsqueda no realiza la fusión, y |Fess| fusiona los +resultados en su lugar. + +- Una búsqueda que incluye parámetros de búsqueda avanzada (``as.*``) +- Una búsqueda que especifica un criterio de ordenación, una búsqueda por geolocalización o una + búsqueda de documentos similares. Estas omiten por completo la búsqueda semántica, por lo que + los resultados provienen solo de la búsqueda por palabras clave (consulte :doc:`search-semantic`). +- Una página cuya posición de inicio más el tamaño de página supera + ``rank.fusion.pagination_depth`` (se escribe un registro DEBUG en cada una de esas búsquedas). En ese caso, la + fusión en |Fess| aplica el límite de ``rank.fusion.window_size``, por lo que con los ajustes + predeterminados los resultados provienen solo de la búsqueda por palabras clave. +- Un valor de ``rank.fusion.combination.weights`` que no cumple las reglas anteriores +- La normalización ``z_score`` combinada con ``geometric_mean`` o ``harmonic_mean`` (un registro + ERROR nombra ambas configuraciones) +- El motor de búsqueda no puede ejecutar solicitudes fusionadas en absoluto: no reconoce la consulta + ``hybrid`` o el procesador del pipeline de búsqueda, por ejemplo porque falta el plugin + neural-search o es demasiado antiguo. Se escribe un registro WARN en cada una de esas búsquedas, y + la siguiente búsqueda vuelve a pedírselo al motor de búsqueda, de modo que la fusión en el motor se + reanuda por sí sola, sin reiniciar |Fess|, en cuanto se instala o actualiza el plugin. + +Cualquier otro fallo de una solicitud fusionada (una consulta no válida, un índice cerrado, un fallo +de shard, etc.) se notifica solo para esa búsqueda, igual que sin la fusión en el motor de búsqueda, +y la siguiente búsqueda vuelve a fusionarla el motor de búsqueda. + +Tenga en cuenta lo siguiente cuando la fusión la realiza el motor de búsqueda. + +- ``rank.fusion.timeout`` no se aplica. El embedding de la consulta se calcula de forma síncrona + antes de enviar la solicitud de búsqueda, por lo que un proveedor de embeddings lento o que no + responde retrasa la búsqueda hasta el tiempo de espera propio del proveedor (por ejemplo, + ``content_chunker.embedding.ollama.timeout``). +- ``rank.fusion.window_size`` y ``rank.fusion.threads`` solo se utilizan cuando la fusión la + realiza |Fess|. +- El ``k`` de la consulta knn del buscador semántico (el número de vecinos por shard) pasa a ser + el mayor entre ``content_chunker.search.knn.k`` y ``rank.fusion.pagination_depth``. Una búsqueda + vectorial devuelve vecinos aunque su similitud sea baja, por lo que, sin + ``content_chunker.search.min_score``, el número total de resultados incluye esos resultados + vectoriales y, en un índice pequeño, puede abarcar la mayoría de los documentos que el usuario + puede ver. Establezca ``content_chunker.search.min_score`` para acotarlo (consulte + :doc:`search-semantic`). +- El campo ``searcher`` se añade a los resultados como de costumbre, pero ``rf_score`` no. + Integración con la búsqueda híbrida ===================================== @@ -210,7 +305,7 @@ por lo que, para consultarlos, establezca lo siguiente en ``fess_config.properti Impacto en el número de resultados ================================== -Cuando se ejecuta Rank Fusion, el número total de resultados devuelto no es sin más el del +Cuando Rank Fusion lo realiza |Fess|, el número total de resultados devuelto no es sin más el del buscador principal (el buscador ``default`` registrado en primer lugar), sino que se corrige de la siguiente manera:: @@ -225,6 +320,8 @@ híbrida está habilitada o no. Tenga en cuenta que, si el número total de resultados del buscador principal se devuelve como un valor aproximado (un límite inferior), esta corrección no se aplica. +Cuando la fusión la realiza el motor de búsqueda, el número total de resultados es el del conjunto +de resultados fusionado (consulte :ref:`rank-fusion-engine`). Ejemplos de uso =============== @@ -293,8 +390,12 @@ Tiempo de procesamiento .. note:: - La ejecución de los buscadores no tiene ningún tiempo de espera configurado. Si algún buscador - no devuelve respuesta, la solicitud de búsqueda espera hasta que este finalice. + Cuando la fusión la realiza |Fess|, se espera a los buscadores distintos del principal un + máximo de ``rank.fusion.timeout`` milisegundos (predeterminado ``10000``). Un buscador que no + ha respondido en ese plazo queda excluido de esa búsqueda, y los resultados se marcan como + parciales (tiempo de espera agotado). Al buscador principal siempre se le espera. Con ``0`` o + menos, se espera sin límite. Este ajuste no se aplica cuando la fusión la realiza el motor de + búsqueda (consulte :ref:`rank-fusion-engine`). Comportamiento cuando falla un buscador ======================================= @@ -327,17 +428,20 @@ Los resultados de búsqueda difieren de lo esperado 1. Verificar el campo ``searcher`` (consulte "Verificación de los resultados de la fusión"). Si todos los documentos muestran únicamente ``["default"]``, el buscador semántico no está devolviendo resultados. -2. Comprobar si la búsqueda semántica se está omitiendo. Además de las consultas que contienen - sintaxis de búsqueda (``"``, ``:``, ``AND``, etc.), en los filtrados por etiqueta, orden o - faceta, en la búsqueda por ubicación y en la búsqueda de documentos similares, el buscador - semántico no devuelve resultados y solo se obtienen los de la búsqueda por palabras clave. - Consulte :doc:`search-semantic` para más detalles sobre las condiciones de omisión. +2. Comprobar si la búsqueda semántica se está omitiendo. En las consultas que contienen sintaxis + de búsqueda como frases o comodines, así como en las búsquedas con ordenación, la búsqueda por + ubicación y la búsqueda de documentos similares, el buscador semántico no devuelve resultados + y solo se obtienen los de la búsqueda por palabras clave. Consulte :doc:`search-semantic` para + más detalles sobre las condiciones de omisión. 3. Verificar los resultados de cada tipo de búsqueda individualmente 4. Ajustar el valor de ``rank.fusion.rank_constant`` 5. En páginas profundas (donde ``posición de inicio × 2`` es mayor o igual que ``rank.fusion.window_size``; de forma predeterminada, a partir del resultado 101), la fusión no se realiza y solo se utiliza el buscador principal. Si desea resultados fusionados en más - páginas, aumente ``rank.fusion.window_size``. + páginas, aumente ``rank.fusion.window_size``. Cuando la fusión la realiza el motor de + búsqueda, una página cuya posición de inicio más el tamaño de página supera + ``rank.fusion.pagination_depth`` la fusiona |Fess| en su lugar, por lo que aumente también + ``rank.fusion.pagination_depth``. La búsqueda es lenta -------------------- diff --git a/es/15.9/config/search-semantic.rst b/es/15.9/config/search-semantic.rst index 1dcfe956d..45e6a19cc 100644 --- a/es/15.9/config/search-semantic.rst +++ b/es/15.9/config/search-semantic.rst @@ -232,7 +232,8 @@ Configuraciones en system.properties * - ``content_chunker.search.knn.k`` - ``100`` - Número de vecinos recuperados por consulta ANN (se amplía automáticamente para paginación - profunda) + profunda; como mínimo ``rank.fusion.pagination_depth`` cuando la fusión la realiza el motor + de búsqueda) * - ``content_chunker.search.knn.param.ef_search`` - (sin establecer) - El parámetro ``ef_search`` para las consultas ANN @@ -528,6 +529,9 @@ Comportamiento de la búsqueda semántica Establecer ``content_chunker.search.enabled=true`` registra el buscador semántico con Rank Fusion, que luego fusiona los resultados de la búsqueda por palabras clave con los resultados de la búsqueda vectorial. (Consulte :doc:`rank-fusion` para saber cómo funciona Rank Fusion.) +De forma predeterminada, |Fess| realiza la fusión por sí mismo; si establece +``rank.fusion.engine.enabled=true``, la realiza OpenSearch en su lugar (consulte +:ref:`rank-fusion-engine`). En el momento de la búsqueda también se consulta ``content_chunker.enabled``: si ``content_chunker.enabled=false`` o ``content_chunker.embedding.name=none``, la búsqueda semántica no se ejecuta aunque el buscador ya esté registrado (esta comprobación se realiza en @@ -589,36 +593,50 @@ modo ``ann`` (internamente se convierte a la escala de puntuación de cada modo) Este corte solo se aplica cuando ``content_chunker.search.knn.space_type`` es ``cosinesimil`` (el valor predeterminado). En un índice en modo ``ann`` configurado con ``innerproduct`` o ``l2`` no se puede definir la similitud de coseno, por lo que el corte se - omite después de registrar una advertencia una sola vez. + omite y se registra una advertencia en cada una de esas búsquedas. Limitaciones -------------- -- **La búsqueda semántica se omite para las consultas que contienen sintaxis de búsqueda** y - solo se ejecuta la búsqueda por palabras clave. La comprobación se realiza sobre la cadena de - consulta ya **ensamblada**, y se activa cuando esta contiene alguno de estos elementos: ``"`` - ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` ``}`` ``^`` ``~`` ``*`` ``?`` ``\``, ``&&``, ``||``, un - ``+`` o un ``-`` al principio o justo después de un espacio, o las palabras en mayúsculas - ``AND`` / ``OR`` / ``NOT`` / ``TO``. Por eso, aunque el usuario no escriba ninguna sintaxis de - búsqueda, las siguientes operaciones también se omiten: - - - Seleccionar una etiqueta (internamente se añade ``label:"..."``) - - Especificar un criterio de ordenación (internamente se añade ``sort:...``) - - Filtrar mediante facetas (internamente se añade ``filetype:...``, etc.) - - En la búsqueda avanzada: búsqueda de frase, términos excluidos, tipo de archivo, sitio y - rango de fechas - - Un término de búsqueda que tiene consultas relacionadas configuradas (internamente se - expande a ``("A" OR "B")``) - - El ``?`` de medio ancho (ASCII) también está incluido, por lo que una frase en lenguaje - natural terminada en signo de interrogación, como «¿Qué es …?», se omite (el ``?`` de ancho - completo no cuenta). +- Las condiciones con campo de la consulta (``label:``, ``site:``, ``filetype:``, rangos sobre + ``timestamp`` / ``last_modified``, etc.) se separan del texto que se convierte en embedding y se + aplican a la búsqueda vectorial como filtros. La consulta se examina ya **ensamblada**, por lo + que las operaciones que añaden internamente este tipo de condiciones - seleccionar una etiqueta, + filtrar mediante facetas, o el tipo de archivo, el sitio y el rango de fechas de la búsqueda + avanzada, incluidas las condiciones pasadas mediante los parámetros ``ex_q`` y ``fields.*`` - + siguen ejecutando la búsqueda semántica, acotada por las mismas condiciones que la búsqueda por + palabras clave. +- **La búsqueda semántica se omite** para las siguientes consultas, y solo se ejecuta la búsqueda + por palabras clave. + + - Un criterio de ordenación (el pseudocampo ``sort:``, o el parámetro ``sort``, que también se + añade internamente como ``sort:...``) + - Una frase (``"..."``), un comodín (``*`` ``?``), una búsqueda difusa (``~``) o un rango sobre + palabras que no indican ningún campo, incluida la frase de la búsqueda avanzada. El ``?`` de + medio ancho (ASCII) se interpreta como comodín, por lo que una pregunta en lenguaje natural + terminada en signo de interrogación ASCII, como «¿Qué es …?», también se omite (el ``?`` de + ancho completo no se ve afectado). + - Excluir una palabra (``-palabra``, ``NOT palabra``, incluidos los términos excluidos de la + búsqueda avanzada) o potenciarla (``palabra^2``) + - Una consulta cuyas condiciones no pueden separarse como filtro, como una palabra y una + condición unidas con ``OR`` + - ``allintitle:`` / ``allinurl:`` + - Una consulta que solo tiene condiciones, sin palabras que convertir en embedding + - Una consulta que no se puede analizar + - También se omite cuando se combina con la búsqueda por geolocalización (un filtro geo) o la búsqueda de documentos similares. -- En las páginas profundas se desactiva el propio Rank Fusion y los resultados provienen solo de - la búsqueda por palabras clave. El límite lo determina ``rank.fusion.window_size`` - (predeterminado ``200``), lo que con los valores predeterminados corresponde a los resultados a - partir del número 101. +- En las páginas profundas se desactiva el propio Rank Fusion. + + - Cuando la fusión la realiza |Fess| (el comportamiento predeterminado), el límite lo determina + ``rank.fusion.window_size`` (predeterminado ``200``); con los valores predeterminados, todos + los resultados a partir del número 101 provienen solo de la búsqueda por palabras clave. + - Cuando la fusión la realiza el motor de búsqueda (``rank.fusion.engine.enabled=true``), el + límite es ``rank.fusion.pagination_depth`` (predeterminado ``200``). Una página cuya posición + de inicio más el tamaño de página lo supera la fusiona |Fess| en su lugar, y se aplica el + límite de ``rank.fusion.window_size`` descrito arriba. + + Consulte :doc:`rank-fusion` para más detalles. - Si el proveedor de embedding no está disponible o se produce un error de búsqueda, |Fess| vuelve automáticamente a los resultados basados solo en palabras clave (la búsqueda en sí nunca falla como resultado). diff --git a/fr/15.9/config/rank-fusion.rst b/fr/15.9/config/rank-fusion.rst index 77a266e9c..8dffeb63b 100644 --- a/fr/15.9/config/rank-fusion.rst +++ b/fr/15.9/config/rank-fusion.rst @@ -49,10 +49,12 @@ Formule :: .. note:: - L'algorithme de fusion est fixé à RRF : aucun réglage ne permet de basculer vers un autre - algorithme. La pondération par moteur de recherche n'est pas non plus prise en charge — la - contribution de chaque moteur est additionnée avec le même poids. Le seul paramètre permettant - d'ajuster la tendance du classement est ``rank.fusion.rank_constant``. + Lorsque |Fess| effectue la fusion (par défaut), l'algorithme est fixé à RRF et la pondération + par moteur de recherche n'est pas prise en charge : la contribution de chaque moteur est + additionnée avec le même poids, et le seul paramètre permettant d'ajuster la tendance du + classement est ``rank.fusion.rank_constant``. Lorsque la fusion est effectuée côté moteur de + recherche, d'autres techniques de combinaison et une pondération par moteur sont disponibles + (voir :ref:`rank-fusion-engine`). Configuration ============= @@ -160,6 +162,101 @@ Ce paramètre se comporte comme suit : « Migration depuis la version 15.7 ou antérieure » dans :doc:`search-semantic` pour plus de détails. +.. _rank-fusion-engine: + +Rank Fusion dans le moteur de recherche +======================================= + +Définir ``rank.fusion.engine.enabled=true`` confie la fusion à OpenSearch plutôt qu'à |Fess|. Les +requêtes des moteurs sont combinées en une seule requête de recherche (une requête ``hybrid``), +et un pipeline de recherche OpenSearch normalise et combine les scores. La fusion ayant lieu en +une seule requête, le nombre total de résultats et le nombre de résultats des facettes portent +eux aussi sur l'ensemble de résultats fusionné. + +Cette fonctionnalité nécessite le plugin neural-search d'OpenSearch. Il est inclus dans la +distribution standard d'OpenSearch et dans l'image ``ghcr.io/codelibs/fess-opensearch``, mais pas +dans la distribution minimale. + +Les réglages se placent dans ``fess_config.properties`` (toute modification nécessite un +redémarrage de |Fess|) :: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - Propriété + - Défaut + - Description + * - ``rank.fusion.engine.enabled`` + - ``false`` + - ``true`` confie la fusion au moteur de recherche. + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - Méthode de combinaison des scores : ``rrf``, ``arithmetic_mean``, ``geometric_mean`` ou ``harmonic_mean``. Avec ``rrf``, ``rank.fusion.rank_constant`` est utilisé comme constante ``k``, ce qui donne la même formule que lorsque |Fess| effectue la fusion. + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - Méthode de normalisation des scores avant leur combinaison : ``min_max``, ``l2`` ou ``z_score``. Non utilisé par ``rrf``. + * - ``rank.fusion.combination.weights`` + - (vide) + - Poids de chaque moteur de recherche, sous forme de paires ``nom:poids`` séparées par des virgules (par exemple ``default:0.7,semantic_chunk:0.3``). Chaque poids doit être compris entre ``0.0`` et ``1.0``, la somme des poids doit valoir ``1.0``, et chaque moteur participant à la fusion doit être nommé. Si la valeur est vide, les moteurs ont tous le même poids. Une valeur qui ne respecte pas ces règles est signalée par un journal ERROR, et la recherche concernée est fusionnée par |Fess|. + * - ``rank.fusion.pagination_depth`` + - ``200`` + - Nombre de résultats que chaque moteur de recherche fournit à la fusion, par shard. Cette valeur borne la profondeur de pagination accessible à un client ainsi que l'ensemble des documents fusionnés. + +.. note:: + + La normalisation ``z_score`` ne peut être combinée qu'avec ``arithmetic_mean``. Il s'agit d'une + restriction du plugin neural-search. Si elle est combinée avec ``geometric_mean`` ou + ``harmonic_mean``, |Fess| refuse cette combinaison, consigne un journal ERROR qui nomme les deux + paramètres et fusionne lui-même la recherche concernée. + +Dans les cas suivants, la fusion n'est pas effectuée côté moteur de recherche, et c'est |Fess| +qui fusionne les résultats à la place. + +- Une recherche comportant des paramètres de recherche avancée (``as.*``) +- Une recherche qui spécifie un critère de tri, une recherche par géolocalisation ou une recherche + de documents similaires. Celles-ci ignorent entièrement la recherche sémantique, de sorte que + les résultats proviennent uniquement de la recherche par mots-clés (voir :doc:`search-semantic`). +- Une page dont la position de début plus la taille de page dépasse + ``rank.fusion.pagination_depth`` (un journal DEBUG est consigné pour chacune de ces recherches). La fusion par + |Fess| applique alors la limite ``rank.fusion.window_size`` : avec les réglages par défaut, les + résultats proviennent donc uniquement de la recherche par mots-clés. +- Une valeur de ``rank.fusion.combination.weights`` qui ne respecte pas les règles ci-dessus +- La normalisation ``z_score`` combinée avec ``geometric_mean`` ou ``harmonic_mean`` (un journal + ERROR nomme les deux paramètres) +- OpenSearch ne peut pas du tout exécuter de requêtes fusionnées : il ne connaît pas la requête + ``hybrid`` ou le processeur du pipeline de recherche, par exemple parce que le plugin + neural-search est absent ou trop ancien. Un journal WARN est consigné pour chacune de ces + recherches, et la recherche suivante interroge de nouveau le moteur de recherche : la fusion par le + moteur reprend d'elle-même, sans redémarrer |Fess|, dès que le plugin est installé ou mis à jour. + +Tout autre échec d'une requête fusionnée (requête invalide, index fermé, défaillance d'un shard, +etc.) n'est signalé que pour la recherche concernée, comme sans fusion côté moteur de recherche, et +la recherche suivante est de nouveau fusionnée côté moteur de recherche. + +Gardez les points suivants à l'esprit lorsque la fusion est effectuée côté moteur de recherche. + +- ``rank.fusion.timeout`` ne s'applique pas. L'embedding de la requête est calculé de manière + synchrone avant l'envoi de la requête de recherche : un fournisseur d'embedding lent ou qui ne + répond pas retarde donc la recherche jusqu'au délai d'expiration propre à ce fournisseur (par + exemple ``content_chunker.embedding.ollama.timeout``). +- ``rank.fusion.window_size`` et ``rank.fusion.threads`` ne sont utilisés que lorsque |Fess| + effectue la fusion. +- Le ``k`` de la requête knn du moteur de recherche sémantique (le nombre de voisins par shard) + devient la plus grande des deux valeurs ``content_chunker.search.knn.k`` et + ``rank.fusion.pagination_depth``. Une recherche vectorielle renvoie des voisins même lorsque + leur similarité est faible : sans ``content_chunker.search.min_score``, le nombre total de + résultats inclut donc ces résultats vectoriels et, sur un petit index, il peut couvrir la plupart + des documents visibles par l'utilisateur. Définissez ``content_chunker.search.min_score`` pour + le restreindre (voir :doc:`search-semantic`). +- Le champ ``searcher`` est ajouté aux résultats comme d'habitude, mais pas ``rf_score``. + Intégration avec la recherche hybride ======================================= @@ -214,7 +311,7 @@ pour les consulter, ajoutez la ligne suivante dans ``fess_config.properties``, p Impact sur le nombre de résultats =================================== -Lorsque le Rank Fusion est exécuté, le nombre total de résultats retourné n'est pas celui du +Lorsque |Fess| exécute le Rank Fusion, le nombre total de résultats retourné n'est pas celui du moteur principal (le moteur ``default``, enregistré en tête de liste) tel quel : il est corrigé comme suit :: @@ -228,6 +325,8 @@ recherche hybride est activée ou non. À noter : lorsque le nombre total de résultats du moteur principal est retourné sous forme de valeur approchée (borne inférieure), cette correction n'est pas appliquée. +Lorsque la fusion est effectuée côté moteur de recherche, le nombre total de résultats est celui de +l'ensemble de résultats fusionné (voir :ref:`rank-fusion-engine`). Exemples d'utilisation ======================= @@ -297,8 +396,12 @@ Temps de traitement .. note:: - Aucun délai d'expiration n'est appliqué à l'exécution des moteurs de recherche. Si l'un d'eux - ne répond pas, la requête de recherche attend qu'il ait terminé. + Lorsque |Fess| effectue la fusion, les moteurs de recherche autres que le moteur principal + sont attendus au plus ``rank.fusion.timeout`` millisecondes (par défaut ``10000``). Un moteur + qui n'a pas répondu dans ce délai est écarté de cette recherche, et les résultats sont marqués + comme partiels (délai dépassé). Le moteur principal est toujours attendu. Une valeur de ``0`` + ou moins attend sans limite. Ce réglage ne s'applique pas lorsque la fusion est effectuée côté + moteur de recherche (voir :ref:`rank-fusion-engine`). Comportement en cas d'échec d'un moteur de recherche ====================================================== @@ -332,17 +435,20 @@ Les résultats de recherche diffèrent des attentes documents ne contiennent que ``["default"]``, le moteur de recherche sémantique ne retourne aucun résultat. 2. Vérifier que la recherche sémantique n'est pas ignorée. Outre les requêtes contenant une - syntaxe de recherche (``"``, ``:``, ``AND``, etc.), le filtrage par label, par tri ou par - facette, la recherche par géolocalisation et la recherche de documents similaires font que le - moteur de recherche sémantique ne retourne aucun résultat : seuls les résultats de la - recherche par mots-clés sont alors renvoyés. Voir :doc:`search-semantic` pour le détail des - conditions d'exclusion. + syntaxe de recherche telle que des phrases ou des caractères génériques, les recherches triées, + la recherche par géolocalisation et la recherche de documents similaires font que le moteur de + recherche sémantique ne retourne aucun résultat : seuls les résultats de la recherche par + mots-clés sont alors renvoyés. Voir :doc:`search-semantic` pour le détail des conditions + d'exclusion. 3. Vérifier les résultats de chaque type de recherche individuellement 4. Ajuster la valeur de ``rank.fusion.rank_constant`` 5. Sur les pages profondes (où ``position de début × 2`` est supérieur ou égal à ``rank.fusion.window_size``, soit à partir du 101e résultat avec les valeurs par défaut), la fusion n'est pas effectuée et seul le moteur principal est utilisé. Pour obtenir des résultats - fusionnés sur davantage de pages, augmentez ``rank.fusion.window_size``. + fusionnés sur davantage de pages, augmentez ``rank.fusion.window_size``. Lorsque la fusion est + effectuée côté moteur de recherche, une page dont la position de début plus la taille de page + dépasse ``rank.fusion.pagination_depth`` est fusionnée par |Fess| à la place : augmentez donc + également ``rank.fusion.pagination_depth``. La recherche est lente ----------------------- diff --git a/fr/15.9/config/search-semantic.rst b/fr/15.9/config/search-semantic.rst index 3f3bd5da0..b0c9739cf 100644 --- a/fr/15.9/config/search-semantic.rst +++ b/fr/15.9/config/search-semantic.rst @@ -236,7 +236,8 @@ Réglages dans system.properties * - ``content_chunker.search.knn.k`` - ``100`` - Nombre de voisins récupérés par requête ANN (agrandi automatiquement pour la pagination - profonde) + profonde ; au moins ``rank.fusion.pagination_depth`` lorsque la fusion est effectuée côté + moteur de recherche) * - ``content_chunker.search.knn.param.ef_search`` - (non défini) - Le paramètre ``ef_search`` pour les requêtes ANN @@ -532,6 +533,8 @@ Comportement de la recherche sémantique Définir ``content_chunker.search.enabled=true`` enregistre le moteur de recherche sémantique auprès du Rank Fusion, qui fusionne ensuite les résultats de la recherche par mots-clés avec ceux de la recherche vectorielle. (Voir :doc:`rank-fusion` pour le fonctionnement du Rank Fusion.) +Par défaut, |Fess| effectue lui-même la fusion ; définir ``rank.fusion.engine.enabled=true`` +la confie plutôt à OpenSearch (voir :ref:`rank-fusion-engine`). Au moment de la recherche, ``content_chunker.enabled`` est également consulté : si ``content_chunker.enabled=false`` ou ``content_chunker.embedding.name=none``, la recherche sémantique n'est pas exécutée, même lorsque le moteur est enregistré (cette évaluation ayant lieu @@ -594,36 +597,51 @@ comme ``ann`` (elle est convertie en interne vers l'échelle de score propre à Cette coupure ne s'applique que lorsque ``content_chunker.search.knn.space_type`` vaut ``cosinesimil`` (la valeur par défaut). Sur un index en mode ``ann`` configuré avec ``innerproduct`` ou ``l2``, aucune similarité cosinus ne peut être définie : la coupure est - ignorée après consignation d'un unique avertissement dans le journal. + ignorée et un avertissement est consigné pour chacune de ces recherches. Limitations ------------- -- **La recherche sémantique est ignorée pour les requêtes contenant une syntaxe de recherche**, - et seule la recherche par mots-clés est exécutée. La détection porte sur la chaîne de requête - **après** son assemblage, et se déclenche dès que celle-ci contient l'un des éléments - suivants : ``"`` ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` ``}`` ``^`` ``~`` ``*`` ``?`` ``\``, - ``&&``, ``||``, un ``+`` ou un ``-`` en début de chaîne ou juste après une espace, ou encore - les mots en majuscules ``AND`` / ``OR`` / ``NOT`` / ``TO``. Les opérations suivantes sont donc - elles aussi ignorées, même si l'utilisateur n'a saisi aucune syntaxe de recherche. - - - La sélection d'un label (``label:"..."`` est ajouté en interne) - - La définition d'un critère de tri (``sort:...`` est ajouté en interne) - - Le filtrage par facette (``filetype:...`` et similaires sont ajoutés en interne) - - La recherche de phrase, les termes exclus, le type de fichier, le site et la plage de dates - de la recherche avancée - - Un terme de recherche auquel des requêtes associées sont attachées (développé en interne en - ``("A" OR "B")``) - - Le ``?`` ASCII faisant partie des caractères détectés, une phrase en langage naturel qui se - termine par un point d'interrogation ASCII est elle aussi ignorée (le point d'interrogation - pleine chasse ``?`` n'est pas concerné). +- Les conditions portant sur un champ dans la requête (``label:``, ``site:``, ``filetype:``, + plages sur ``timestamp`` / ``last_modified``, etc.) sont séparées du texte à vectoriser et + appliquées à la recherche vectorielle sous forme de filtres. La requête est examinée **après** + son assemblage : les opérations qui ajoutent de telles conditions en interne — la sélection + d'un label, le filtrage par facette, ou le type de fichier, le site et la plage de dates de la + recherche avancée, y compris les conditions transmises via les paramètres ``ex_q`` et + ``fields.*`` — exécutent donc toujours la recherche sémantique, restreinte par les mêmes + conditions que la recherche par mots-clés. +- **La recherche sémantique est ignorée** pour les requêtes suivantes, et seule la recherche par + mots-clés est exécutée. + + - Un critère de tri (le pseudo-champ ``sort:``, ou le paramètre ``sort``, qui est lui aussi + ajouté en interne sous la forme ``sort:...``) + - Une phrase (``"..."``), un caractère générique (``*`` ``?``), une recherche floue (``~``) ou + une plage sur des mots qui ne désignent aucun champ, y compris la phrase de la recherche + avancée. Le ``?`` ASCII étant interprété comme un caractère générique, une phrase en langage + naturel qui se termine par un point d'interrogation ASCII est elle aussi ignorée (le point + d'interrogation pleine chasse ``?`` n'est pas concerné). + - L'exclusion d'un mot (``-mot``, ``NOT mot``, y compris les termes exclus de la recherche + avancée) ou son renforcement (``mot^2``) + - Une requête dont les conditions ne peuvent pas être séparées sous forme de filtre, comme un + mot et une condition reliés par ``OR`` + - ``allintitle:`` / ``allinurl:`` + - Une requête ne contenant que des conditions, sans aucun mot à vectoriser + - Une requête qui ne peut pas être analysée + - Elle est également ignorée lorsqu'elle est combinée à une recherche par géolocalisation (un filtre géo) ou à une recherche de documents similaires. -- Sur les pages profondes, le Rank Fusion lui-même est désactivé et les résultats proviennent - uniquement de la recherche par mots-clés. La limite est déterminée par - ``rank.fusion.window_size`` (par défaut ``200``), ce qui correspond, avec les valeurs par - défaut, aux résultats à partir du 101e. +- Sur les pages profondes, le Rank Fusion lui-même est désactivé. + + - Lorsque |Fess| effectue la fusion (par défaut), la limite est déterminée par + ``rank.fusion.window_size`` (par défaut ``200``) ; avec les valeurs par défaut, tous les + résultats à partir du 101e proviennent uniquement de la recherche par mots-clés. + - Lorsque la fusion est effectuée côté moteur de recherche + (``rank.fusion.engine.enabled=true``), la limite est ``rank.fusion.pagination_depth`` (par + défaut ``200``). Une page dont la position de début plus la taille de page dépasse cette + valeur est fusionnée par |Fess| à la place, et la limite ``rank.fusion.window_size`` + ci-dessus s'applique. + + Voir :doc:`rank-fusion` pour plus de détails. - Si le fournisseur d'embedding est inaccessible ou qu'une erreur de recherche survient, |Fess| bascule automatiquement vers des résultats basés uniquement sur les mots-clés (la recherche elle-même n'échoue jamais de ce fait). diff --git a/ja/15.9/config/rank-fusion.rst b/ja/15.9/config/rank-fusion.rst index ebc9b87e1..0a0a4a54d 100644 --- a/ja/15.9/config/rank-fusion.rst +++ b/ja/15.9/config/rank-fusion.rst @@ -47,9 +47,10 @@ RRFは、各検索結果におけるドキュメントの順位の逆数を合 .. note:: - 融合アルゴリズムはRRF固定で、他のアルゴリズムに切り替える設定はありません。 - また、サーチャーごとの重み付けもサポートしていません。各サーチャーの寄与は同じ重みで - 合計されます。ランキングの傾向を調整できるのは ``rank.fusion.rank_constant`` のみです。 + |Fess| 側で融合する場合(既定)、融合アルゴリズムはRRF固定で、サーチャーごとの重み付けも + サポートしていません。各サーチャーの寄与は同じ重みで合計され、ランキングの傾向を調整できる + のは ``rank.fusion.rank_constant`` のみです。検索エンジン側で融合する場合は、他の結合方式や + サーチャーごとの重みを指定できます(:ref:`rank-fusion-engine` を参照)。 設定 ==== @@ -148,6 +149,92 @@ JVMシステムプロパティ ``semantic_chunk`` を追加してください。詳細は :doc:`search-semantic` の 「15.7 以前からアップグレードする場合の移行」を参照してください。 +.. _rank-fusion-engine: + +検索エンジン側でのランクフュージョン +==================================== + +``rank.fusion.engine.enabled=true`` を設定すると、融合を |Fess| ではなく OpenSearch が行います。 +各サーチャーのクエリを1つの検索リクエスト(``hybrid`` クエリ)にまとめ、OpenSearch の検索 +パイプラインでスコアを正規化・結合します。1回のリクエストで融合するため、総ヒット件数と +ファセットの件数も融合後の結果集合を表します。 + +この機能には OpenSearch の neural-search プラグインが必要です。標準配布の OpenSearch と +``ghcr.io/codelibs/fess-opensearch`` イメージには含まれていますが、minimal 配布には含まれません。 + +設定は ``fess_config.properties`` に記述します(変更の反映には |Fess| の再起動が必要です):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - プロパティ + - デフォルト + - 説明 + * - ``rank.fusion.engine.enabled`` + - ``false`` + - ``true`` にすると検索エンジン側で融合します。 + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - スコアの結合方式。\ ``rrf``\ 、\ ``arithmetic_mean``\ 、\ ``geometric_mean``\ 、\ ``harmonic_mean`` のいずれか。\ ``rrf`` の定数 ``k`` には ``rank.fusion.rank_constant`` が使われ、|Fess| 側で融合する場合と同じ計算式になります。 + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - 結合前のスコアの正規化方式。\ ``min_max``\ 、\ ``l2``\ 、\ ``z_score`` のいずれか。\ ``rrf`` では使われません。 + * - ``rank.fusion.combination.weights`` + - (空) + - サーチャーごとの重みを ``名前:重み`` のカンマ区切りで指定します(例: ``default:0.7,semantic_chunk:0.3``)。重みは ``0.0``\ 〜\ ``1.0`` で合計が ``1.0`` になる必要があり、融合に参加するすべてのサーチャーを指定する必要があります。空の場合は均等に扱われます。条件を満たさない場合はERRORログを出力し、その検索は |Fess| 側で融合されます。 + * - ``rank.fusion.pagination_depth`` + - ``200`` + - 各サーチャーがシャードごとに融合へ提供する結果の件数。ページングできる深さと、融合の対象になるドキュメントの範囲を決めます。 + +.. note:: + + ``z_score`` 正規化は ``arithmetic_mean`` とのみ組み合わせられます(neural-search プラグインの + 制約です)。\ ``geometric_mean`` または ``harmonic_mean`` と組み合わせた場合、|Fess| はこの + 組み合わせを使わず、両方の設定名を示すERRORログを出力したうえで、その検索を |Fess| 側で + 融合します。 + +次の場合は検索エンジン側での融合は行われず、|Fess| 側での融合で処理されます。 + +- 詳細検索のパラメーター(``as.*``)を含む検索 +- ソート、位置情報検索、類似ドキュメント検索を指定した検索。これらではセマンティック検索自体が + スキップされるため、キーワード検索のみの結果になります(:doc:`search-semantic` を参照)。 +- 開始位置+ページサイズが ``rank.fusion.pagination_depth`` を超えるページ(該当する検索ごとに + DEBUGログを出力します)。|Fess| 側での融合では ``rank.fusion.window_size`` の境界が適用されるため、 + 既定の設定ではキーワード検索のみの結果になります。 +- ``rank.fusion.combination.weights`` が条件を満たさない場合 +- ``z_score`` 正規化と ``geometric_mean`` または ``harmonic_mean`` を組み合わせた場合(両方の + 設定名を示すERRORログを出力します) +- OpenSearch が融合のリクエストをまったく実行できない場合(``hybrid`` クエリや検索パイプライン + のプロセッサーを認識しない場合。neural-search プラグインがない、または古い場合など)。 + その検索ごとにWARNログを出力します。次の検索では再び OpenSearch に融合を依頼するため、 + プラグインを導入または更新すれば |Fess| を再起動しなくても OpenSearch 側での融合に戻ります。 + +それ以外の理由で融合のリクエストが失敗した場合(不正なクエリ、クローズされたインデックス、 +シャードの障害など)は、検索エンジン側で融合しない場合と同様にその検索に限って報告され、次の +検索は再び検索エンジン側で融合されます。 + +検索エンジン側で融合する場合の注意点は次のとおりです。 + +- ``rank.fusion.timeout`` は適用されません。クエリの埋め込みは検索リクエストの送信前に同期的に + 計算されるため、埋め込みプロバイダの応答が遅い場合や応答しない場合は、検索がプロバイダ側の + タイムアウト(例: ``content_chunker.embedding.ollama.timeout``)まで待たされます。 +- ``rank.fusion.window_size`` と ``rank.fusion.threads`` は、|Fess| 側で融合する場合にのみ + 使われます。 +- セマンティックサーチャーの knn クエリの ``k``\ (シャードごとの近傍数)は、 + ``content_chunker.search.knn.k`` と ``rank.fusion.pagination_depth`` の大きい方になります。 + ベクトル検索は類似度が低いドキュメントも近傍として返すため、\ ``content_chunker.search.min_score`` + を設定していない場合、総ヒット件数にはその分のベクトル検索のヒットが加わり、小規模な + インデックスでは閲覧できるドキュメントのほとんどが件数に含まれることがあります。件数を絞る + には ``content_chunker.search.min_score`` を設定してください(:doc:`search-semantic` を参照)。 +- 検索結果の ``searcher`` フィールドは同様に付与されますが、\ ``rf_score`` は付与されません。 + ハイブリッド検索との連携 ======================== @@ -200,7 +287,7 @@ Rank Fusionが実際に動作しているかは、検索結果に付与される ヒット件数への影響 ================== -Rank Fusionが実行されると、返される総ヒット件数はメインサーチャー(先頭に登録された +|Fess| 側でRank Fusionが実行されると、返される総ヒット件数はメインサーチャー(先頭に登録された ``default`` サーチャー)の件数そのままではなく、次のように補正されます:: 総ヒット件数 = メインサーチャーの総ヒット件数 + 補正値 @@ -211,6 +298,7 @@ Rank Fusionが実行されると、返される総ヒット件数はメインサ そのため、同じクエリでもハイブリッド検索の有効・無効でヒット件数が変わることがあります。 なお、メインサーチャーの総ヒット件数が概算値(下限値)として返される場合、この補正は行われません。 +検索エンジン側で融合する場合、総ヒット件数は融合後の結果集合の件数です(:ref:`rank-fusion-engine` を参照)。 使用例 ====== @@ -276,8 +364,11 @@ Rank Fusionが実行されると、返される総ヒット件数はメインサ .. note:: - サーチャーの実行にタイムアウトは設定されていません。応答が返らないサーチャーがあると、 - 検索リクエストはその完了まで待機します。 + |Fess| 側で融合する場合、メインサーチャー以外のサーチャーは ``rank.fusion.timeout``\ (ミリ秒、 + デフォルト ``10000``)まで待機されます。それまでに応答しないサーチャーはその検索から除外され、 + 検索結果は部分的な結果(タイムアウト)として扱われます。メインサーチャーは常に完了まで待機 + されます。\ ``0`` 以下を指定すると無制限に待機します。検索エンジン側で融合する場合、この設定は + 適用されません(:ref:`rank-fusion-engine` を参照)。 サーチャー障害時の動作 ====================== @@ -306,15 +397,18 @@ WARNログを出力したうえで、残りのサーチャーの結果だけで 1. ``searcher`` フィールドを確認する(「融合結果の確認」を参照)。すべてのドキュメントが ``["default"]`` のみの場合、セマンティックサーチャーが結果を返していません。 -2. セマンティック検索がスキップされていないか確認する。検索構文(``"`` ``:`` ``AND`` など)を - 含むクエリのほか、ラベル・ソート・ファセットによる絞り込み、位置情報検索、類似ドキュメント検索 - では、セマンティックサーチャーは結果を返さずキーワード検索のみの結果になります。 - スキップ条件の詳細は :doc:`search-semantic` を参照してください。 +2. セマンティック検索がスキップされていないか確認する。フレーズやワイルドカードなどの検索構文を + 含むクエリのほか、ソート、位置情報検索、類似ドキュメント検索では、セマンティックサーチャーは + 結果を返さずキーワード検索のみの結果になります。スキップ条件の詳細は :doc:`search-semantic` + を参照してください。 3. 各検索タイプの結果を個別に確認 4. ``rank.fusion.rank_constant`` の値を調整 5. 深いページ(``開始位置 × 2`` が ``rank.fusion.window_size`` 以上になる位置。既定では 101件目以降)では融合が行われず、メインサーチャーのみで検索されます。より多くのページで - 融合結果を利用したい場合は ``rank.fusion.window_size`` を大きくしてください。 + 融合結果を利用したい場合は ``rank.fusion.window_size`` を大きくしてください。検索エンジン側で + 融合する場合は、開始位置+ページサイズが ``rank.fusion.pagination_depth`` を超えるページが + |Fess| 側での融合に切り替わるため、あわせて ``rank.fusion.pagination_depth`` も大きくして + ください。 検索が遅い ---------- diff --git a/ja/15.9/config/search-semantic.rst b/ja/15.9/config/search-semantic.rst index e2b8f1b5a..78fdabf58 100644 --- a/ja/15.9/config/search-semantic.rst +++ b/ja/15.9/config/search-semantic.rst @@ -207,7 +207,8 @@ system.properties の設定 インデックスの再作成が必要) * - ``content_chunker.search.knn.k`` - ``100`` - - ANNクエリで取得する近傍数(ページング範囲が大きい場合は自動的に拡大) + - ANNクエリで取得する近傍数(ページング範囲が大きい場合は自動的に拡大。検索エンジン側で + 融合する場合は ``rank.fusion.pagination_depth`` 以上になります) * - ``content_chunker.search.knn.param.ef_search`` - (未設定) - ANNクエリの ``ef_search`` パラメーター @@ -477,7 +478,9 @@ Docker 版は ``/opt/fess/system.properties``。以下はすべて同じファ ``content_chunker.search.enabled=true`` を設定すると、セマンティックサーチャーが Rank Fusion に登録され、キーワード検索結果とベクトル検索結果が統合されます -(Rank Fusion の仕組みは :doc:`rank-fusion` を参照)。 +(Rank Fusion の仕組みは :doc:`rank-fusion` を参照)。融合は既定では |Fess| が行いますが、 +``rank.fusion.engine.enabled=true`` を設定すると OpenSearch 側で行うこともできます +(:ref:`rank-fusion-engine` を参照)。 なお、検索時には ``content_chunker.enabled`` も参照されます。``content_chunker.enabled=false`` または ``content_chunker.embedding.name=none`` の場合、サーチャーが登録済みでもセマンティック 検索は実行されません(この判定はリクエストごとに行われるため、再起動は不要です)。 @@ -532,30 +535,43 @@ exact モードと ann モード この足切りが適用されるのは、``content_chunker.search.knn.space_type`` が ``cosinesimil``\ (デフォルト)の場合のみです。``innerproduct`` / ``l2`` を指定した ``ann`` - モードのインデックスでは、コサイン類似度を定義できないため、足切りは警告ログを1度出力した - うえでスキップされます。 + モードのインデックスでは、コサイン類似度を定義できないため、足切りはスキップされ、 + 該当する検索ごとに警告ログが出力されます。 制限事項 -------- -- **検索構文を含むクエリでは、セマンティック検索はスキップ** され、キーワード検索のみが実行され - ます。判定はクエリの組み立て **後** の文字列に対して行われ、``"`` ``(`` ``)`` ``:`` ``[`` ``]`` - ``{`` ``}`` ``^`` ``~`` ``*`` ``?`` ``\``、``&&``、``||``、先頭または空白直後の ``+`` / ``-``、 - 大文字の ``AND`` / ``OR`` / ``NOT`` / ``TO`` のいずれかが含まれると対象になります。 - そのため、利用者が検索構文を入力していなくても、以下の操作は同様にスキップされます。 +- クエリに含まれるフィールド指定の条件(``label:``\ 、``site:``\ 、``filetype:``\ 、 + ``timestamp`` / ``last_modified`` の範囲指定など)は、埋め込みの対象から切り離され、ベクトル + 検索にフィルタとして適用されます。判定はクエリの組み立て **後** の文字列に対して行われるため、 + ラベルの指定、ファセットによる絞り込み、詳細検索のファイル種別・サイト・日時の指定など、内部的 + にこうした条件が付加される操作(``ex_q`` や ``fields.*`` パラメーターによるものを含む)でも + セマンティック検索は実行され、キーワード検索と同じ条件で絞り込まれます。 +- 次のクエリでは **セマンティック検索はスキップ** され、キーワード検索のみが実行されます。 + + - ソート条件の指定(``sort:`` 疑似フィールド、または ``sort`` パラメーター。後者も内部的に + ``sort:...`` として付加されます) + - フィールドを指定しない語に対するフレーズ(``"..."``)、ワイルドカード(``*`` ``?``)、 + あいまい検索(``~``)、範囲指定。詳細検索のフレーズ指定も含みます。半角の ``?`` はワイルド + カードとして解釈されるため、「〜とは?」のように半角疑問符で終わる自然文もスキップされます + (全角の ``?`` は対象外です)。 + - 語の除外(``-語``\ 、``NOT 語``\ 。詳細検索の除外語を含む)や語のブースト(``語^2``) + - 語と条件を ``OR`` で結んだクエリなど、条件をフィルタとして切り離せないクエリ + - ``allintitle:`` / ``allinurl:`` + - 条件だけで、埋め込みの対象となる語を含まないクエリ + - 構文解析できないクエリ - - ラベルの指定(内部的に ``label:"..."`` が付加されます) - - ソート条件の指定(内部的に ``sort:...`` が付加されます) - - ファセットによる絞り込み(内部的に ``filetype:...`` などが付加されます) - - 詳細検索のフレーズ検索・除外語・ファイル種別・サイト指定・日時指定 - - 関連クエリが設定された検索語(内部的に ``("A" OR "B")`` に展開されます) - - 半角の ``?`` も対象に含まれるため、「〜とは?」のように半角疑問符で終わる自然文はスキップされ - ます(全角の ``?`` は対象外です)。 - 位置情報検索(ジオフィルタ)や類似ドキュメント検索と併用した場合もスキップされます。 -- 深いページではRank Fusion自体が無効化され、キーワード検索のみの結果になります。境界は - ``rank.fusion.window_size``\ (デフォルト ``200``)で決まり、既定では検索結果の 101 件目以降が - 該当します。 +- 深いページではRank Fusion自体が無効化されます。 + + - |Fess| 側で融合する場合(既定)は、境界は ``rank.fusion.window_size``\ (デフォルト + ``200``)で決まり、既定では検索結果の 101 件目以降がキーワード検索のみの結果になります。 + - 検索エンジン側で融合する場合(``rank.fusion.engine.enabled=true``)は、境界は + ``rank.fusion.pagination_depth``\ (デフォルト ``200``)です。開始位置+ページサイズがこの値を + 超えるページは |Fess| 側での融合で処理され、上記の ``rank.fusion.window_size`` の境界が + 適用されます。 + + 詳細は :doc:`rank-fusion` を参照してください。 - 埋め込みプロバイダに接続できない場合や検索エラーが発生した場合は、自動的にキーワード検索のみの 結果になります(検索自体がエラーになることはありません)。 - ロール・仮想ホストによるアクセス制御は、セマンティック検索結果にも適用されます。 diff --git a/ko/15.9/config/rank-fusion.rst b/ko/15.9/config/rank-fusion.rst index 299fe2486..9ad8e6ac4 100644 --- a/ko/15.9/config/rank-fusion.rst +++ b/ko/15.9/config/rank-fusion.rst @@ -47,9 +47,10 @@ RRF는 각 검색 결과에서 문서의 순위 역수를 합산하여 스코어 .. note:: - 융합 알고리즘은 RRF로 고정되어 있으며, 다른 알고리즘으로 전환하는 설정은 없습니다. - 또한 검색기별 가중치도 지원하지 않습니다. 각 검색기의 기여도는 동일한 가중치로 - 합산됩니다. 랭킹 경향을 조정할 수 있는 것은 ``rank.fusion.rank_constant`` 뿐입니다. + |Fess| 측에서 융합하는 경우(기본값), 융합 알고리즘은 RRF로 고정되어 있으며 검색기별 가중치도 + 지원하지 않습니다. 각 검색기의 기여도는 동일한 가중치로 합산되며, 랭킹 경향을 조정할 수 있는 + 것은 ``rank.fusion.rank_constant`` 뿐입니다. 검색 엔진 측에서 융합하는 경우에는 다른 결합 + 방식이나 검색기별 가중치를 지정할 수 있습니다(:ref:`rank-fusion-engine` 참조). 설정 ==== @@ -149,6 +150,93 @@ JVM 시스템 프로퍼티 :doc:`search-semantic` 의 "15.7 이전 버전에서 업그레이드하는 경우의 마이그레이션"을 참조하세요. +.. _rank-fusion-engine: + +검색 엔진 측에서의 Rank Fusion +================================ + +``rank.fusion.engine.enabled=true`` 를 설정하면 융합을 |Fess|\ 가 아닌 OpenSearch가 수행합니다. +각 검색기의 쿼리를 하나의 검색 요청(``hybrid`` 쿼리)으로 묶고, OpenSearch의 검색 파이프라인에서 +스코어를 정규화·결합합니다. 한 번의 요청으로 융합하므로 총 히트 건수와 패싯 건수도 융합 후의 +결과 집합을 나타냅니다. + +이 기능에는 OpenSearch의 neural-search 플러그인이 필요합니다. 표준 배포판 OpenSearch와 +``ghcr.io/codelibs/fess-opensearch`` 이미지에는 포함되어 있지만, minimal 배포판에는 포함되어 있지 +않습니다. + +설정은 ``fess_config.properties`` 에 작성합니다(변경 사항을 반영하려면 |Fess|\ 를 재시작해야 합니다):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - 프로퍼티 + - 기본값 + - 설명 + * - ``rank.fusion.engine.enabled`` + - ``false`` + - ``true`` 로 설정하면 검색 엔진 측에서 융합합니다. + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - 스코어 결합 방식. ``rrf``, ``arithmetic_mean``, ``geometric_mean``, ``harmonic_mean`` 중 하나. ``rrf`` 의 상수 ``k`` 에는 ``rank.fusion.rank_constant`` 가 사용되며, |Fess| 측에서 융합하는 경우와 동일한 계산식이 됩니다. + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - 결합 전 스코어의 정규화 방식. ``min_max``, ``l2``, ``z_score`` 중 하나. ``rrf`` 에서는 사용되지 않습니다. + * - ``rank.fusion.combination.weights`` + - (비어 있음) + - 검색기별 가중치를 ``이름:가중치`` 의 쉼표 구분 형식으로 지정합니다(예: ``default:0.7,semantic_chunk:0.3``). 각 가중치는 ``0.0``\ ~\ ``1.0`` 이어야 하고 합계가 ``1.0`` 이 되어야 하며, 융합에 참여하는 모든 검색기를 지정해야 합니다. 비어 있으면 균등하게 취급됩니다. 조건을 충족하지 않는 경우에는 ERROR 로그를 출력하고, 해당 검색은 |Fess| 측에서 융합됩니다. + * - ``rank.fusion.pagination_depth`` + - ``200`` + - 각 검색기가 샤드별로 융합에 제공하는 결과 건수. 페이징할 수 있는 깊이와 융합 대상이 되는 문서의 범위를 결정합니다. + +.. note:: + + ``z_score`` 정규화는 ``arithmetic_mean`` 과만 조합할 수 있습니다(neural-search 플러그인의 + 제약입니다). ``geometric_mean`` 또는 ``harmonic_mean`` 과 조합한 경우 |Fess|\ 는 이 조합을 + 사용하지 않고, 두 설정 이름을 나타내는 ERROR 로그를 출력한 뒤 해당 검색을 |Fess| 측에서 + 융합합니다. + +다음 경우에는 검색 엔진 측에서의 융합이 수행되지 않고 |Fess| 측에서의 융합으로 처리됩니다. + +- 상세 검색 파라미터(``as.*``)를 포함하는 검색 +- 정렬, 위치 정보 검색, 유사 문서 검색을 지정한 검색. 이들에서는 시맨틱 검색 자체가 건너뛰어지므로 + 키워드 검색만의 결과가 됩니다(:doc:`search-semantic` 참조). +- 시작 위치+페이지 크기가 ``rank.fusion.pagination_depth`` 를 초과하는 페이지(해당 검색마다 DEBUG + 로그를 출력합니다). |Fess| 측에서의 융합에서는 ``rank.fusion.window_size`` 경계가 적용되므로, + 기본 설정에서는 키워드 검색만의 결과가 됩니다. +- ``rank.fusion.combination.weights`` 가 조건을 충족하지 않는 경우 +- ``z_score`` 정규화를 ``geometric_mean`` 또는 ``harmonic_mean`` 과 조합한 경우(두 설정 이름을 + 나타내는 ERROR 로그를 출력합니다) +- OpenSearch가 융합 요청을 전혀 실행할 수 없는 경우(``hybrid`` 쿼리나 검색 파이프라인의 + 프로세서를 인식하지 못하는 경우. neural-search 플러그인이 없거나 오래된 경우 등). 해당 검색마다 + WARN 로그를 출력합니다. 다음 검색에서는 다시 OpenSearch에 융합을 요청하므로, 플러그인을 설치하거나 + 업데이트하면 |Fess|\ 를 재시작하지 않아도 OpenSearch 측 융합으로 돌아갑니다. + +그 밖의 이유로 융합 요청이 실패한 경우(잘못된 쿼리, 닫힌 인덱스, 샤드 장애 등)는 검색 엔진 측에서 +융합하지 않는 경우와 마찬가지로 해당 검색에 한해 보고되며, 다음 검색은 다시 검색 엔진 측에서 +융합됩니다. + +검색 엔진 측에서 융합하는 경우의 주의 사항은 다음과 같습니다. + +- ``rank.fusion.timeout`` 은 적용되지 않습니다. 쿼리 임베딩은 검색 요청을 보내기 전에 동기적으로 + 계산되므로, 임베딩 프로바이더의 응답이 느리거나 응답하지 않는 경우에는 검색이 프로바이더 측의 + 타임아웃(예: ``content_chunker.embedding.ollama.timeout``)까지 대기하게 됩니다. +- ``rank.fusion.window_size`` 와 ``rank.fusion.threads`` 는 |Fess| 측에서 융합하는 경우에만 + 사용됩니다. +- 시맨틱 서처의 knn 쿼리의 ``k``\ (샤드별 이웃 수)는 ``content_chunker.search.knn.k`` 와 + ``rank.fusion.pagination_depth`` 중 큰 값이 됩니다. 벡터 검색은 유사도가 낮은 문서도 이웃으로 + 반환하므로, ``content_chunker.search.min_score`` 를 설정하지 않은 경우 총 히트 건수에는 그만큼의 + 벡터 검색 히트가 더해지며, 소규모 인덱스에서는 열람할 수 있는 문서의 대부분이 건수에 포함될 수 + 있습니다. 건수를 줄이려면 ``content_chunker.search.min_score`` 를 설정하세요 + (:doc:`search-semantic` 참조). +- 검색 결과의 ``searcher`` 필드는 동일하게 부여되지만, ``rf_score`` 는 부여되지 않습니다. + 하이브리드 검색과의 연계 ========================== @@ -201,7 +289,7 @@ Rank Fusion이 실제로 동작하고 있는지는 검색 결과에 부여되는 히트 건수에 대한 영향 ====================== -Rank Fusion이 실행되면 반환되는 총 히트 건수는 메인 검색기(맨 앞에 등록된 +|Fess| 측에서 Rank Fusion이 실행되면 반환되는 총 히트 건수는 메인 검색기(맨 앞에 등록된 ``default`` 검색기)의 건수 그대로가 아니라 다음과 같이 보정됩니다:: 총 히트 건수 = 메인 검색기의 총 히트 건수 + 보정값 @@ -212,6 +300,7 @@ Rank Fusion이 실행되면 반환되는 총 히트 건수는 메인 검색기( 그래서 같은 쿼리라도 하이브리드 검색의 활성화 여부에 따라 히트 건수가 달라질 수 있습니다. 또한 메인 검색기의 총 히트 건수가 개략값(하한값)으로 반환되는 경우에는 이 보정이 수행되지 않습니다. +검색 엔진 측에서 융합하는 경우, 총 히트 건수는 융합 후 결과 집합의 건수입니다(:ref:`rank-fusion-engine` 참조). 사용 예 ======== @@ -278,8 +367,11 @@ Rank Fusion이 실행되면 반환되는 총 히트 건수는 메인 검색기( .. note:: - 검색기 실행에는 타임아웃이 설정되어 있지 않습니다. 응답을 반환하지 않는 검색기가 있으면 - 검색 요청은 그 검색기가 완료될 때까지 대기합니다. + |Fess| 측에서 융합하는 경우, 메인 검색기 이외의 검색기는 ``rank.fusion.timeout``\ (밀리초, + 기본값 ``10000``)까지 대기합니다. 그때까지 응답하지 않는 검색기는 해당 검색에서 제외되고, + 검색 결과는 부분 결과(타임아웃)로 취급됩니다. 메인 검색기는 항상 완료될 때까지 대기합니다. + ``0`` 이하를 지정하면 무제한으로 대기합니다. 검색 엔진 측에서 융합하는 경우에는 이 설정이 + 적용되지 않습니다(:ref:`rank-fusion-engine` 참조). 검색기 장애 시 동작 ==================== @@ -308,15 +400,17 @@ WARN 로그를 출력한 뒤 나머지 검색기의 결과만으로 융합이 1. ``searcher`` 필드를 확인합니다("융합 결과 확인" 참조). 모든 문서가 ``["default"]`` 만 포함하고 있다면 시맨틱 서처가 결과를 반환하지 않은 것입니다. -2. 시맨틱 검색이 건너뛰어지지 않았는지 확인합니다. 검색 구문(``"`` ``:`` ``AND`` 등)을 - 포함하는 쿼리 외에, 라벨·정렬·패싯에 의한 필터링, 위치 정보 검색, 유사 문서 검색에서는 - 시맨틱 서처가 결과를 반환하지 않고 키워드 검색만의 결과가 됩니다. - 건너뛰는 조건에 대한 자세한 내용은 :doc:`search-semantic` 을 참조하세요. +2. 시맨틱 검색이 건너뛰어지지 않았는지 확인합니다. 구문이나 와일드카드 등의 검색 구문을 + 포함하는 쿼리 외에, 정렬, 위치 정보 검색, 유사 문서 검색에서는 시맨틱 서처가 결과를 반환하지 + 않고 키워드 검색만의 결과가 됩니다. 건너뛰는 조건에 대한 자세한 내용은 :doc:`search-semantic` + 을 참조하세요. 3. 각 검색 유형의 결과를 개별적으로 확인 4. ``rank.fusion.rank_constant`` 값을 조정 5. 깊은 페이지(``시작 위치 × 2`` 가 ``rank.fusion.window_size`` 이상이 되는 위치. 기본값에서는 101번째 이후)에서는 융합이 수행되지 않고 메인 검색기만으로 검색됩니다. 더 많은 페이지에서 - 융합 결과를 사용하려면 ``rank.fusion.window_size`` 를 크게 늘려 주세요. + 융합 결과를 사용하려면 ``rank.fusion.window_size`` 를 크게 늘려 주세요. 검색 엔진 측에서 + 융합하는 경우에는 시작 위치+페이지 크기가 ``rank.fusion.pagination_depth`` 를 초과하는 페이지가 + |Fess| 측에서의 융합으로 전환되므로, ``rank.fusion.pagination_depth`` 도 함께 크게 늘려 주세요. 검색이 느림 ------------ diff --git a/ko/15.9/config/search-semantic.rst b/ko/15.9/config/search-semantic.rst index 6031742c8..55b6018f1 100644 --- a/ko/15.9/config/search-semantic.rst +++ b/ko/15.9/config/search-semantic.rst @@ -205,7 +205,8 @@ system.properties 설정 경고와 함께 ``cosinesimil`` 로 대체됩니다(매핑에 반영됨. 변경하려면 인덱스 재작성이 필요) * - ``content_chunker.search.knn.k`` - ``100`` - - ANN 쿼리당 검색할 이웃 수(딥 페이징 시 자동으로 확대됨) + - ANN 쿼리당 검색할 이웃 수(딥 페이징 시 자동으로 확대됨. 검색 엔진 측에서 융합하는 경우에는 + ``rank.fusion.pagination_depth`` 이상이 됨) * - ``content_chunker.search.knn.param.ef_search`` - (미설정) - ANN 쿼리의 ``ef_search`` 파라미터 @@ -473,7 +474,9 @@ Docker 버전은 ``/opt/fess/system.properties``. 아래 항목은 모두 같은 ``content_chunker.search.enabled=true`` 를 설정하면 시맨틱 서처가 Rank Fusion에 등록되며, 그 이후 키워드 검색 결과와 벡터 검색 결과가 병합됩니다(Rank Fusion의 동작 방식은 -:doc:`rank-fusion` 을 참조하세요). +:doc:`rank-fusion` 을 참조하세요). 융합은 기본적으로 |Fess|\ 가 수행하지만, +``rank.fusion.engine.enabled=true`` 를 설정하면 OpenSearch 측에서 수행할 수도 있습니다 +(:ref:`rank-fusion-engine` 을 참조하세요). 또한 검색 시에는 ``content_chunker.enabled`` 도 함께 참조됩니다. ``content_chunker.enabled=false`` 이거나 ``content_chunker.embedding.name=none`` 인 경우에는 서처가 등록되어 있더라도 시맨틱 검색은 실행되지 않습니다(이 판정은 요청마다 이루어지므로 재시작은 필요하지 않습니다). @@ -528,30 +531,42 @@ exact 모드와 ann 모드 이 컷오프가 적용되는 것은 ``content_chunker.search.knn.space_type`` 이 ``cosinesimil``\ (기본값)인 경우뿐입니다. ``innerproduct`` 나 ``l2`` 를 지정한 ``ann`` 모드 - 인덱스에서는 코사인 유사도를 정의할 수 없으므로, 컷오프는 경고 로그를 한 번 출력한 뒤 - 스킵됩니다. + 인덱스에서는 코사인 유사도를 정의할 수 없으므로, 컷오프는 스킵되며 해당 검색마다 경고 + 로그가 출력됩니다. 제한 사항 ---------- -- **검색 구문을 포함하는 쿼리에서는 시맨틱 검색이 스킵**\ 되고 키워드 검색만 실행됩니다. 판정은 - 쿼리를 조립한 **뒤**\ 의 문자열에 대해 이루어지며, ``"`` ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` - ``}`` ``^`` ``~`` ``*`` ``?`` ``\``, ``&&``, ``||``, 맨 앞 또는 공백 바로 뒤의 ``+`` / ``-``, - 대문자 ``AND`` / ``OR`` / ``NOT`` / ``TO`` 중 하나라도 포함되면 대상이 됩니다. 따라서 사용자가 - 검색 구문을 입력하지 않았더라도 다음 조작은 마찬가지로 스킵됩니다. +- 쿼리에 포함된 필드 지정 조건(``label:``\ , ``site:``\ , ``filetype:``\ , ``timestamp`` / + ``last_modified`` 의 범위 지정 등)은 임베딩 대상에서 분리되어 벡터 검색에 필터로 적용됩니다. + 판정은 쿼리를 조립한 **뒤**\ 의 문자열에 대해 이루어지므로, 라벨 지정, 패싯을 이용한 좁히기, + 상세 검색의 파일 종류·사이트·일시 지정 등 내부적으로 이러한 조건이 부가되는 조작(``ex_q`` 나 + ``fields.*`` 파라미터에 의한 것을 포함)에서도 시맨틱 검색이 실행되며, 키워드 검색과 동일한 + 조건으로 좁혀집니다. +- 다음 쿼리에서는 **시맨틱 검색이 스킵**\ 되고 키워드 검색만 실행됩니다. + + - 정렬 조건 지정(``sort:`` 의사 필드 또는 ``sort`` 파라미터. 후자도 내부적으로 + ``sort:...`` 로 부가됩니다) + - 필드를 지정하지 않은 단어에 대한 구문(``"..."``), 와일드카드(``*`` ``?``), 퍼지 검색(``~``), + 범위 지정. 상세 검색의 구문 지정도 포함합니다. 반각 ``?`` 는 와일드카드로 해석되므로, + "~란?"처럼 반각 물음표로 끝나는 자연문도 스킵됩니다(전각 ``?`` 는 대상이 아닙니다). + - 단어 제외(``-단어``\ , ``NOT 단어``\ . 상세 검색의 제외어 포함)나 단어 부스트(``단어^2``) + - 단어와 조건을 ``OR`` 로 연결한 쿼리 등, 조건을 필터로 분리할 수 없는 쿼리 + - ``allintitle:`` / ``allinurl:`` + - 조건만 있고 임베딩 대상이 되는 단어를 포함하지 않는 쿼리 + - 구문 분석할 수 없는 쿼리 - - 라벨 지정(내부적으로 ``label:"..."`` 이 부가됩니다) - - 정렬 조건 지정(내부적으로 ``sort:...`` 이 부가됩니다) - - 패싯을 이용한 좁히기(내부적으로 ``filetype:...`` 등이 부가됩니다) - - 상세 검색의 구문 검색·제외어·파일 종류·사이트 지정·일시 지정 - - 연관 쿼리가 설정된 검색어(내부적으로 ``("A" OR "B")`` 로 전개됩니다) - - 반각 ``?`` 도 대상에 포함되므로, "~란?"처럼 반각 물음표로 끝나는 자연문도 스킵됩니다(전각 - ``?`` 는 대상이 아닙니다). - 위치 정보 검색(지오 필터) 또는 유사 문서 검색과 조합된 경우에도 스킵됩니다. -- 깊은 페이지에서는 Rank Fusion 자체가 비활성화되어 키워드 검색만의 결과가 됩니다. 경계는 - ``rank.fusion.window_size``\ (기본값 ``200``)로 결정되며, 기본 설정에서는 검색 결과의 101번째 - 이후가 여기에 해당합니다. +- 깊은 페이지에서는 Rank Fusion 자체가 비활성화됩니다. + + - |Fess| 측에서 융합하는 경우(기본값)에는 경계가 ``rank.fusion.window_size``\ (기본값 + ``200``)로 결정되며, 기본 설정에서는 검색 결과의 101번째 이후가 키워드 검색만의 결과가 됩니다. + - 검색 엔진 측에서 융합하는 경우(``rank.fusion.engine.enabled=true``)에는 경계가 + ``rank.fusion.pagination_depth``\ (기본값 ``200``)입니다. 시작 위치+페이지 크기가 이 값을 + 초과하는 페이지는 |Fess| 측의 융합으로 처리되며, 위의 ``rank.fusion.window_size`` 경계가 + 적용됩니다. + + 자세한 내용은 :doc:`rank-fusion` 을 참조하세요. - 임베딩 프로바이더에 연결할 수 없거나 검색 오류가 발생한 경우, |Fess|\ 는 자동으로 키워드 검색만의 결과로 폴백합니다(그 결과로 검색 자체가 실패하는 일은 없습니다). - 역할 및 가상 호스트 기반 접근 제어는 시맨틱 검색 결과에도 적용됩니다. diff --git a/zh-cn/15.9/config/rank-fusion.rst b/zh-cn/15.9/config/rank-fusion.rst index cf7f348aa..73abb2f2a 100644 --- a/zh-cn/15.9/config/rank-fusion.rst +++ b/zh-cn/15.9/config/rank-fusion.rst @@ -46,9 +46,10 @@ RRF 通过对每个搜索结果中文档排名的倒数求和来计算分数。 .. note:: - 融合算法固定为 RRF,没有可切换到其他算法的设置。 - 此外,也不支持按搜索器设置权重。各搜索器的贡献会以相同的权重进行合计。 - 唯一能够调整排名倾向的设置是 ``rank.fusion.rank_constant``\ 。 + 由 |Fess| 执行融合时(默认),融合算法固定为 RRF,也不支持按搜索器设置权重。各搜索器的贡献 + 会以相同的权重进行合计,唯一能够调整排名倾向的设置是 ``rank.fusion.rank_constant``\ 。 + 由搜索引擎执行融合时,可以使用其他组合方式,并可按搜索器指定权重(请参阅 + :ref:`rank-fusion-engine`\ )。 配置 ==== @@ -143,6 +144,86 @@ JVM 系统属性 DEBUG 级别记录)。如果您的配置中指定了 ``default,semantic``\ ,请移除该设置,或为其添加 ``semantic_chunk``\ 。详情请参阅 :doc:`search-semantic` 中的“从 15.7 及更早版本迁移”一节。 +.. _rank-fusion-engine: + +在搜索引擎中执行 Rank Fusion +============================ + +设置 ``rank.fusion.engine.enabled=true`` 后,融合将由 OpenSearch 而非 |Fess| 执行。 +各搜索器的查询会合并为一个搜索请求(``hybrid`` 查询),并由 OpenSearch 的搜索管道对分数进行 +归一化和组合。由于融合在一次请求中完成,总命中数量和分面数量也反映融合后的结果集。 + +此功能需要 OpenSearch 的 neural-search 插件。标准发行版的 OpenSearch 和 +``ghcr.io/codelibs/fess-opensearch`` 镜像中已包含该插件,但 minimal 发行版中不包含。 + +配置写入 ``fess_config.properties``\ (更改后需要重启 |Fess| 才能生效):: + + rank.fusion.engine.enabled=true + rank.fusion.combination.technique=rrf + rank.fusion.normalization.technique=min_max + rank.fusion.combination.weights= + rank.fusion.pagination_depth=200 + +.. list-table:: + :header-rows: 1 + :widths: 30 15 55 + + * - 属性 + - 默认值 + - 说明 + * - ``rank.fusion.engine.enabled`` + - ``false`` + - 设为 ``true`` 时由搜索引擎执行融合。 + * - ``rank.fusion.combination.technique`` + - ``rrf`` + - 分数的组合方式:\ ``rrf``\ 、\ ``arithmetic_mean``\ 、\ ``geometric_mean`` 或 ``harmonic_mean``\ 。对于 ``rrf``\ ,\ ``rank.fusion.rank_constant`` 会用作常数 ``k``\ ,计算公式与由 |Fess| 执行融合时相同。 + * - ``rank.fusion.normalization.technique`` + - ``min_max`` + - 组合前对分数进行归一化的方式:\ ``min_max``\ 、\ ``l2`` 或 ``z_score``\ 。\ ``rrf`` 不使用此设置。 + * - ``rank.fusion.combination.weights`` + - (空) + - 各搜索器的权重,以逗号分隔的 ``名称:权重`` 对指定(例如 ``default:0.7,semantic_chunk:0.3``)。每个权重必须在 ``0.0`` 到 ``1.0`` 之间,权重之和必须为 ``1.0``\ ,并且必须指定参与融合的所有搜索器。为空时各搜索器权重相等。不满足这些规则的值会输出 ERROR 日志,该次搜索将由 |Fess| 执行融合。 + * - ``rank.fusion.pagination_depth`` + - ``200`` + - 每个搜索器在每个分片上提供给融合的结果数量。它限制了客户端可以翻页的深度,以及参与融合的文档范围。 + +.. note:: + + ``z_score`` 归一化只能与 ``arithmetic_mean`` 组合使用。这是 neural-search 插件的限制。 + 如果与 ``geometric_mean`` 或 ``harmonic_mean`` 组合,|Fess| 会拒绝该组合,输出指明这两个设置的 + ERROR 日志,并由 |Fess| 对该次搜索执行融合。 + +在以下情况下,不会由搜索引擎执行融合,而是改由 |Fess| 融合结果。 + +- 包含高级搜索参数(``as.*``)的搜索 +- 指定了排序、位置信息搜索或相似文档搜索的搜索。这些搜索会完全跳过语义搜索,因此结果仅来自 + 关键词搜索(请参阅 :doc:`search-semantic`\ )。 +- 起始位置加上每页大小超过 ``rank.fusion.pagination_depth`` 的页面(每次这样的搜索都会输出 DEBUG 日志)。 + 此时由 |Fess| 执行的融合会适用 ``rank.fusion.window_size`` 的分界,因此在默认配置下结果仅来自 + 关键词搜索。 +- ``rank.fusion.combination.weights`` 的值不满足上述规则时 +- ``z_score`` 归一化与 ``geometric_mean`` 或 ``harmonic_mean`` 组合时(会输出指明这两个设置的 + ERROR 日志) +- 搜索引擎完全无法执行融合请求时(无法识别 ``hybrid`` 查询或搜索管道的处理器,例如缺少 + neural-search 插件或其版本过旧)。每次这样的搜索都会输出 WARN 日志。下一次搜索会再次请求 + OpenSearch 执行融合,因此安装或升级插件后,无需重启 |Fess| 即可恢复由 OpenSearch 执行融合。 + +融合请求因其他原因失败时(无效的查询、已关闭的索引、分片故障等),与不由搜索引擎执行融合时一样, +仅针对该次搜索进行报告,下一次搜索会再次由搜索引擎执行融合。 + +由搜索引擎执行融合时,请注意以下几点。 + +- ``rank.fusion.timeout`` 不适用。查询的嵌入会在发送搜索请求之前同步计算,因此如果嵌入提供商 + 响应缓慢或无响应,搜索会一直等待,最长直到提供商自身的超时时间(例如 + ``content_chunker.embedding.ollama.timeout``\ )。 +- ``rank.fusion.window_size`` 和 ``rank.fusion.threads`` 仅在由 |Fess| 执行融合时使用。 +- 语义搜索器 knn 查询的 ``k``\ (每个分片的近邻数量)取 ``content_chunker.search.knn.k`` 与 + ``rank.fusion.pagination_depth`` 中较大的值。向量搜索即使在相似度较低时也会返回近邻,因此在未设置 + ``content_chunker.search.min_score`` 的情况下,总命中数量会包含这些向量搜索的命中,在小规模索引中 + 可能涵盖用户可见的大部分文档。若要缩小范围,请设置 ``content_chunker.search.min_score``\ (请参阅 + :doc:`search-semantic`\ )。 +- 搜索结果中照常附加 ``searcher`` 字段,但不会附加 ``rf_score``\ 。 + 与混合搜索的集成 ================ @@ -192,7 +273,7 @@ Rank Fusion 在结合关键词搜索与语义搜索的 对命中数量的影响 ================ -执行 Rank Fusion 时,返回的总命中数量并非直接使用主搜索器(注册在首位的 ``default`` +由 |Fess| 执行 Rank Fusion 时,返回的总命中数量并非直接使用主搜索器(注册在首位的 ``default`` 搜索器)的数量,而是按如下方式进行修正:: 总命中数量 = 主搜索器的总命中数量 + 修正值 @@ -203,6 +284,7 @@ Rank Fusion 在结合关键词搜索与语义搜索的 因此,即使是相同的查询,启用与不启用混合搜索时的命中数量也可能不同。 另外,当主搜索器的总命中数量以概算值(下限值)返回时,不会进行此修正。 +由搜索引擎执行融合时,总命中数量为融合后结果集的数量(请参阅 :ref:`rank-fusion-engine`\ )。 使用示例 ======== @@ -268,7 +350,10 @@ Rank Fusion 在结合关键词搜索与语义搜索的 .. note:: - 搜索器的执行没有设置超时。如果存在不返回响应的搜索器,搜索请求将一直等待其完成。 + 由 |Fess| 执行融合时,主搜索器以外的搜索器最多等待 ``rank.fusion.timeout`` 毫秒(默认 + ``10000``\ )。届时仍未响应的搜索器会从该次搜索中排除,搜索结果会被标记为部分结果(超时)。 + 主搜索器始终会等待至完成。指定 ``0`` 或以下时将无限制地等待。由搜索引擎执行融合时,此设置 + 不适用(请参阅 :ref:`rank-fusion-engine`\ )。 搜索器故障时的行为 ================== @@ -296,15 +381,16 @@ Rank Fusion 在结合关键词搜索与语义搜索的 1. 确认 ``searcher`` 字段(请参阅“融合结果的确认”)。如果所有文档都仅为 ``["default"]``\ ,则说明语义搜索器没有返回结果。 -2. 确认语义搜索是否被跳过。除了包含搜索语法(如 ``"`` ``:`` ``AND`` 等)的查询之外, - 在通过标签、排序、分面进行筛选,以及位置信息搜索、相似文档搜索时,语义搜索器也不会返回 - 结果,仅返回关键词搜索的结果。 +2. 确认语义搜索是否被跳过。除了包含短语、通配符等搜索语法的查询之外,在排序搜索、位置信息搜索、 + 相似文档搜索时,语义搜索器也不会返回结果,仅返回关键词搜索的结果。 跳过条件的详细信息请参阅 :doc:`search-semantic`\ 。 3. 分别确认各搜索类型的结果 4. 调整 ``rank.fusion.rank_constant`` 的值 5. 在翻页较深的页面(``起始位置 × 2`` 大于等于 ``rank.fusion.window_size`` 的位置,默认情况下 为第 101 条之后)不会执行融合,仅使用主搜索器进行搜索。若希望在更多页面上获得融合结果, - 请增大 ``rank.fusion.window_size``\ 。 + 请增大 ``rank.fusion.window_size``\ 。由搜索引擎执行融合时,起始位置加上每页大小超过 + ``rank.fusion.pagination_depth`` 的页面会改由 |Fess| 执行融合,因此请同时增大 + ``rank.fusion.pagination_depth``\ 。 搜索缓慢 -------- diff --git a/zh-cn/15.9/config/search-semantic.rst b/zh-cn/15.9/config/search-semantic.rst index 8f5e5f18a..4cb154b04 100644 --- a/zh-cn/15.9/config/search-semantic.rst +++ b/zh-cn/15.9/config/search-semantic.rst @@ -192,7 +192,8 @@ system.properties 配置 ``cosinesimil``\ (会反映到映射中;更改需要重新创建索引) * - ``content_chunker.search.knn.k`` - ``100`` - - 每次 ANN 查询检索的邻居数量(深分页时会自动放大) + - 每次 ANN 查询检索的邻居数量(深分页时会自动放大;由搜索引擎执行融合时,至少为 + ``rank.fusion.pagination_depth``\ ) * - ``content_chunker.search.knn.param.ef_search`` - (未设置) - ANN 查询的 ``ef_search`` 参数 @@ -448,6 +449,8 @@ Docker 为 ``/opt/fess/system.properties``\ 。以下各项均写入同一个文 设置 ``content_chunker.search.enabled=true`` 会将语义搜索器注册到 Rank Fusion 中,之后它会将 关键词搜索结果与向量搜索结果合并。(有关 Rank Fusion 的工作原理,请参阅 :doc:`rank-fusion`\ 。) +默认情况下由 |Fess| 自身执行融合;设置 ``rank.fusion.engine.enabled=true`` 后,改由 OpenSearch +执行融合(请参阅 :ref:`rank-fusion-engine`\ )。 另外,搜索时还会参照 ``content_chunker.enabled``\ 。当 ``content_chunker.enabled=false`` 或 ``content_chunker.embedding.name=none`` 时,即使搜索器已经注册,也不会执行语义搜索(该判断按每次 请求进行,因此无需重启)。 @@ -499,28 +502,38 @@ exact 模式与 ann 模式 仅当 ``content_chunker.search.knn.space_type`` 为 ``cosinesimil``\ (默认值)时,该阈值才会 生效。对于指定了 ``innerproduct`` / ``l2`` 的 ``ann`` 模式索引,由于无法定义余弦相似度, - 该阈值会在输出一次警告日志后被跳过。 + 该阈值会被跳过,并且每次这样的搜索都会输出警告日志。 限制事项 -------- -- **若查询中包含检索语法,将跳过语义搜索**\ ,仅执行关键词搜索。该判定是针对查询组装\ **之后**\ 的 - 字符串进行的:只要其中出现 ``"`` ``(`` ``)`` ``:`` ``[`` ``]`` ``{`` ``}`` ``^`` ``~`` ``*`` - ``?`` ``\``、``&&``、``||``、位于开头或紧跟空白之后的 ``+`` / ``-``\ ,或者大写的 ``AND`` / - ``OR`` / ``NOT`` / ``TO``\ ,就会命中该判定。因此,即使用户本身并未输入检索语法,以下操作 - 同样会被跳过。 +- 查询中带字段限定的条件(``label:``、``site:``、``filetype:``、``timestamp`` / ``last_modified`` + 的范围等)会从用于嵌入的文本中分离出来,并作为过滤条件应用于向量搜索。由于查询是在组装 + **之后**\ 才被分析的,因此,即使是在内部附加此类条件的操作——指定标签、通过分面进行筛选, + 以及高级搜索中的文件类型、站点指定、日期时间指定,包括通过 ``ex_q`` 和 ``fields.*`` 参数传入的 + 条件——也仍会执行语义搜索,并按与关键词搜索相同的条件进行筛选。 +- 对于以下查询,\ **将跳过语义搜索**\ ,仅执行关键词搜索。 + + - 指定排序条件(``sort:`` 伪字段,或 ``sort`` 参数,后者在内部同样会以 ``sort:...`` 的形式附加) + - 针对未指定字段的词语的短语(``"..."``)、通配符(``*`` ``?``)、模糊搜索(``~``)或范围, + 包括高级搜索中的短语。半角的 ``?`` 会被视为通配符,因此像“……是什么?”这样以半角问号结尾的 + 自然语句也会被跳过(全角的 ``?`` 不在范围内)。 + - 排除词语(``-word``、``NOT word``\ ,包括高级搜索中的排除词)或提升权重(``word^2``) + - 无法将条件作为过滤条件分离出来的查询,例如用 ``OR`` 连接词语与条件的查询 + - ``allintitle:`` / ``allinurl:`` + - 只有条件、没有可用于嵌入的词语的查询 + - 无法解析的查询 - - 指定标签(内部会附加 ``label:"..."``\ ) - - 指定排序条件(内部会附加 ``sort:...``\ ) - - 通过分面进行筛选(内部会附加 ``filetype:...`` 等) - - 高级搜索中的短语搜索、排除词、文件类型、站点指定、日期时间指定 - - 配置了相关查询的检索词(内部会展开为 ``("A" OR "B")``\ ) - - 半角的 ``?`` 同样在判定范围内,因此像“……是什么?”这样以半角问号结尾的自然语句也会被跳过 - (全角的 ``?`` 不在范围内)。 - 与地理位置搜索(地理过滤)或相似文档搜索结合使用时,同样会被跳过。 -- 在较深的页码上,Rank Fusion 本身会被禁用,结果将仅来自关键词搜索。分界由 - ``rank.fusion.window_size``\ (默认 ``200``)决定,默认情况下对应搜索结果的第 101 条及以后。 +- 在较深的页码上,Rank Fusion 本身会被禁用。 + + - 由 |Fess| 执行融合时(默认),分界由 ``rank.fusion.window_size``\ (默认 ``200``)决定; + 默认情况下,搜索结果的第 101 条及以后仅来自关键词搜索。 + - 由搜索引擎执行融合时(``rank.fusion.engine.enabled=true``),分界为 + ``rank.fusion.pagination_depth``\ (默认 ``200``)。起始位置加上每页大小超过该值的页面改由 + |Fess| 执行融合,并适用上述 ``rank.fusion.window_size`` 的分界。 + + 详情请参阅 :doc:`rank-fusion`\ 。 - 如果嵌入提供商不可访问,或发生搜索错误,|Fess| 会自动回退为仅使用关键词搜索的结果(搜索本身 不会因此失败)。 - 基于角色和虚拟主机的访问控制同样适用于语义搜索结果。