diff --git a/de/15.8/dev/ingest-plugin.rst b/de/15.8/dev/ingest-plugin.rst index 7c728ab0..5f6fd8b1 100644 --- a/de/15.8/dev/ingest-plugin.rst +++ b/de/15.8/dev/ingest-plugin.rst @@ -5,74 +5,177 @@ Ingest-Plugin Übersicht ========= -Ingest-Plugins bieten Funktionen zur Verarbeitung und Transformation von Daten, -bevor Dokumente im Index registriert werden. +Ingest-Plugins bieten eine Funktion zur Verarbeitung und Transformation von +Daten, unmittelbar bevor Dokumente im Index registriert werden. Jedes durch +den Crawl abgerufene Dokument durchläuft vor der Übermittlung an den Index +die registrierten Ingester. -Anwendungsfalle +Anwendungsfälle =============== -- Textnormalisierung (z.B. Vollbreite/Halbbreite-Konvertierung) -- Hinzufugen von Metadaten +- Textnormalisierung (z. B. Konvertierung zwischen Vollbreiten- und + Halbbreitenzeichen, Formatierung von Leerzeichen usw.) +- Hinzufügen von Metadaten oder benutzerdefinierten Feldern - Maskierung sensibler Informationen -- Hinzufugen benutzerdefinierter Felder +- Umwandlung von Werten (z. B. Dekodierung kodierter Vektor-Embeddings) -Grundimplementierung -==================== +Ingester-Klasse +=============== + +Die Ingest-Funktion wird implementiert, indem die abstrakte Klasse +``org.codelibs.fess.ingest.Ingester`` erweitert wird. ``Ingester`` stellt +``process``-Methoden bereit, die je nach Crawl-Typ und Verarbeitungsphase +aufgerufen werden. Da alle Standardimplementierungen das empfangene +``target`` unverändert zurückgeben (also nichts tun), müssen nur die +benötigten Methoden überschrieben werden. + +- ``protected Map process(Map target)`` + + Dies ist das gemeinsame Delegationsziel der beiden ``Map``-Varianten der + Methode. Wird diese Methode überschrieben, gilt sie sowohl für Dokumente + aus dem Datenspeicher-Crawl als auch für Dokumente aus dem Web-/Datei-Crawl + (bei der Indexregistrierung). Für die meisten Anwendungsfälle genügt es, + nur diese Methode zu überschreiben. + +- ``public Map process(Map target, DataStoreParams params)`` + + Wird beim Datenspeicher-Crawl aufgerufen. Standardmäßig wird an + ``process(target)`` delegiert. + +- ``public Map process(Map target, AccessResult accessResult)`` + + Wird bei der Indexregistrierung im Web-/Datei-Crawl aufgerufen. + Standardmäßig wird an ``process(target)`` delegiert. + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Wird bei der Antwortverarbeitung im Web-/Datei-Crawl aufgerufen (bevor das + Zugriffsergebnis gespeichert wird). Standardmäßig wird ``target`` + unverändert zurückgegeben. + +Ausführungsreihenfolge (priority) +---------------------------------- + +Wenn mehrere Ingester registriert sind, werden sie in aufsteigender +Reihenfolge des Felds ``priority`` ausgeführt (kleinere Werte zuerst). Der +Standardwert ist ``99``. Er kann direkt im Konstruktor gesetzt oder über +``setPriority(int)`` geändert werden. + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +Implementierungsbeispiel +========================= -Implementieren Sie das ``IngestHandler``-Interface: +Ein Beispiel, bei dem ``process(Map)`` überschrieben wird, +um den Inhalt zu normalisieren und ein benutzerdefiniertes Feld +hinzuzufügen: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // Ausführungsreihenfolge festlegen (kleinere Werte werden zuerst ausgeführt; Standard ist 99) + setPriority(50); + } @Override - public Map process(Map document) { - // Inhaltsnormalisierung - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + protected Map process(final Map target) { + // Normalisierung des Inhalts + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } - // Benutzerdefiniertes Feld hinzufugen - document.put("processed_at", new Date()); - - return document; - } + // Hinzufügen eines benutzerdefinierten Felds + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // Normalisierungslogik - return text.trim().replaceAll("\\s+", " "); + // Das verarbeitete Dokument zurückgeben + return target; } } +.. note:: + + Wenn die ``process``-Methode ``null`` zurückgibt, schlägt die + Indexregistrierung fehl. Da es keinen Mechanismus zum Überspringen von + Dokumenten gibt, muss stets ``target`` zurückgegeben werden. + Registrierung ============= -``fess_ingest.xml``: +Ingester werden über den DI-Container registriert. Das Plugin enthält dafür +die Datei ``fess_ingest++.xml``. Das ``++`` am Ende des Dateinamens ist eine +Merge-Konvention, mit der die Konfiguration an die Datei +``fess_ingest.xml`` (welche die ``ingestFactory``, die die Ingester +verwaltet, definiert) der |Fess|-Kernanwendung angehängt wird. .. code-block:: xml - - - + + + + + + + -Konfiguration -============= +Durch ```` wird nach der Erzeugung der +Komponente ``Ingester#register()`` aufgerufen, wodurch sie sich selbst bei +der ``ingestFactory`` registriert. + +Für die Ingest-Funktion gibt es keine Konfigurationseinträge in +``fess_config.properties``. Aktivierung bzw. Deaktivierung erfolgt durch das +Vorhandensein des Plugins, und die Ausführungsreihenfolge wird über +``priority`` gesteuert. + +Ausführungsablauf +================== + +Ingester werden unmittelbar bevor das verarbeitete Dokument an den Index +übermittelt wird, an den folgenden Stellen in aufsteigender Reihenfolge von +``priority`` aufgerufen: + +- **Datenspeicher-Crawl**: Unmittelbar bevor das Dokument gesendet wird, + wird ``process(Map, DataStoreParams)`` aufgerufen. +- **Web-/Datei-Crawl (bei der Antwortverarbeitung)**: Bevor das + Crawl-Ergebnis gespeichert wird, wird ``process(ResultData, ResponseData)`` + aufgerufen. +- **Web-/Datei-Crawl (bei der Indexregistrierung)**: Unmittelbar bevor das + Dokument gesendet wird, wird ``process(Map, AccessResult)`` aufgerufen. + +In allen Fällen wird, wenn ein Ingester eine Ausnahme auslöst, eine +Warnmeldung protokolliert und die Verarbeitung fortgesetzt (die +Indexregistrierung des betreffenden Dokuments wird dadurch nicht +abgebrochen). + +.. note:: + + Da Ingester in der Ausführungsumgebung des Crawlers (``ingestFactory``) + registriert werden, arbeiten sie als Teil des Crawl-Prozesses. -``fess_config.properties``: +Referenzimplementierungen +========================== -:: +Als Referenz für die Implementierung sind die folgenden Plugins auf GitHub +unter `CodeLibs `__ veröffentlicht: - ingest.handler.example.enabled=true +- ``fess-ingest-example`` - Minimalistische Beispielimplementierung +- ``fess-webapp-multimodal`` - Plugin mit ``EmbeddingIngester``, der + Vektor-Embeddings dekodiert Referenzinformationen -===================== +====================== - :doc:`plugin-architecture` - Plugin-Architektur diff --git a/en/15.8/dev/ingest-plugin.rst b/en/15.8/dev/ingest-plugin.rst index fd767d43..133bbfca 100644 --- a/en/15.8/dev/ingest-plugin.rst +++ b/en/15.8/dev/ingest-plugin.rst @@ -6,74 +6,169 @@ Overview ======== Ingest plugins provide functionality to process and transform data -before documents are registered in the index. +immediately before a document is registered in the index. Each document +retrieved by a crawl passes through the registered Ingesters before it is +sent to the index. Use Cases ========= -- Text normalization (full-width/half-width conversion, etc.) -- Adding metadata +- Text normalization (full-width/half-width conversion, whitespace formatting, etc.) +- Adding metadata or custom fields - Masking sensitive information -- Adding custom fields +- Value conversion (e.g., decoding encoded vector embeddings) -Basic Implementation -==================== +Ingester Class +============== -Implement the ``IngestHandler`` interface: +Ingest functionality is implemented by extending the +``org.codelibs.fess.ingest.Ingester`` abstract class. ``Ingester`` provides +``process`` methods that are invoked depending on the type of crawl and the +processing stage. Since the default implementations simply return the +received ``target`` unchanged (i.e., do nothing), you only need to override +the methods you actually need. + +- ``protected Map process(Map target)`` + + This is the common delegation target for the two ``Map``-based methods. + Overriding this method applies it to documents from both data store crawls + and web/file crawls (at index registration time). For most use cases, + overriding only this method is sufficient. + +- ``public Map process(Map target, DataStoreParams params)`` + + Called during a data store crawl. By default, it delegates to + ``process(target)``. + +- ``public Map process(Map target, AccessResult accessResult)`` + + Called when registering a document from a web/file crawl into the index. + By default, it delegates to ``process(target)``. + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Called during response processing of a web/file crawl (before the access + result is saved). By default, it returns ``target`` unchanged. + +Execution Order (priority) +--------------------------- + +When multiple Ingesters are registered, they are executed in ascending +order of the ``priority`` field (lower values run first). The default +value is ``99``. You can set it directly in the constructor, or change it +using ``setPriority(int)``. + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +Implementation Example +======================= + +The following example overrides ``process(Map)`` to +normalize the content and add a custom field: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // Set the execution order (lower values execute first; default is 99) + setPriority(50); + } @Override - public Map process(Map document) { - // Content normalization - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + protected Map process(final Map target) { + // Normalize the content + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } - // Add custom field - document.put("processed_at", new Date()); - - return document; - } + // Add a custom field + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // Normalization logic - return text.trim().replaceAll("\\s+", " "); + // Return the processed document + return target; } } +.. note:: + + Returning ``null`` from the ``process`` method will cause index + registration to fail. There is no mechanism for skipping a document, + so always return ``target``. + Registration ============ -``fess_ingest.xml``: +Ingesters are registered via the DI container. Include ``fess_ingest++.xml`` +in your plugin. The ``++`` suffix in the file name follows the merge +convention that appends the configuration to |Fess|'s own +``fess_ingest.xml`` (which defines the ``ingestFactory`` that manages +Ingesters). .. code-block:: xml - - - + + + + + + + -Configuration -============= +With ````, ``Ingester#register()`` is +called after the component is created, registering itself with the +``ingestFactory``. -``fess_config.properties``: +There are no ``fess_config.properties`` settings related to the Ingest +functionality. Whether it is enabled or disabled is determined by whether +the plugin is installed, and the execution order is controlled by +``priority``. -:: +Execution Flow +============== - ingest.handler.example.enabled=true +Ingesters are called, in ascending order of ``priority``, immediately +before the processed document is sent to the index, at the following +points: -Reference -========= +- **Data store crawl**: ``process(Map, DataStoreParams)`` is called + immediately before the document is sent. +- **Web/file crawl (response processing)**: ``process(ResultData, + ResponseData)`` is called before the crawl result is saved. +- **Web/file crawl (index registration)**: ``process(Map, AccessResult)`` + is called immediately before the document is sent. -- :doc:`plugin-architecture` - Plugin Architecture +In every case, if an Ingester throws an exception, a warning is logged and +processing continues (index registration of that document is not +interrupted). +.. note:: + + Since Ingesters are registered in the crawler's runtime environment + (``ingestFactory``), they operate as part of the crawl process. + +Reference Implementations +========================== + +For reference, the following plugins are published on GitHub under +`CodeLibs `__: + +- ``fess-ingest-example`` - A minimal sample implementation +- ``fess-webapp-multimodal`` - A plugin that includes ``EmbeddingIngester``, which decodes vector embeddings + +References +========== + +- :doc:`plugin-architecture` - Plugin Architecture diff --git a/es/15.8/dev/ingest-plugin.rst b/es/15.8/dev/ingest-plugin.rst index 4f056129..7bcc7c9a 100644 --- a/es/15.8/dev/ingest-plugin.rst +++ b/es/15.8/dev/ingest-plugin.rst @@ -2,77 +2,181 @@ Plugin Ingest ================================== -Vision General +Visión General ============== -Los plugins Ingest proporcionan funcionalidad para procesar y transformar -datos antes de que los documentos se registren en el indice. +Los plugins Ingest proporcionan la funcionalidad de procesar y transformar +datos justo antes de que los documentos se registren en el índice. Cada +documento obtenido mediante el rastreo pasa por los Ingester registrados +antes de enviarse al índice. Casos de Uso ============ -- Normalizacion de texto (conversion de ancho completo/medio, etc.) -- Adicion de metadatos -- Enmascaramiento de informacion sensible -- Adicion de campos personalizados +- Normalización de texto (conversión de ancho completo/medio, ajuste de + espacios en blanco, etc.) +- Adición de metadatos y campos personalizados +- Enmascaramiento de información sensible +- Conversión de valores (por ejemplo: decodificación de embeddings + vectoriales codificados) -Implementacion Basica -===================== +Clase Ingester +============== + +La funcionalidad de Ingest se implementa heredando de la clase abstracta +``org.codelibs.fess.ingest.Ingester``. ``Ingester`` proporciona métodos +``process`` que se invocan según el tipo de rastreo y la etapa de +procesamiento. Dado que todas las implementaciones por defecto devuelven +el ``target`` recibido tal cual (sin hacer nada), solo es necesario +sobrescribir los métodos que se necesiten. + +- ``protected Map process(Map target)`` + + Es el destino común de delegación de las dos versiones de métodos + ``Map``. Si se sobrescribe, se aplica tanto a los documentos del + rastreo de almacén de datos como a los del rastreo web/de archivos + (durante el registro en el índice). Para la mayoría de los casos de + uso, basta con sobrescribir únicamente este método. + +- ``public Map process(Map target, DataStoreParams params)`` + + Se invoca durante el rastreo de almacén de datos. Por defecto, + delega en ``process(target)``. + +- ``public Map process(Map target, AccessResult accessResult)`` + + Se invoca durante el registro en el índice del rastreo web/de + archivos. Por defecto, delega en ``process(target)``. + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Se invoca durante el procesamiento de la respuesta del rastreo + web/de archivos (antes de guardar el resultado de acceso). Por + defecto, devuelve el ``target`` tal cual. + +Orden de ejecución (priority) +----------------------------- + +Cuando hay varios Ingester registrados, se ejecutan en orden ascendente +del campo ``priority`` (los valores más pequeños se ejecutan primero). +El valor por defecto es ``99``. Se puede establecer directamente en el +constructor o modificar mediante ``setPriority(int)``. + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) -Implemente la interfaz ``IngestHandler``: +Ejemplo de Implementación +========================= + +Ejemplo que sobrescribe ``process(Map)`` para normalizar +el contenido y añadir un campo personalizado: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // Establece el orden de ejecución (los valores más pequeños se ejecutan primero; el valor por defecto es 99) + setPriority(50); + } @Override - public Map process(Map document) { - // Normalizacion de contenido - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + protected Map process(final Map target) { + // Normalización del contenido + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } - // Adicion de campo personalizado - document.put("processed_at", new Date()); - - return document; - } + // Adición de un campo personalizado + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // Logica de normalizacion - return text.trim().replaceAll("\\s+", " "); + // Devuelve el documento procesado + return target; } } +.. note:: + + Si el método ``process`` devuelve ``null``, el registro en el + índice fallará. Como no existe un mecanismo para omitir documentos, + asegúrese siempre de devolver ``target``. + Registro ======== -``fess_ingest.xml``: +Los Ingester se registran a través del contenedor DI. El plugin debe +incluir ``fess_ingest++.xml``. El sufijo ``++`` al final del nombre del +archivo es una convención de fusión que añade la configuración a +``fess_ingest.xml`` (que define ``ingestFactory``, encargado de +gestionar los Ingester) del núcleo de |Fess|. .. code-block:: xml - - - - -Configuracion -============= - -``fess_config.properties``: - -:: - - ingest.handler.example.enabled=true - -Informacion de Referencia -========================= + + + + + + + + +Gracias a ````, tras crear el componente +se invoca ``Ingester#register()``, con lo que se registra a sí mismo en +``ingestFactory``. + +No existen elementos de configuración relacionados con la +funcionalidad de Ingest en ``fess_config.properties``. La activación o +desactivación depende de si el plugin está instalado, y el orden de +ejecución se controla mediante ``priority``. + +Flujo de Ejecución +================== + +Los Ingester se invocan en orden ascendente de ``priority`` justo antes +de que el documento procesado se envíe al índice, en los siguientes +puntos: + +- **Rastreo de almacén de datos**: se invoca + ``process(Map, DataStoreParams)`` justo antes de enviar el documento. +- **Rastreo web/de archivos (procesamiento de la respuesta)**: se + invoca ``process(ResultData, ResponseData)`` antes de guardar el + resultado del rastreo. +- **Rastreo web/de archivos (registro en el índice)**: se invoca + ``process(Map, AccessResult)`` justo antes de enviar el documento. + +En cualquiera de estos puntos, si un Ingester lanza una excepción, se +emite un registro de advertencia y el procesamiento continúa (el +registro en el índice de ese documento no se interrumpe). + +.. note:: + + Dado que los Ingester se registran en el entorno de ejecución del + rastreador (``ingestFactory``), funcionan como parte del proceso + de rastreo. + +Implementación de Referencia +============================ + +Como referencia de implementación, los siguientes plugins están +publicados en `CodeLibs `__ en GitHub: + +- ``fess-ingest-example`` - Implementación de ejemplo con la + configuración mínima +- ``fess-webapp-multimodal`` - Plugin que incluye ``EmbeddingIngester``, + encargado de decodificar embeddings vectoriales + +Información de Referencia +========================== - :doc:`plugin-architecture` - Arquitectura de plugins diff --git a/fr/15.8/dev/ingest-plugin.rst b/fr/15.8/dev/ingest-plugin.rst index 2a388d17..12dfb7f7 100644 --- a/fr/15.8/dev/ingest-plugin.rst +++ b/fr/15.8/dev/ingest-plugin.rst @@ -5,74 +5,178 @@ Plugin Ingest Vue d'ensemble ============== -Les plugins Ingest fournissent des fonctionnalites de traitement et de transformation -des donnees avant leur enregistrement dans l'index. +Les plugins Ingest fournissent une fonctionnalité de traitement et de +transformation des données juste avant que les documents ne soient +enregistrés dans l'index. Chaque document récupéré lors du crawl passe +par les Ingester enregistrés avant d'être envoyé à l'index. Cas d'utilisation ================= -- Normalisation du texte (conversion pleine largeur/demi-largeur, etc.) -- Ajout de metadonnees +- Normalisation du texte (conversion pleine largeur/demi-largeur, + mise en forme des espaces, etc.) +- Ajout de métadonnées ou de champs personnalisés - Masquage d'informations sensibles -- Ajout de champs personnalises +- Conversion de valeurs (par exemple : décodage d'embeddings vectoriels + encodés) -Implementation de base -====================== +Classe Ingester +=============== -Implementez l'interface ``IngestHandler``: +La fonctionnalité Ingest s'implémente en héritant de la classe abstraite +``org.codelibs.fess.ingest.Ingester``. ``Ingester`` fournit des méthodes +``process`` appelées selon le type de crawl et l'étape de traitement. +Les implémentations par défaut renvoient toutes le ``target`` reçu tel +quel (elles ne font rien), il suffit donc de ne surcharger que les +méthodes nécessaires. + +- ``protected Map process(Map target)`` + + Point de délégation commun aux deux méthodes basées sur ``Map``. En la + surchargeant, elle s'applique aux documents du crawl de datastore ainsi + qu'à ceux du crawl Web/fichier (lors de l'enregistrement dans l'index). + Pour de nombreux cas d'usage, surcharger uniquement cette méthode + suffit. + +- ``public Map process(Map target, DataStoreParams params)`` + + Appelée lors du crawl de datastore. Par défaut, elle délègue à + ``process(target)``. + +- ``public Map process(Map target, AccessResult accessResult)`` + + Appelée lors de l'enregistrement dans l'index pour le crawl Web/fichier. + Par défaut, elle délègue à ``process(target)``. + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Appelée lors du traitement de la réponse pour le crawl Web/fichier + (avant l'enregistrement du résultat d'accès). Par défaut, elle renvoie + ``target`` tel quel. + +Ordre d'exécution (priority) +---------------------------- + +Lorsque plusieurs Ingester sont enregistrés, ils s'exécutent par ordre +croissant du champ ``priority`` (les valeurs les plus petites en +premier). La valeur par défaut est ``99``. Elle peut être définie +directement dans le constructeur ou modifiée via ``setPriority(int)``. + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +Exemple d'implémentation +======================== + +Exemple de surcharge de ``process(Map)`` qui normalise +le contenu et ajoute un champ personnalisé : .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // Définit l'ordre d'exécution (plus la valeur est petite, plus tôt l'exécution a lieu ; la valeur par défaut est 99) + setPriority(50); + } @Override - public Map process(Map document) { + protected Map process(final Map target) { // Normalisation du contenu - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } - // Ajout d'un champ personnalise - document.put("processed_at", new Date()); + // Ajout d'un champ personnalisé + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - return document; - } - - private String normalizeText(String text) { - // Logique de normalisation - return text.trim().replaceAll("\\s+", " "); + // Renvoie le document traité + return target; } } +.. note:: + + Si la méthode ``process`` renvoie ``null``, l'enregistrement dans + l'index échoue. Comme il n'existe aucun mécanisme pour ignorer un + document, veillez à toujours renvoyer ``target``. + Enregistrement ============== -``fess_ingest.xml``: +Les Ingester s'enregistrent via le conteneur DI. Le plugin doit inclure +``fess_ingest++.xml``. Le suffixe ``++`` à la fin du nom de fichier +correspond à la convention de fusion qui ajoute la configuration au +fichier ``fess_ingest.xml`` du cœur de |Fess| (qui définit +``ingestFactory``, chargé de gérer les Ingester). .. code-block:: xml - - - - -Configuration -============= - -``fess_config.properties``: - -:: - - ingest.handler.example.enabled=true - -Informations complementaires -============================ + + + + + + + + +Grâce à ````, ``Ingester#register()`` +est appelée après la création du composant, ce qui l'enregistre +lui-même dans ``ingestFactory``. + +Il n'existe aucun paramètre de configuration dans +``fess_config.properties`` pour la fonctionnalité Ingest. L'activation +ou la désactivation dépend de l'installation ou non du plugin, et +l'ordre d'exécution est contrôlé par ``priority``. + +Flux d'exécution +================ + +Les Ingester sont appelés par ordre croissant de ``priority``, juste +avant que le document traité ne soit envoyé à l'index, aux emplacements +suivants : + +- **Crawl de datastore** : ``process(Map, DataStoreParams)`` est + appelée juste avant l'envoi du document. +- **Crawl Web/fichier (traitement de la réponse)** : + ``process(ResultData, ResponseData)`` est appelée avant + l'enregistrement du résultat du crawl. +- **Crawl Web/fichier (enregistrement dans l'index)** : + ``process(Map, AccessResult)`` est appelée juste avant l'envoi du + document. + +Dans tous les cas, si un Ingester lève une exception, un message +d'avertissement est journalisé et le traitement se poursuit +(l'enregistrement du document dans l'index n'est pas interrompu). + +.. note:: + + Comme les Ingester sont enregistrés dans l'environnement + d'exécution du crawler (``ingestFactory``), ils fonctionnent dans + le cadre du traitement de crawl. + +Implémentations de référence +============================= + +À titre de référence pour l'implémentation, les plugins suivants sont +publiés sur GitHub par `CodeLibs `__ : + +- ``fess-ingest-example`` - exemple d'implémentation minimale +- ``fess-webapp-multimodal`` - plugin contenant ``EmbeddingIngester``, + qui décode les embeddings vectoriels + +Informations complémentaires +============================= - :doc:`plugin-architecture` - Architecture des plugins diff --git a/ja/15.8/dev/ingest-plugin.rst b/ja/15.8/dev/ingest-plugin.rst index 221beab8..191c6e29 100644 --- a/ja/15.8/dev/ingest-plugin.rst +++ b/ja/15.8/dev/ingest-plugin.rst @@ -5,72 +5,157 @@ Ingestプラグイン 概要 ==== -Ingestプラグインは、ドキュメントがインデックスに登録される前に -データを加工・変換する機能を提供します。 +Ingestプラグインは、ドキュメントがインデックスに登録される直前に +データを加工・変換する機能を提供します。クロールで取得した各ドキュメントは、 +インデックスへ送信される前に登録済みの Ingester を通過します。 用途 ==== -- テキストの正規化(全角/半角変換など) -- メタデータの追加 +- テキストの正規化(全角/半角変換、空白の整形など) +- メタデータやカスタムフィールドの追加 - センシティブ情報のマスキング -- カスタムフィールドの追加 +- 値の変換(例: エンコードされたベクトル埋め込みのデコード) -基本実装 -======== +Ingester クラス +=============== + +Ingest機能は ``org.codelibs.fess.ingest.Ingester`` 抽象クラスを継承して +実装します。``Ingester`` には、クロールの種類や処理ステージに応じて +呼び出される ``process`` メソッドが用意されています。デフォルト実装は +いずれも受け取った ``target`` をそのまま返す(何もしない)ため、 +必要なメソッドだけをオーバーライドします。 + +- ``protected Map process(Map target)`` + + 2つの ``Map`` 版メソッドの共通の委譲先です。これをオーバーライドすると、 + データストアクロールとWeb/ファイルクロール(インデックス登録時)の + 両方のドキュメントに適用されます。多くの用途では、このメソッドだけを + オーバーライドすれば十分です。 + +- ``public Map process(Map target, DataStoreParams params)`` + + データストアクロール時に呼び出されます。デフォルトでは + ``process(target)`` に委譲します。 + +- ``public Map process(Map target, AccessResult accessResult)`` + + Web/ファイルクロールのインデックス登録時に呼び出されます。 + デフォルトでは ``process(target)`` に委譲します。 + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Web/ファイルクロールのレスポンス処理時(アクセス結果を保存する前)に + 呼び出されます。デフォルトでは ``target`` をそのまま返します。 + +実行順序(priority) +-------------------- + +複数の Ingester が登録されている場合は、``priority`` フィールドの昇順 +(値が小さいものが先)に実行されます。デフォルト値は ``99`` です。 +コンストラクタで直接設定するか、``setPriority(int)`` で変更できます。 + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +実装例 +====== -``IngestHandler`` インターフェースを実装します: +``process(Map)`` をオーバーライドし、コンテンツを正規化して +カスタムフィールドを追加する例です: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // 実行順序を設定(値が小さいほど先に実行。デフォルトは 99) + setPriority(50); + } @Override - public Map process(Map document) { + protected Map process(final Map target) { // コンテンツの正規化 - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } // カスタムフィールドの追加 - document.put("processed_at", new Date()); - - return document; - } + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // 正規化ロジック - return text.trim().replaceAll("\\s+", " "); + // 加工したドキュメントを返す + return target; } } +.. note:: + + ``process`` メソッドで ``null`` を返すとインデックス登録に失敗します。 + ドキュメントをスキップする仕組みはないため、必ず ``target`` を返してください。 + 登録 ==== -``fess_ingest.xml``: +Ingester は DIコンテナ経由で登録します。プラグインには ``fess_ingest++.xml`` +を含めます。ファイル名末尾の ``++`` は、|Fess| 本体の ``fess_ingest.xml`` +(Ingester を管理する ``ingestFactory`` を定義)へ設定を追記するマージ規約です。 .. code-block:: xml - - - + + + + + + + -設定 -==== +```` により、コンポーネント生成後に +``Ingester#register()`` が呼び出され、``ingestFactory`` に自身が登録されます。 -``fess_config.properties``: +Ingest機能に関する ``fess_config.properties`` の設定項目はありません。 +有効・無効はプラグインの導入有無で、実行順序は ``priority`` で制御します。 + +実行フロー +========== + +Ingester は、加工されたドキュメントがインデックスへ送信される直前に、 +以下の箇所で ``priority`` の昇順に呼び出されます: + +- **データストアクロール**: ドキュメントを送信する直前に + ``process(Map, DataStoreParams)`` が呼び出されます。 +- **Web/ファイルクロール(レスポンス処理時)**: クロール結果を保存する前に + ``process(ResultData, ResponseData)`` が呼び出されます。 +- **Web/ファイルクロール(インデックス登録時)**: ドキュメントを送信する直前に + ``process(Map, AccessResult)`` が呼び出されます。 + +いずれの箇所でも、ある Ingester が例外をスローした場合は警告ログを出力して +処理を継続します(そのドキュメントのインデックス登録は中断されません)。 + +.. note:: + + Ingester はクローラの実行環境(``ingestFactory``)に登録されるため、 + クロール処理の一部として動作します。 + +参考実装 +======== -:: +実装の参考として、以下のプラグインが GitHub の +`CodeLibs `__ で公開されています: - ingest.handler.example.enabled=true +- ``fess-ingest-example`` - 最小構成のサンプル実装 +- ``fess-webapp-multimodal`` - ベクトル埋め込みをデコードする ``EmbeddingIngester`` を含むプラグイン 参考情報 ======== diff --git a/ko/15.8/dev/ingest-plugin.rst b/ko/15.8/dev/ingest-plugin.rst index 68aa5bb8..64827c2f 100644 --- a/ko/15.8/dev/ingest-plugin.rst +++ b/ko/15.8/dev/ingest-plugin.rst @@ -5,72 +5,156 @@ Ingest 플러그인 개요 ==== -Ingest 플러그인은 문서가 인덱스에 등록되기 전에 -데이터를 가공/변환하는 기능을 제공합니다. +Ingest 플러그인은 문서가 인덱스에 등록되기 직전에 +데이터를 가공·변환하는 기능을 제공합니다. 크롤링으로 수집한 각 문서는, +인덱스로 전송되기 전에 등록된 Ingester를 통과합니다. 용도 ==== -- 텍스트 정규화(전각/반각 변환 등) -- 메타데이터 추가 +- 텍스트 정규화(전각/반각 변환, 공백 정리 등) +- 메타데이터나 커스텀 필드 추가 - 민감한 정보 마스킹 -- 커스텀 필드 추가 +- 값 변환(예: 인코딩된 벡터 임베딩 디코딩) -기본 구현 -======== +Ingester 클래스 +=============== + +Ingest 기능은 ``org.codelibs.fess.ingest.Ingester`` 추상 클래스를 상속하여 +구현합니다. ``Ingester``에는 크롤링 종류나 처리 단계에 따라 +호출되는 ``process`` 메서드가 준비되어 있습니다. 기본 구현은 +모두 전달받은 ``target``을 그대로 반환(아무 작업도 하지 않음)하므로, +필요한 메서드만 오버라이드합니다. + +- ``protected Map process(Map target)`` + + 두 ``Map`` 버전 메서드가 공통으로 위임하는 대상입니다. 이 메서드를 오버라이드하면 + 데이터 스토어 크롤링과 Web/파일 크롤링(인덱스 등록 시) 양쪽 문서에 모두 적용됩니다. + 대부분의 용도에서는 이 메서드만 오버라이드하면 충분합니다. + +- ``public Map process(Map target, DataStoreParams params)`` + + 데이터 스토어 크롤링 시 호출됩니다. 기본적으로 + ``process(target)``에 위임합니다. + +- ``public Map process(Map target, AccessResult accessResult)`` + + Web/파일 크롤링의 인덱스 등록 시 호출됩니다. + 기본적으로 ``process(target)``에 위임합니다. + +- ``public ResultData process(ResultData target, ResponseData responseData)`` + + Web/파일 크롤링의 응답 처리 시(액세스 결과를 저장하기 전)에 + 호출됩니다. 기본적으로 ``target``을 그대로 반환합니다. + +실행 순서(priority) +-------------------- + +여러 Ingester가 등록되어 있는 경우 ``priority`` 필드의 오름차순 +(값이 작은 것이 먼저)으로 실행됩니다. 기본값은 ``99``입니다. +생성자에서 직접 설정하거나 ``setPriority(int)``로 변경할 수 있습니다. + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +구현 예시 +====== -``IngestHandler`` 인터페이스를 구현합니다: +``process(Map)``를 오버라이드하여 콘텐츠를 정규화하고 +커스텀 필드를 추가하는 예시입니다: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // 실행 순서를 설정(값이 작을수록 먼저 실행됨. 기본값은 99) + setPriority(50); + } @Override - public Map process(Map document) { + protected Map process(final Map target) { // 콘텐츠 정규화 - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } // 커스텀 필드 추가 - document.put("processed_at", new Date()); - - return document; - } + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // 정규화 로직 - return text.trim().replaceAll("\\s+", " "); + // 가공한 문서를 반환 + return target; } } +.. note:: + + ``process`` 메서드에서 ``null``을 반환하면 인덱스 등록이 실패합니다. + 문서를 건너뛰는 방법은 없으므로 반드시 ``target``을 반환해야 합니다. + 등록 ==== -``fess_ingest.xml``: +Ingester는 DI 컨테이너를 통해 등록합니다. 플러그인에는 ``fess_ingest++.xml`` +을 포함합니다. 파일명 끝의 ``++``는 |Fess| 본체의 ``fess_ingest.xml`` +(Ingester를 관리하는 ``ingestFactory``를 정의)에 설정을 추가하는 병합 규칙입니다. .. code-block:: xml - - - + + + + + + + -설정 -==== +````에 의해 컴포넌트 생성 후 +``Ingester#register()``가 호출되어 ``ingestFactory``에 자신이 등록됩니다. -``fess_config.properties``: +Ingest 기능과 관련된 ``fess_config.properties`` 설정 항목은 없습니다. +활성화 여부는 플러그인 도입 여부로, 실행 순서는 ``priority``로 제어합니다. + +실행 흐름 +========== + +Ingester는 가공된 문서가 인덱스로 전송되기 직전에, +다음 위치에서 ``priority`` 오름차순으로 호출됩니다: + +- **데이터 스토어 크롤링**: 문서를 전송하기 직전에 + ``process(Map, DataStoreParams)``가 호출됩니다. +- **Web/파일 크롤링(응답 처리 시)**: 크롤링 결과를 저장하기 전에 + ``process(ResultData, ResponseData)``가 호출됩니다. +- **Web/파일 크롤링(인덱스 등록 시)**: 문서를 전송하기 직전에 + ``process(Map, AccessResult)``가 호출됩니다. + +어느 위치에서든 특정 Ingester가 예외를 던지면 경고 로그를 출력하고 +처리를 계속합니다(해당 문서의 인덱스 등록은 중단되지 않습니다). + +.. note:: + + Ingester는 크롤러 실행 환경(``ingestFactory``)에 등록되므로 + 크롤링 처리의 일부로 동작합니다. + +참고 구현 +======== -:: +구현 참고 자료로 다음 플러그인이 GitHub의 +`CodeLibs `__ 에 공개되어 있습니다: - ingest.handler.example.enabled=true +- ``fess-ingest-example`` - 최소 구성의 샘플 구현 +- ``fess-webapp-multimodal`` - 벡터 임베딩을 디코딩하는 ``EmbeddingIngester``를 포함하는 플러그인 참고 정보 ======== diff --git a/zh-cn/15.8/dev/ingest-plugin.rst b/zh-cn/15.8/dev/ingest-plugin.rst index 434e7594..55a1fe29 100644 --- a/zh-cn/15.8/dev/ingest-plugin.rst +++ b/zh-cn/15.8/dev/ingest-plugin.rst @@ -5,74 +5,154 @@ Ingest插件 概述 ==== -Ingest插件提供在文档注册到索引之前进行数据加工和转换的功能。 +Ingest插件提供在文档注册到索引之前对数据进行加工和转换的功能。 +通过抓取获取的各个文档,在发送到索引之前都会经过已注册的 Ingester。 用途 ==== -- 文本规范化(全角/半角转换等) -- 添加元数据 +- 文本规范化(全角/半角转换、空白整理等) +- 添加元数据或自定义字段 - 敏感信息脱敏 -- 添加自定义字段 +- 值转换(例如:解码已编码的向量嵌入) -基本实现 -======== +Ingester 类 +=============== + +Ingest 功能通过继承 ``org.codelibs.fess.ingest.Ingester`` 抽象类来实现。 +``Ingester`` 提供了根据抓取类型和处理阶段调用的 ``process`` 方法。由于 +默认实现均直接返回接收到的 ``target``(不做任何处理),因此只需重写 +所需的方法即可。 + +- ``protected Map process(Map target)`` + + 这是两个 ``Map`` 版本方法共同的委托目标。重写此方法后,将同时适用于 + 数据存储抓取以及 Web/文件抓取(索引注册时)的文档。在多数场景下, + 只需重写此方法即可满足需求。 + +- ``public Map process(Map target, DataStoreParams params)`` + + 在数据存储抓取时被调用。默认情况下会委托给 ``process(target)``。 + +- ``public Map process(Map target, AccessResult accessResult)`` + + 在 Web/文件抓取的索引注册时被调用。默认情况下会委托给 ``process(target)``。 + +- ``public ResultData process(ResultData target, ResponseData responseData)`` -实现 ``IngestHandler`` 接口: + 在 Web/文件抓取的响应处理时(保存访问结果之前)被调用。默认情况下 + 会直接返回 ``target``。 + +执行顺序(priority) +-------------------- + +当注册了多个 Ingester 时,将按照 ``priority`` 字段的升序(值越小越先 +执行)执行。默认值为 ``99``。可以在构造函数中直接设置,也可以通过 +``setPriority(int)`` 进行修改。 + +.. code-block:: java + + public int getPriority() + public void setPriority(final int priority) + +实现示例 +====== + +以下是重写 ``process(Map)`` 方法,对内容进行规范化并 +添加自定义字段的示例: .. code-block:: java package org.codelibs.fess.ingest.example; - import org.codelibs.fess.ingest.IngestHandler; import java.util.Map; - public class ExampleIngestHandler implements IngestHandler { + import org.codelibs.fess.ingest.Ingester; + + public class ExampleIngester extends Ingester { + + public ExampleIngester() { + // 设置执行顺序(值越小越先执行。默认值为 99) + setPriority(50); + } @Override - public Map process(Map document) { + protected Map process(final Map target) { // 内容规范化 - String content = (String) document.get("content"); - if (content != null) { - content = normalizeText(content); - document.put("content", content); + final Object content = target.get("content"); + if (content instanceof String) { + target.put("content", ((String) content).trim().replaceAll("\\s+", " ")); } // 添加自定义字段 - document.put("processed_at", new Date()); - - return document; - } + target.put("ingested_by", ExampleIngester.class.getSimpleName()); - private String normalizeText(String text) { - // 规范化逻辑 - return text.trim().replaceAll("\\s+", " "); + // 返回加工后的文档 + return target; } } +.. note:: + + 在 ``process`` 方法中返回 ``null`` 会导致索引注册失败。由于没有跳过 + 文档的机制,因此请务必返回 ``target``。 + 注册 ==== -``fess_ingest.xml``: +Ingester 通过 DI 容器进行注册。插件中需包含 ``fess_ingest++.xml`` +文件。文件名末尾的 ``++`` 是一种合并约定,表示将配置追加到 |Fess| +本体的 ``fess_ingest.xml``(其中定义了管理 Ingester 的 ``ingestFactory``)中。 .. code-block:: xml - - - + + + + + + + -配置 -==== +通过 ````,组件生成后会调用 +``Ingester#register()``,从而将自身注册到 ``ingestFactory`` 中。 + +关于 Ingest 功能,``fess_config.properties`` 中没有相应的配置项。 +是否启用取决于插件是否安装,执行顺序则通过 ``priority`` 控制。 -``fess_config.properties``: +执行流程 +========== -:: +在加工后的文档发送到索引之前,Ingester 会在以下位置按照 ``priority`` +的升序被调用: - ingest.handler.example.enabled=true +- **数据存储抓取**:在发送文档之前,会调用 + ``process(Map, DataStoreParams)``。 +- **Web/文件抓取(响应处理时)**:在保存抓取结果之前,会调用 + ``process(ResultData, ResponseData)``。 +- **Web/文件抓取(索引注册时)**:在发送文档之前,会调用 + ``process(Map, AccessResult)``。 + +无论在哪个位置,如果某个 Ingester 抛出异常,都会输出警告日志并继续 +处理(该文档的索引注册不会中断)。 + +.. note:: + + 由于 Ingester 是注册到抓取器的运行环境(``ingestFactory``)中的, + 因此它作为抓取处理的一部分运行。 + +参考实现 +======== + +作为实现参考,以下插件已在 GitHub 的 +`CodeLibs `__ 上公开: + +- ``fess-ingest-example`` - 最小配置的示例实现 +- ``fess-webapp-multimodal`` - 包含用于解码向量嵌入的 ``EmbeddingIngester`` 的插件 参考信息 ======== - :doc:`plugin-architecture` - 插件架构 -