diff --git a/de/15.9/admin/index.rst b/de/15.9/admin/index.rst index b69b8f21..b7923bc2 100644 --- a/de/15.9/admin/index.rst +++ b/de/15.9/admin/index.rst @@ -28,6 +28,7 @@ Rollen bis zu Protokollen und Sicherungen. fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/de/15.9/admin/labeltype-guide.rst b/de/15.9/admin/labeltype-guide.rst index be87afa6..01a2c634 100644 --- a/de/15.9/admin/labeltype-guide.rst +++ b/de/15.9/admin/labeltype-guide.rst @@ -85,46 +85,11 @@ Anzeigereihenfolge Geben Sie die Anzeigereihenfolge der Labels an. -Art -::: - -Geben Sie „Label“ oder „Tag“ an. Ein gewöhnliches Label ist „Label“. „Tag“ ist ein Tag, den Benutzer -auf der Suchseite hinzufügen (siehe „Tags“ unten). Ein bestehendes Label ohne Art wird als „Label“ -behandelt. - - Konfiguration löschen --------------------- Klicken Sie auf den Konfigurationsnamen auf der Übersichtsseite und dann auf die Schaltfläche „Löschen". Es wird ein Bestätigungsbildschirm angezeigt. Klicken Sie auf die Schaltfläche „Löschen", um die Konfiguration zu löschen. -Tags ----- - -Mit ``user.tag.enabled=true`` (Standard: ``false``) in ``fess_config.properties`` können -angemeldete Benutzer Suchergebnisse taggen. Im mitgelieferten Theme ``bootstrap`` werden Tags an den -Ergebnissen angezeigt, Benutzer können Tags hinzufügen und eigene entfernen, und eine Facette „Tags“ -grenzt die Ergebnisse ein. Zur API siehe :doc:`../api/api-tag`. - -Ein Tag wird als Label der Art „Tag“ gespeichert: Der Name ist der Tag-Name, der Wert der SHA-256 -des Namens, die eingeschlossenen Pfade sind die getaggten URLs (eine je Zeile, exakte -Übereinstimmung), und die Berechtigungen bestimmen, wer das Tag sehen kann. Ein Benutzer, der ein Tag -hinzufügt, wird zu dessen Berechtigungen hinzugefügt. - -- Ein Tag ist nur sichtbar, wenn die Berechtigungen seines Labels auf den Aufrufer zutreffen. - Administratoren können ein Tag auf dieser Seite bearbeiten, um es mit einer Rolle oder Gruppe zu - teilen, oder es löschen. -- Tags mit gleichem Namen werden zu einem Label zusammengeführt; Benutzer, die ein Tag gleichen - Namens hinzugefügt haben, sehen daher gegenseitig, wo ihre Tags gesetzt sind. -- Tags erscheinen weder in der Label-Listen-API (``/api/v2/labels``) noch in der Label-Auswahl der - Suchseite. -- Tags zählen zum Label-Limit (``page.labeltype.max.fetch.size``, Standard: 1000). Ist das Limit - erreicht, kann kein neues Tag erstellt werden. -- Ändert oder löscht ein Administrator ein Tag auf dieser Seite, behalten die indexierten Dokumente die - alten Werte, bis sie erneut gecrawlt werden oder der Job „Label Updater“ läuft. -- Ein Dokument kann bis zu ``user.tag.max.document.tags`` (Standard: 100) Tags haben, ein Tag-Name bis - zu ``user.tag.name.max.length`` (Standard: 50) Zeichen. - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png diff --git a/de/15.9/admin/tagtype-guide.rst b/de/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..e5b51599 --- /dev/null +++ b/de/15.9/admin/tagtype-guide.rst @@ -0,0 +1,161 @@ +=== +Tag +=== + +Übersicht +========= + +Hier wird der Bildschirm zur Verwaltung der Tags der Benutzer erläutert. + +Ein Tag ist eine Markierung, die ein angemeldeter Benutzer an Dokumente in den Suchergebnissen +vergibt. Tags werden pro Benutzer verwaltet: Wer ein Tag erstellt, ist sein Besitzer, und zwei +Benutzer können denselben Namen verwenden und haben trotzdem zwei getrennte Tags. Tags sind keine +:doc:`Labels `, die Administratoren über URL-Muster definieren; Benutzer erstellen +Tags selbst und vergeben sie an einzelne Dokumente. + +Tags sind standardmäßig deaktiviert. Um sie zu nutzen, setzen Sie ``user.tag.enabled=true`` in +``fess_config.properties``. Danach können angemeldete Benutzer im mitgelieferten Theme +``bootstrap`` Tags an Suchergebnisse vergeben und wieder entfernen und über eine Tag-Facette filtern. +Unter „Meine Tags“ können sie ihre eigenen Tags umbenennen, freigeben und löschen. Freigegebene Tags +anderer Benutzer werden mit dem Präfix „Geteilt:“ angezeigt. Zur Benutzer-API und zu den +Einstellungen siehe :doc:`../api/api-tag`. + +In diesem Bildschirm können Administratoren die Tags aller Benutzer auflisten, erstellen, bearbeiten +und löschen. + +Verwaltung +========== + +Anzeige +------- + +Um die Tag-Liste zu öffnen, klicken Sie im linken Menü auf [Crawler > Tag]. Zum Anzeigen ist die +Rolle ``admin-tagtype`` oder ``admin-tagtype-view`` erforderlich, zum Erstellen, Bearbeiten und +Löschen ``admin-tagtype``. + +Die Liste zeigt Name und Besitzer jedes Tags, sortiert nach Sortierreihenfolge, Name und Besitzer. +Sie können nach Name und nach Besitzer suchen; beide treffen die Tags, die den eingegebenen Text +enthalten. + +Klicken Sie auf einen Namen, um das Tag zu bearbeiten. + +Konfiguration erstellen +----------------------- + +Um die Seite zum Erstellen eines Tags zu öffnen, klicken Sie auf die Schaltfläche „Neu erstellen“. + +Konfigurationsparameter +----------------------- + +Name +:::: + +Gibt den Tag-Namen an. Der Name wird NFKC-normalisiert, Leerzeichenfolgen werden zu einem +Leerzeichen zusammengefasst, und Anfang und Ende werden getrimmt. Das Ergebnis muss 1 bis +``user.tag.name.max.length`` (Standard: 50) Zeichen lang sein und darf kein Steuer- oder +Formatzeichen enthalten. + +Besitzer +:::::::: + +Gibt die Benutzer-ID der Anmeldung des Benutzers an, dem das Tag gehört. Besitzer und Name zusammen +kennzeichnen ein Tag; ein Besitzer kann also keine zwei Tags gleichen Namens haben, auch nicht auf +verschiedenen virtuellen Hosts. + +Wenn Sie den Besitzer ändern, wird die Benutzerberechtigung des alten Besitzers unter +„Berechtigungen“ durch die des neuen Besitzers ersetzt. + +Pfade +::::: + +Gibt die URLs der Dokumente an, an die das Tag vergeben wird, eine pro Zeile. Eine URL muss dem Feld +``url`` eines indexierten Dokuments genau entsprechen; reguläre Ausdrücke werden nicht verwendet. Ein +Tag kann höchstens ``user.tag.max.paths`` (Standard: 10000) URLs haben. + +Berechtigungen +:::::::::::::: + +Gibt die Benutzer, Gruppen und Rollen an, die das Tag sehen können, wie bei Labels: {user}Benutzername +für einen Benutzer, {group}Gruppenname für eine Gruppe und {role}Rollenname für eine Rolle. Bleibt +das Feld leer, sieht nur der Besitzer das Tag. + +Der Besitzer sieht seine eigenen Tags immer, unabhängig von den Berechtigungen. Ein nicht +angemeldeter Benutzer sieht nie ein Tag, unabhängig von den Berechtigungen. + +Virtueller Host +::::::::::::::: + +Gibt den Hostnamen des virtuellen Hosts an, auf dem das Tag angezeigt wird. Ein von einem Benutzer +erstelltes Tag erhält den virtuellen Host, über den der Benutzer zugegriffen hat. Auf einem über einen +virtuellen Host aufgerufenen Suchbildschirm sind nur die Tags sichtbar, die hier diesen virtuellen +Hostnamen haben. Ein Zugriff, der keinem virtuellen Host entspricht, sieht die Tags unabhängig von +diesem Feld. Weitere Informationen finden Sie unter +:doc:`Virtueller Host im Konfigurationshandbuch <../config/security-virtual-host>`. + +Sortierreihenfolge +:::::::::::::::::: + +Gibt die Anzeigereihenfolge des Tags an. + +Konfiguration löschen +--------------------- + +Klicken Sie auf der Listenseite auf einen Namen und dann auf die Schaltfläche „Löschen“, um einen +Bestätigungsbildschirm anzuzeigen. Ein Klick auf „Löschen“ löscht das Tag, und sein Wert wird aus den +Dokumenten entfernt. + +Freigabe +======== + +Gibt ein Benutzer ein Tag frei, werden die Werte von ``role.search.guest.permissions`` (Standard: +``{role}guest``) zu seinen Berechtigungen hinzugefügt. Ob ein Tag sichtbar ist, wird mit diesen +Werten zusätzlich zu den Rollen des angemeldeten Benutzers entschieden; ein freigegebenes Tag ist +daher für jeden angemeldeten Benutzer sichtbar, der auch danach filtern kann. Das Aufheben der +Freigabe entfernt nur diese Werte. + +In diesem Bildschirm kann ein Administrator den Berechtigungen auch Gruppen oder Rollen hinzufügen, +um ein Tag nur bestimmten Benutzern zu zeigen. Nur der Besitzer und Administratoren können ein Tag +ändern; andere Benutzer können die für sie sichtbaren Tags nur anzeigen und zum Filtern verwenden. + +Wie Änderungen die Dokumente erreichen +====================================== + +Ein Dokument speichert seine Tags im Feld ``tag`` des Index als ``base64url(Name):base64url(Besitzer)``. + +- Das Erstellen, Bearbeiten und Löschen von Tags sowie das Vergeben und Entfernen durch Benutzer + werden sofort in den Tags (Index ``fess_config.tag_type``) gespeichert. Die Dokumente werden über + eine Warteschlange im Speicher aktualisiert, die der Job „Log Aggregator“ (``log_aggregator``) + jede Minute gesammelt anwendet; die Suchergebnisse spiegeln eine Änderung daher erst nach bis zu + etwa einer Minute wider. +- Das Ändern der Pfade in diesem Bildschirm aktualisiert die Dokumente der hinzugefügten und + entfernten URLs. Das Ändern von Name oder Besitzer ersetzt den alten Wert an den Dokumenten durch + den neuen. +- Wenn Dokumente durch einen Crawl oder einen Datenspeicher indexiert werden, wird ihr Feld ``tag`` + aus den Pfaden der Tags gesetzt; Tags bleiben daher bei einem erneuten Crawl erhalten. +- Der Job „Tag Updater“ (``tag_updater``) baut das Feld ``tag`` aller Dokumente aus den Tags neu auf. + Er hat keinen Zeitplan; führen Sie ihn bei Bedarf über den Scheduler aus. + +Hinweise für den Betrieb +======================== + +- **Führen Sie Log Aggregator auf jedem Knoten aus.** Jede JVM hat ihre eigene Warteschlange, die nur + der Log Aggregator dieses Knotens verarbeitet. Belassen Sie das Ziel des Jobs ``log_aggregator`` + auf dem Standardwert ``all``; ist es auf einige Knoten beschränkt, erreichen die von den anderen + Knoten angenommenen Änderungen die Dokumente nie. +- **Führen Sie Tag Updater in den folgenden Fällen aus.** Die Warteschlange liegt im Speicher, daher + gehen noch nicht angewendete Änderungen bei einem Neustart von |Fess| verloren. Solange + ``user.tag.enabled=false`` gilt, erreichen Tag-Änderungen die Dokumente nicht, und ein erneuter + Crawl löscht ihr Feld ``tag``. Auch nach einer Wiederherstellung aus einer Sicherung müssen die + Tags der Dokumente neu aufgebaut werden. Und wenn die Warteschlange ``user.tag.queue.max.size`` + (Standard: 10000) überschreitet, werden die überzähligen Änderungen mit einem WARN-Log verworfen. + In jedem dieser Fälle baut ``tag_updater`` die Tags der Dokumente neu auf. +- **Der Besitzer eines Tags ist die Benutzer-ID der Anmeldung.** Ändert sich eine Benutzer-ID, + bleiben die Tags bei der alten ID. Bei SAML muss die NameID persistent sein. Bei Entra ID ist der + Besitzer der UPN, bei LDAP der Benutzername in der bei der Anmeldung eingegebenen Groß- und + Kleinschreibung. Das Löschen eines Benutzers lässt seine Tags bestehen; löschen Sie nicht mehr + benötigte Tags in diesem Bildschirm. +- **Vorhandene Indizes funktionieren ebenfalls.** Hat der Dokumentindex beim Start keine Zuordnung + für das Feld ``tag``, wird sie als ``keyword`` hinzugefügt. Vorhandene Felder werden nicht + geändert. +- Die Tags werden im Index ``fess_config.tag_type`` gespeichert. Sie sind in ``fess_config.bulk`` + einer Sicherung enthalten, nicht aber in ``fess_basic_config.bulk``. diff --git a/de/15.9/api/admin/api-admin-overview.rst b/de/15.9/api/admin/api-admin-overview.rst index 283b8b02..741cb8df 100644 --- a/de/15.9/api/admin/api-admin-overview.rst +++ b/de/15.9/api/admin/api-admin-overview.rst @@ -450,6 +450,8 @@ Such-Tuning - Beschreibung * - :doc:`api-admin-labeltype` - Label-Typen + * - :doc:`api-admin-tagtype` + - Tags * - :doc:`api-admin-keymatch` - Key Match * - :doc:`api-admin-boostdoc` diff --git a/de/15.9/api/admin/api-admin-tagtype.rst b/de/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..6f4fddc1 --- /dev/null +++ b/de/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,398 @@ +=========== +TagType API +=========== + +Übersicht +========= + +Die TagType API dient zur Verwaltung der Tags der Benutzer in |Fess|, also der benutzereigenen +Tags, die angemeldete Benutzer an Dokumente vergeben (siehe :doc:`../../admin/tagtype-guide`). Sie +verwaltet die Tags aller Benutzer, unabhängig davon, ob ``user.tag.enabled`` den Wert ``true`` hat. + +Informationen zur Authentifizierung sowie zu den gemeinsamen Spezifikationen von Antworten +(``status``-Code, ``version``-Feld, Fehlerformat, HTTP-Statuscodes usw.) finden Sie unter +:doc:`api-admin-overview`. +Für den Zugriff auf diese API ist ein Access Token mit Admin-API-Berechtigung (``admin-api``) +im Header ``Authorization: Bearer `` erforderlich. + +Die JSON-Feldnamen dieser API sind in snake_case (``sort_order``, ``virtual_host``, ``seq_no``, +``primary_term`` usw.). + +Basis-URL +========= + +:: + + /api/admin/tagtype + +Endpunktliste +============= + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - Methode + - Pfad + - Beschreibung + * - GET + - /settings + - Tags auflisten + * - GET + - /setting/{id} + - Tag abrufen + * - POST + - /setting + - Tag erstellen + * - PUT + - /setting + - Tag aktualisieren + * - DELETE + - /setting/{id} + - Tag löschen + +Tags auflisten +============== + +Anfrage +------- + +:: + + GET /api/admin/tagtype/settings + +Parameter +~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Parameter + - Typ + - Erforderlich + - Beschreibung + * - ``size`` + - Integer + - Nein + - Anzahl der Einträge pro Seite. Standard ist der Wert von ``paging.page.size`` (standardmäßig ``25``). + * - ``page`` + - Integer + - Nein + - Seitennummer (beginnt bei 1). Standard ist ``1``. + * - ``name`` + - String + - Nein + - Nach Tag-Name filtern (Platzhaltersuche: trifft Namen, die den Text enthalten). + * - ``owner`` + - String + - Nein + - Nach Besitzer filtern (Platzhaltersuche: trifft Besitzer, die den Text enthalten). + +Die Tags sind nach Sortierreihenfolge, Name und Besitzer sortiert. + +Antwort +------- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + Die Liste liest die möglicherweise langen Pfade der Tags nicht; die Einträge haben daher kein + ``paths``. PUT ersetzt das Tag als Ganzes: Um ein Tag zu bearbeiten, rufen Sie es zuerst mit + ``GET /setting/{id}`` ab, damit seine ``paths`` erhalten bleiben. + +Tag abrufen +=========== + +Anfrage +------- + +:: + + GET /api/admin/tagtype/setting/{id} + +Antwort +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` und ``primary_term`` kennzeichnen die gelesene Version des Tags. ``paths`` und +``permissions`` enthalten einen Eintrag pro Zeile. + +Tag erstellen +============= + +Anfrage +------- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +Anfragetext +~~~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +Feldbeschreibung +~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Feld + - Typ + - Erforderlich + - Beschreibung + * - ``name`` + - String + - Ja + - Tag-Name. Er wird NFKC-normalisiert, Leerzeichenfolgen werden zusammengefasst und Anfang und + Ende getrimmt; das Ergebnis muss 1 bis ``user.tag.name.max.length`` (Standard: ``50``) + Zeichen ohne Steuer- oder Formatzeichen umfassen. + * - ``owner`` + - String + - Ja + - Benutzer-ID der Anmeldung des Besitzers (max. 1000 Zeichen). + * - ``paths`` + - String + - Nein + - URLs der Dokumente, an die das Tag vergeben wird, getrennt durch einen Zeilenumbruch + (``\n``). Jede muss dem Feld ``url`` eines Dokuments genau entsprechen. Höchstens + ``user.tag.max.paths`` (Standard: ``10000``). + * - ``permissions`` + - String + - Nein + - Benutzer/Gruppen/Rollen, die das Tag sehen können (z. B. ``{role}guest``), getrennt durch + einen Zeilenumbruch (``\n``). Ist das Feld leer, sieht nur der Besitzer das Tag. + ``{role}guest`` (der Wert von ``role.search.guest.permissions``) gibt das Tag für alle + angemeldeten Benutzer frei. + * - ``virtual_host`` + - String + - Nein + - Virtueller Host (max. 1000 Zeichen). + * - ``sort_order`` + - Integer + - Nein + - Anzeigereihenfolge (nicht negative Ganzzahl). Ohne Angabe ``0``. + +Die ID eines Tags ist der SHA-256 seines aus Name und Besitzer gebildeten Werts und wird daher vom +Server bestimmt. Besitzer und Name kennzeichnen ein Tag gemeinsam: Hat der Besitzer bereits ein Tag +dieses Namens, schlägt das Erstellen mit einem Validierungsfehler fehl (``status: 1``, „A tag with +the same name and owner already exists.“). + +Antwort +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +Bei erfolgreicher Erstellung ist ``created`` ``true``. + +Tag aktualisieren +================= + +Anfrage +------- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +Anfragetext +~~~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +Der Text enthält alle Felder der Erstellung und zusätzlich die folgenden Felder. Das Tag wird als +Ganzes ersetzt; senden Sie also auch die ``paths``, die erhalten bleiben sollen. + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Feld + - Typ + - Erforderlich + - Beschreibung + * - ``id`` + - String + - Ja + - Die ID des zu aktualisierenden Tags. + * - ``seq_no`` + - Integer + - Ja + - Der von ``GET /setting/{id}`` zurückgegebene ``seq_no`` des Tags. + * - ``primary_term`` + - Integer + - Ja + - Der von ``GET /setting/{id}`` zurückgegebene ``primary_term`` des Tags. + +- Wurde das Tag nach dem Lesen geändert, sodass ``seq_no`` und ``primary_term`` nicht mehr passen, + schlägt die Aktualisierung mit einem Validierungsfehler fehl (``status: 1``, „The tag was changed + by someone else. Reload it and try again.“). Rufen Sie das Tag erneut ab und wiederholen Sie den + Vorgang. +- Eine Änderung von ``name`` oder ``owner`` gibt dem Tag eine neue ID; die ``id`` der Antwort ist die + neue. Hat der Besitzer bereits ein Tag des neuen Namens, schlägt die Aktualisierung mit „A tag + with the same name and owner already exists.“ fehl. +- Ändert sich der Besitzer, wird die Benutzerberechtigung des alten Besitzers in ``permissions`` + durch die des neuen Besitzers ersetzt. + +Antwort +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +Bei der Aktualisierung ist ``created`` ``false``. + +Tag löschen +=========== + +Anfrage +------- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +Antwort +------- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +Wird das Tag während des Löschens geändert, schlägt das Löschen mit „The tag was changed by someone +else. Reload it and try again.“ fehl. + +Wie Änderungen die Dokumente erreichen +====================================== + +Das Erstellen, Aktualisieren und Löschen eines Tags über diese API wird sofort in den Tags +gespeichert. Solange ``user.tag.enabled`` den Wert ``true`` hat, wird die Änderung für die Dokumente +(hinzugefügte und entfernte Pfade, eine Umbenennung oder eine Löschung) in die Warteschlange +gestellt und vom minütlichen Job „Log Aggregator“ (``log_aggregator``) angewendet. Bei ``false`` +wird nichts eingereiht; führen Sie nach dem Aktivieren der Tags den Job „Tag Updater“ +(``tag_updater``) aus. Siehe :doc:`../../admin/tagtype-guide`. + +Anwendungsbeispiele +=================== + +Ein Tag für alle angemeldeten Benutzer freigeben +------------------------------------------------ + +.. code-block:: bash + + # Das Tag mit paths, seq_no und primary_term lesen + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # Mit {role}guest in den Berechtigungen zurücksenden + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +Die Tags eines Benutzers auflisten +---------------------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +Siehe auch +========== + +- :doc:`api-admin-overview` - Admin API Übersicht +- :doc:`../api-tag` - Tags-API +- :doc:`../../admin/tagtype-guide` - Tag-Verwaltungsanleitung diff --git a/de/15.9/api/admin/index.rst b/de/15.9/api/admin/index.rst index ef7d9a93..a4eecd24 100644 --- a/de/15.9/api/admin/index.rst +++ b/de/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Admin API Referenz :caption: Such-Tuning api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/de/15.9/api/api-tag.rst b/de/15.9/api/api-tag.rst index 403a38f9..e2f9277b 100644 --- a/de/15.9/api/api-tag.rst +++ b/de/15.9/api/api-tag.rst @@ -2,7 +2,8 @@ Tags-API ======== -Dieses Dokument beschreibt die v2-Tags-API von |Fess|, mit der Benutzer Dokumente taggen. +Dieses Dokument beschreibt die v2-Tags-API von |Fess|, mit der angemeldete Benutzer ihre eigenen +Tags verwalten und an Dokumente vergeben. Informationen zum gemeinsamen Antwort-Envelope, zum Fehlermodell und zu CSRF finden Sie unter :doc:`api-overview`. Die Basis-URL lautet ``http:///api/v2/`` (Beispiel für eine lokale Umgebung: ``http://localhost:8080/api/v2``). @@ -11,18 +12,229 @@ Die Basis-URL lautet ``http:///api/v2/`` (Beispiel für eine lokale Tags sind standardmäßig deaktiviert. Um sie zu nutzen, setzen Sie ``user.tag.enabled=true`` in ``fess_config.properties``. ``features.user_tag`` von ``/api/v2/ui/config`` meldet den Zustand. + Solange Tags deaktiviert sind, antworten die Tag-Endpunkte auf eine Anfrage, die die CSRF- und + Origin-Prüfung besteht und eine unterstützte Methode verwendet, mit ``invalid_request`` (400). + +Funktionsweise der Tags +======================= + +- Tags werden pro Benutzer verwaltet. Wer ein Tag erstellt, ist sein Besitzer; der Besitzer ist die + Benutzer-ID der Anmeldung. Zwei Benutzer können denselben Namen verwenden und haben trotzdem zwei + getrennte Tags. +- Nur angemeldete Benutzer können Tags verwenden. Jeder Tag-Endpunkt handelt als Benutzer der + Anmeldesitzung; ein Zugriffstoken ersetzt keine Anmeldung. Ein Aufrufer ohne Anmeldung erhält + ``auth_required`` (401). +- Ein neues Tag ist privat: Nur sein Besitzer sieht es. Gibt der Besitzer das Tag frei, kann jeder + angemeldete Benutzer es sehen und danach filtern. Ein nicht angemeldeter Benutzer sieht kein Tag, + auch kein freigegebenes. +- Nur der Besitzer kann ein Tag ändern, löschen und an Dokumente vergeben oder davon entfernen. Ein + freigegebenes Tag eines anderen Benutzers kann nur angezeigt und zum Filtern verwendet werden. + Administratoren verwalten alle Tags im Verwaltungsbildschirm (siehe :doc:`../admin/tagtype-guide`). +- Ein Tag wird an die URL eines Dokuments vergeben, sodass jedes indexierte Dokument mit dieser URL + es erhält. + +Jedes Tag hat zwei Bezeichner. + +``value`` + Der Tag-Wert, ``base64url(Name):base64url(Besitzer)`` (UTF-8, ohne Auffüllung), der im Feld + ``tag`` des Index gespeichert wird. Behandeln Sie ihn als undurchsichtigen Wert zum Filtern von + Suchergebnissen. + +``id`` + Die Tag-ID, der SHA-256 von ``value`` in hexadezimalen Kleinbuchstaben (64 Zeichen). Sie wird in + Pfaden wie ``/api/v2/tags/{tagId}`` angegeben. Eine Umbenennung ändert sowohl ``value`` als auch + ``id``. + +Ein Tag-Name wird NFKC-normalisiert, Leerzeichenfolgen werden zu einem Leerzeichen zusammengefasst, +und Anfang und Ende werden getrimmt. Das Ergebnis muss 1 bis ``user.tag.name.max.length`` +(Standard: ``50``) Zeichen lang sein; Namen mit einem Steuer- oder Formatzeichen (etwa einem +Nullbreitenzeichen oder einer Bidi-Überschreibung) werden abgelehnt. + +Tags in der Suche +================= + +Solange ``user.tag.enabled`` den Wert ``true`` hat, behandelt die Such-API (``/api/v2/search``) Tags +wie folgt. + +- Jeder Treffer enthält die für den Aufrufer sichtbaren Tags als ``tags``. Jeder Eintrag hat + ``value``, ``name``, ``owner``, ``mine`` (``true``, wenn der Aufrufer das Tag besitzt) und + ``shared`` (``true`` für ein freigegebenes Tag). Ohne Tags fehlt ``tags``. Das Indexfeld ``tag`` + selbst wird nie zurückgegeben. +- ``facet.field=tag`` liefert in ``facet_field`` eine Facette der für den Aufrufer sichtbaren Tags. + Neben ``value`` und ``count`` hat jeder Bucket ``label`` (den Tag-Namen), ``owner``, ``mine`` und + ``shared``. +- ``fields.tag=`` grenzt die Ergebnisse auf Dokumente mit einem Tag ein. Übergeben Sie den + ``value`` aus ``tags`` eines Treffers oder aus einem Facetten-Bucket unverändert. + +Eine Bedingung auf Tags (``fields.tag``, ``tag:``, ``ex_q``, ``facet.query``) trifft nur den exakten +Wert eines Tags, das der Aufrufer sehen kann. Der Wert eines für ihn unsichtbaren Tags sowie +Platzhalter-, Präfix-, unscharfe und Bereichsbedingungen treffen nichts. Ein Aufrufer ohne Anmeldung +erhält weder Tags noch eine Tag-Facette, und eine Tag-Bedingung trifft nichts. + +Ein Benutzer sieht höchstens ``user.tag.visible.max.size`` (Standard: ``1000``) Tags, die eigenen +zuerst. Weitere Tags erscheinen weder in ``tags`` der Treffer noch in der Facette, lassen sich aber +weiterhin zum Filtern verwenden. + +Wann Dokumente Änderungen übernehmen +==================================== + +Das Erstellen, Ändern und Löschen von Tags sowie das Vergeben und Entfernen an Dokumenten zeigen die +Tag-Endpunkte sofort. Das Feld ``tag`` der indexierten Dokumente wird dagegen über eine Warteschlange +im Speicher aktualisiert, die der Job „Log Aggregator“ (``log_aggregator``) jede Minute gesammelt +anwendet. Suchtreffer, Facette und Filter spiegeln eine Änderung daher erst nach bis zu etwa einer +Minute wider. Nach einer Umbenennung behalten die Dokumente den alten Wert, bis die Warteschlange das +nächste Mal verarbeitet wird, und das Tag wird in der Zwischenzeit nicht an ihnen angezeigt. + +Zur Warteschlange und zu den Jobs siehe :doc:`../admin/tagtype-guide`. + +Tags auflisten +============== + +Anfrage +------- + +================== ==================================================== +HTTP-Methode GET +Endpunkt ``/api/v2/tags`` +================== ==================================================== + +Gibt die Tags des Aufrufers nach Sortierreihenfolge und Name zurück. Freigegebene Tags anderer +Benutzer sind nicht enthalten. + +Antwort +------- + +Bei Erfolg (200) werden die folgenden Felder direkt unter ``response`` des gemeinsamen Envelopes zurückgegeben. + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "10cfcc876984e934930a5e4461088f738d748271320a8755344fd7f2edc8120a", + "value": "enUtcHJ1ZWZlbg:YW5uYQ", + "name": "zu-pruefen", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Antwortfelder + + * - ``tags`` + - Die Tags des Aufrufers. Jedes hat ``id``, ``value``, ``name``, ``shared`` (``true`` für ein + freigegebenes Tag), ``sort_order`` und ``path_count`` (die Anzahl der URLs mit dem Tag). + +Tabelle: Antwortfelder + +Ein Tag erstellen +================= + +Anfrage +------- + +================== ==================================================== +HTTP-Methode POST +Endpunkt ``/api/v2/tags`` +================== ==================================================== + +Erstellt ein Tag des Aufrufers. Als zustandsändernde Anfrage erfordert sie den Header +``X-Fess-CSRF-Token`` (siehe :doc:`api-overview`). -Ein Tag ist ein Label der Art „Tag“ (siehe :doc:`../admin/labeltype-guide`): Der Labelname ist der -Tag-Name, der Wert der SHA-256 des Namens in Hexadezimalform, die eingeschlossenen Pfade sind die -getaggten URLs, und die Berechtigungen bestimmen, wer das Tag sehen kann. Ein Tag ist nur sichtbar, -wenn sein Label für den Aufrufer sichtbar ist. +- Ein Benutzer kann höchstens ``user.tag.max.tags`` (Standard: ``1000``) Tags haben. Darüber hinaus + antwortet der Endpunkt mit ``invalid_request`` (400). +- Hat der Aufrufer bereits ein Tag dieses Namens, antwortet der Endpunkt mit ``conflict`` (409). Ein + gleichnamiges Tag eines anderen Benutzers spielt keine Rolle. -Die Such-API (``/api/v2/search``) gibt zu jedem Treffer die für den Aufrufer sichtbaren Tags als -``tags`` zurück. ``fields.tag=`` grenzt die Ergebnisse auf Dokumente mit einem Tag ein, und -``facet.field=tag`` liefert eine Tag-Facette. Das Indexfeld ``tag`` selbst wird nicht zurückgegeben. +Senden Sie ``Content-Type: application/json``; der Body darf höchstens 1 KiB (1024 Byte) groß sein. -Tags abrufen -============ +:: + + { + "name": "zu-pruefen", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Anfrage-Body + + * - ``name`` + - Tag-Name (str, erforderlich). + * - ``shared`` + - ``true`` macht das Tag für jeden angemeldeten Benutzer sichtbar (bool, Standard: ``false``). + +Tabelle: Anfrage-Body + +Antwort +------- + +Bei Erfolg (200) enthält ``tag`` direkt unter ``response`` das neue Tag in der Form eines Eintrags +von ``GET /api/v2/tags`` mit ``path_count`` ``0``. + +Ein Tag ändern +============== + +Anfrage +------- + +================== ==================================================== +HTTP-Methode PUT +Endpunkt ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Benennt ein Tag des Aufrufers um oder ändert, ob es freigegeben ist. Der Header +``X-Fess-CSRF-Token`` ist erforderlich. + +- Der Body enthält ``name``, ``shared`` oder beides. +- Ein neuer ``name`` benennt das Tag um und gibt ihm eine neue ``id`` und einen neuen ``value``. + Dokumente mit dem alten Wert erhalten den neuen, wenn die Warteschlange das nächste Mal verarbeitet + wird. Eine Umbenennung auf einen Namen, den der Aufrufer bereits verwendet, ergibt ``conflict`` + (409) und lässt das Tag unverändert. +- ``shared`` ändert nur, wer das Tag sieht; kein Dokument wird aktualisiert. Wird ``shared`` auf + ``false`` gesetzt, bleiben die Rollen und Gruppen, die ein Administrator zu den Berechtigungen + hinzugefügt hat, erhalten. +- Ein freigegebenes Tag eines anderen Benutzers ergibt ``forbidden`` (403), ein für den Aufrufer + unsichtbares Tag ``not_found`` (404). +- Ein Schreibvorgang, der wiederholt gegen eine andere Aktualisierung verliert, ergibt ebenfalls + ``conflict`` (409). + +:: + + { + "name": "geprueft", + "shared": true + } + +Bei Erfolg (200) enthält ``response`` ``tag`` (das geänderte Tag) und ``renamed`` (``true``, wenn +das Tag umbenannt wurde; dann sind ``tag.id`` und ``tag.value`` neu). + +Ein Tag löschen +=============== + +Anfrage +------- + +================== ==================================================== +HTTP-Methode DELETE +Endpunkt ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Löscht ein Tag des Aufrufers. Die Dokumente verlieren seinen Wert, wenn die Warteschlange das nächste +Mal verarbeitet wird. Der Header ``X-Fess-CSRF-Token`` ist erforderlich. Ein freigegebenes Tag eines +anderen Benutzers ergibt ``forbidden`` (403), ein für den Aufrufer unsichtbares Tag ``not_found`` +(404). + +Bei Erfolg (200) enthält ``response`` ``id`` (die ID des gelöschten Tags) und ``deleted`` (immer +``true``). + +Die Tags eines Dokuments abrufen +================================ Anfrage ------- @@ -32,8 +244,9 @@ HTTP-Methode GET Endpunkt ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Gibt die für den Aufrufer sichtbaren Tags des Dokuments zurück. Kann der Aufrufer das Dokument nicht -durchsuchen, antwortet der Endpunkt mit ``not_found`` (404). +Gibt die für den Aufrufer sichtbaren Tags an der URL des Dokuments zurück sowie die eigenen Tags des +Aufrufers, die dort noch nicht vergeben sind. Das Dokument wird mit den Rollen des Aufrufers +gesucht; ein Dokument, das der Aufrufer nicht durchsuchen kann, ergibt ``not_found`` (404). Antwort ------- @@ -46,10 +259,25 @@ Bei Erfolg (200) werden die folgenden Felder direkt unter ``response`` des gemei "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "zu-pruefen", "mine": true } - ] + { + "id": "10cfcc876984e934930a5e4461088f738d748271320a8755344fd7f2edc8120a", + "value": "enUtcHJ1ZWZlbg:YW5uYQ", + "name": "zu-pruefen", + "owner": "anna", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -58,21 +286,24 @@ Bei Erfolg (200) werden die folgenden Felder direkt unter ``response`` des gemei * - ``doc_id`` - Dokument-ID (str). + * - ``tags`` + - Die für den Aufrufer sichtbaren Tags an der URL des Dokuments. Jedes hat ``id``, ``value``, + ``name``, ``owner``, ``mine`` (``true``, wenn der Aufrufer das Tag besitzt) und ``shared`` + (``true`` für ein freigegebenes Tag). * - ``addable`` - - ``true``, wenn der Aufrufer angemeldet ist und Tags hinzufügen kann (bool). + - Die Tags des Aufrufers, die nicht an der URL des Dokuments vergeben sind, in derselben Form + wie ``tags``. * - ``added`` - - Nur POST. ``false``, wenn der Aufrufer das Dokument bereits getaggt hatte (bool). + - Nur POST. ``false``, wenn das Tag bereits am Dokument war (bool). + * - ``tag`` + - Nur POST. Das an das Dokument vergebene Tag, in derselben Form wie ``tags``. * - ``removed`` - - Nur DELETE (bool). - * - ``tags`` - - Die für den Aufrufer sichtbaren Tags. Jedes hat ``value`` (den Labelwert für ``fields.tag``), - ``name`` (den Tag-Namen) und ``mine`` (``true``, wenn der Aufrufer zu den Berechtigungen des - Tags gehört). + - Nur DELETE. ``false``, wenn das Tag nicht am Dokument war (bool). Tabelle: Antwortfelder -Ein Tag hinzufügen -================== +Ein Tag an ein Dokument vergeben +================================ Anfrage ------- @@ -82,17 +313,11 @@ HTTP-Methode POST Endpunkt ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Taggt die URL des Dokuments für den angemeldeten Benutzer; ein Zugriffstoken ersetzt keine Anmeldung. -Als zustandsändernde Anfrage erfordert sie den Header ``X-Fess-CSRF-Token``. +Fügt die URL des Dokuments einem Tag des Aufrufers hinzu. Der Header ``X-Fess-CSRF-Token`` ist +erforderlich. -- Gibt es bereits ein Tag dieses Namens, wird die URL zu seinen eingeschlossenen Pfaden und der - Benutzer zu seinen Berechtigungen hinzugefügt. Andernfalls wird ein Tag erstellt, das nur der - Benutzer sehen kann. Tags gleichen Namens werden daher zu einem zusammengeführt, und Benutzer, die - ein Tag gleichen Namens hinzugefügt haben, sehen gegenseitig, wo ihre Tags gesetzt sind. -- Erneutes Taggen desselben Dokuments ergibt ``added: false``. -- Ein Dokument kann höchstens ``user.tag.max.document.tags`` (Standard: ``100``) Tags haben. - -Senden Sie ``Content-Type: application/json`` mit dem Tag-Namen in ``name``. +Der Body (``Content-Type: application/json``, höchstens 1 KiB) enthält entweder ``id``, ein +vorhandenes Tag, oder ``name``, einen Tag-Namen. Sind beide angegeben, gilt ``id``. :: @@ -100,52 +325,101 @@ Senden Sie ``Content-Type: application/json`` mit dem Tag-Namen in ``name``. "name": "zu-pruefen" } -Der Name wird NFKC-normalisiert, Leerzeichenfolgen werden zusammengefasst und er wird getrimmt. Er -muss 1 bis ``user.tag.name.max.length`` (Standard: ``50``) Zeichen lang sein; Namen mit einem -Steuer- oder Formatzeichen (etwa einem Nullbreitenzeichen oder einer Bidi-Überschreibung) werden -abgelehnt. +- Mit ``name`` wird ein privates Tag dieses Namens erstellt und vergeben, wenn der Aufrufer noch + keines hat. Das neue Tag zählt gegen ``user.tag.max.tags``. +- Ein Tag kann an höchstens ``user.tag.max.paths`` (Standard: ``10000``) URLs vergeben werden. + Darüber hinaus antwortet der Endpunkt mit ``invalid_request`` (400). +- Die ``id`` eines Tags eines anderen Benutzers ergibt ``forbidden`` (403), wenn der Aufrufer das + Tag sehen kann, sonst ``not_found`` (404). +- Bei Erfolg enthält die Antwort die Felder von „Die Tags eines Dokuments abrufen“ sowie ``added`` + und ``tag``. Die Tag-Endpunkte zeigen das Tag sofort; die Suchergebnisse der Dokumente mit der URL + übernehmen es, wenn die Warteschlange das nächste Mal verarbeitet wird (etwa eine Minute später). -Ein Tag entfernen -================= +Ein Tag von einem Dokument entfernen +==================================== Anfrage ------- ================== ==================================================== HTTP-Methode DELETE -Endpunkt ``/api/v2/documents/{docId}/tags?value=`` +Endpunkt ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -Entfernt den angemeldeten Benutzer aus den Berechtigungen des mit ``value`` angegebenen Tags. Bleibt -keine Berechtigung eines Benutzers, einer Gruppe oder einer Rolle übrig, wird das Tag gelöscht und aus -den Dokumenten entfernt. Gehört der Benutzer nicht zu den Berechtigungen des Tags, antwortet der -Endpunkt mit ``forbidden`` (403). Der Header ``X-Fess-CSRF-Token`` ist erforderlich. +Entfernt die URL des Dokuments aus dem mit ``tagId`` angegebenen Tag des Aufrufers. Der Header +``X-Fess-CSRF-Token`` ist erforderlich. Ein Tag eines anderen Benutzers ergibt ``forbidden`` (403), +wenn der Aufrufer es sehen kann, sonst ``not_found`` (404). Bei Erfolg enthält die Antwort die +Felder von „Die Tags eines Dokuments abrufen“ sowie ``removed``. Fehlerantwort ============= +Details zum Fehlermodell finden Sie unter :doc:`api-overview`. Die Tag-Endpunkte geben die folgenden +HTTP-Status zurück. + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: Fehlerantwort * - Statuscode - Beschreibung * - 400 Bad Request - - Wenn die Anfrage ungültig ist (auch wenn Tags deaktiviert sind, der Tag-Name ungültig ist oder - ein Tag-Limit überschritten wird). + - Wenn die Anfrage ungültig ist, auch wenn Tags deaktiviert sind, der Tag-Name ungültig ist, ein + erforderliches Feld fehlt oder ``user.tag.max.tags`` bzw. ``user.tag.max.paths`` + überschritten würde. * - 401 Unauthorized - - POST oder DELETE ohne Anmeldung. + - Ohne Anmeldung (ein Zugriffstoken ersetzt sie nicht). * - 403 Forbidden - - Ein fehlendes oder abgelaufenes CSRF-Token oder ein DELETE eines Tags, das der Benutzer nicht - hinzugefügt hat. + - Ein fehlendes oder abgelaufenes CSRF-Token oder eine Änderung am Tag eines anderen Benutzers. + Die CSRF-Prüfung erfolgt vor der Anmeldeprüfung, daher erhält eine zustandsändernde Anfrage + ohne Sitzung 403 statt 401. * - 404 Not Found - - Wenn das Dokument nicht gefunden wird oder der Aufrufer es nicht durchsuchen kann. + - Wenn das Tag nicht existiert oder für den Aufrufer unsichtbar ist, oder wenn das Dokument nicht + gefunden wird oder der Aufrufer es nicht durchsuchen kann. * - 405 Method Not Allowed - Wenn die HTTP-Methode nicht zulässig ist. + * - 409 Conflict + - Wenn bereits ein Tag dieses Namens existiert oder ein Schreibvorgang gegen eine andere + Aktualisierung verloren hat. * - 413 Payload Too Large - - Wenn der Anfrage-Body die Größenbegrenzung überschreitet. + - Wenn der Anfrage-Body die Größenbegrenzung (1 KiB) überschreitet. * - 415 Unsupported Media Type - Wenn der ``Content-Type`` nicht unterstützt wird. * - 500 Internal Server Error - Wenn ein interner Serverfehler auftritt. Tabelle: Fehlerantwort + +Einstellungen +============= + +Die folgenden Einstellungen in ``fess_config.properties`` passen die Tags an. + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - Eigenschaft + - Beschreibung + - Standard + * - ``user.tag.enabled`` + - Ob angemeldete Benutzer Tags verwenden können. + - ``false`` + * - ``user.tag.name.max.length`` + - Maximale Länge eines Tag-Namens in Codepunkten. + - ``50`` + * - ``user.tag.max.tags`` + - Maximale Anzahl Tags, die ein Benutzer besitzen kann. + - ``1000`` + * - ``user.tag.max.paths`` + - Maximale Anzahl URLs, an die ein Tag vergeben werden kann. + - ``10000`` + * - ``user.tag.queue.max.size`` + - Maximale Anzahl Änderungen, die im Speicher gehalten werden, bis sie die Dokumente erreichen. + Eine Änderung darüber hinaus wird mit einem WARN-Log verworfen. + - ``10000`` + * - ``user.tag.process.batch.size`` + - Anzahl der URLs pro Bulk-Anfrage, wenn Änderungen auf die Dokumente angewendet werden. + - ``100`` + * - ``user.tag.visible.max.size`` + - Maximale Anzahl Tags, die ein Benutzer in einer Suche sieht. + - ``1000`` diff --git a/de/15.9/api/api-uiconfig.rst b/de/15.9/api/api-uiconfig.rst index 9eb2067d..82df02fa 100644 --- a/de/15.9/api/api-uiconfig.rst +++ b/de/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ Alle Felder sind Pflichtfelder. - Ob der Export von Suchergebnissen (``GET /api/v2/documents/export``) aktiviert ist (``api.search.export``). * - ``user_tag`` - boolean - - Ob Tags (``/api/v2/documents/{docId}/tags``) aktiviert sind (``user.tag.enabled``). + - Ob benutzereigene Tags aktiviert sind (``user.tag.enabled``): Die Tag-Endpunkte (``/api/v2/tags``, ``/api/v2/documents/{docId}/tags``) antworten, und Suchtreffer enthalten ``tags``. * - ``popular_word`` - boolean - Gibt an, ob die Beliebte-Wörter-Funktion aktiviert ist. diff --git a/de/15.9/config/properties.po b/de/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/de/15.9/config/properties.po +++ b/de/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/de/15.9/config/properties.rst b/de/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/de/15.9/config/properties.rst +++ b/de/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/en/15.9/admin/index.rst b/en/15.9/admin/index.rst index 2e98d5d7..d4a24ca0 100644 --- a/en/15.9/admin/index.rst +++ b/en/15.9/admin/index.rst @@ -28,6 +28,7 @@ logs, and backups. fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/en/15.9/admin/labeltype-guide.rst b/en/15.9/admin/labeltype-guide.rst index 611b473f..02a7074a 100644 --- a/en/15.9/admin/labeltype-guide.rst +++ b/en/15.9/admin/labeltype-guide.rst @@ -84,43 +84,11 @@ Display Order Specifies the display order of labels. -Kind -:::: - -Specify "Label" or "Tag". An ordinary label is "Label". "Tag" is a tag that users add from the -search screen (see "Tags" below). An existing label without a kind is treated as "Label". - - Deleting Configuration ---------------------- Click the configuration name on the list page, then click the Delete button to display a confirmation screen. Click the Delete button to remove the configuration. -Tags ----- - -With ``user.tag.enabled=true`` (default: ``false``) in ``fess_config.properties``, logged-in users -can tag search results. In the bundled ``bootstrap`` theme, tags are shown on the results, users can -add tags and remove their own, and a "Tags" facet narrows the results. For the API, see -:doc:`../api/api-tag`. - -A tag is stored as a label of the kind "Tag": the name is the tag name, the value is the SHA-256 of -the name, the included paths are the tagged URLs (one per line, exact match), and the permissions -decide who can see the tag. A user who adds a tag is added to its permissions. - -- A tag is visible only when the permissions of its label match the caller. Administrators can edit - a tag on this page to share it with a role or a group, or delete it. -- Tags with the same name are merged into one label, so users who added a tag of the same name can - see where each other's tags are. -- Tags are not included in the label list API (``/api/v2/labels``) or in the label choices of the - search screen. -- Tags count toward the label limit (``page.labeltype.max.fetch.size``, default: 1000). Once the - limit is reached, no new tag can be created. -- After an administrator changes or deletes a tag on this page, the indexed documents keep the old - values until they are crawled again or the "Label Updater" job runs. -- A document can have up to ``user.tag.max.document.tags`` (default: 100) tags, and a tag name can be - up to ``user.tag.name.max.length`` (default: 50) characters long. - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png \ No newline at end of file diff --git a/en/15.9/admin/tagtype-guide.rst b/en/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..c6ecdced --- /dev/null +++ b/en/15.9/admin/tagtype-guide.rst @@ -0,0 +1,146 @@ +=== +Tag +=== + +Overview +======== + +This page explains the screen that manages the tags of users. + +A tag is a marker that a logged-in user puts on documents in the search results. Tags are kept per +user: the user who creates a tag owns it, and two users can use the same name and still have two +separate tags. Tags are not :doc:`labels `, which administrators define by URL +patterns; users create tags themselves and put them on individual documents. + +Tags are disabled by default. To use them, set ``user.tag.enabled=true`` in +``fess_config.properties``. Once they are enabled, the bundled ``bootstrap`` theme lets logged-in +users put tags on search results and take them off, and filter by a tag facet. "My tags" lets them +rename, share and delete their own tags. Shared tags of other users are shown with a "Shared:" +prefix. For the user API and the settings, see :doc:`../api/api-tag`. + +On this screen, administrators list, create, edit and delete the tags of every user. + +Management Operations +===================== + +Display Method +-------------- + +To open the tag list page, click [Crawler > Tag] in the left menu. Viewing requires the +``admin-tagtype`` or ``admin-tagtype-view`` role; creating, editing and deleting require +``admin-tagtype``. + +The list shows the name and the owner of each tag, by sort order, name and owner. You can search by +name and by owner; each matches the tags that contain the text entered. + +Click a name to edit the tag. + +Creating Configuration +---------------------- + +To open the tag creation page, click the New button. + +Configuration Items +------------------- + +Name +:::: + +Specifies the tag name. The name is NFKC-normalized, runs of whitespace are collapsed to one space +and the ends are trimmed. The result must be 1 to ``user.tag.name.max.length`` (default: 50) +characters and cannot contain a control or format character. + +Owner +::::: + +Specifies the login user ID of the user who owns the tag. The owner and the name together identify +a tag, so one owner cannot have two tags of the same name, even on different virtual hosts. + +When you change the owner, the user permission of the old owner in Permissions is replaced with +that of the new owner. + +Paths +::::: + +Specifies the URLs of the documents to put the tag on, one per line. A URL must equal the ``url`` +field of an indexed document; regular expressions are not used. A tag can have at most +``user.tag.max.paths`` (default: 10000) URLs. + +Permissions +::::::::::: + +Specifies the users, groups and roles that can see the tag, as for labels: {user}user name for a +user, {group}group name for a group and {role}role name for a role. When left empty, only the owner +can see the tag. + +The owner always sees their own tags, whatever the permissions. A user who is not logged in never +sees a tag, whatever the permissions. + +Virtual Host +:::::::::::: + +Specifies the host name of the virtual host where the tag is shown. A tag created by a user gets +the virtual host the user was accessing. On a search screen accessed through a virtual host, only +the tags with that virtual host name here are visible. An access that matches no virtual host sees +tags whatever this field holds. For details, see +:doc:`Virtual Host in the Configuration Guide <../config/security-virtual-host>`. + +Sort Order +:::::::::: + +Specifies the display order of the tag. + +Deleting Configuration +---------------------- + +Click a name on the list page and then the Delete button to show a confirmation screen. Clicking +the Delete button deletes the tag, and its value is removed from the documents. + +Sharing +======= + +When a user shares a tag, the values of ``role.search.guest.permissions`` (default: +``{role}guest``) are added to its permissions. Whether a tag is visible is decided with these values +added to the roles of the logged-in user, so a shared tag is visible to every logged-in user, who +can also filter by it. Unsharing removes only these values. + +On this screen, an administrator can also add groups or roles to the permissions to show a tag to +some users only. Only the owner and administrators can change a tag; other users can only show and +filter by the tags they see. + +How Changes Reach Documents +=========================== + +A document keeps its tags in the ``tag`` field of the index, as ``base64url(name):base64url(owner)``. + +- Creating, editing and deleting tags, and users putting tags on and taking them off documents, are + saved to the tags (the ``fess_config.tag_type`` index) at once. The documents are updated through + an in-memory queue that the "Log Aggregator" job (``log_aggregator``) applies in bulk every + minute, so the search results reflect a change after up to about a minute. +- Changing the paths on this screen updates the documents of the added and removed URLs. Changing + the name or the owner replaces the old value on the documents with the new one. +- When documents are indexed by a crawl or a data store, their ``tag`` field is set from the paths + of the tags, so tags survive a re-crawl. +- The "Tag Updater" job (``tag_updater``) rebuilds the ``tag`` field of every document from the + tags. It has no schedule; run it from the scheduler when needed. + +Notes for Operators +=================== + +- **Run Log Aggregator on every node.** Each JVM has its own queue, which only the Log Aggregator of + that node processes. Keep the target of the ``log_aggregator`` job at the default ``all``; when + it is limited to some nodes, the changes received by the other nodes never reach the documents. +- **Run Tag Updater in the following cases.** The queue is in memory, so changes not yet applied are + lost when |Fess| restarts. While ``user.tag.enabled=false``, tag changes do not reach the + documents, and a re-crawl clears their ``tag`` field. After a restore from a backup, the tags of + the documents also need rebuilding. And when the queue exceeds ``user.tag.queue.max.size`` + (default: 10000), the changes beyond it are dropped with a WARN log. In each case, running + ``tag_updater`` rebuilds the tags of the documents. +- **The owner of a tag is the login user ID.** When a user ID changes, the tags stay with the old + ID. With SAML, the NameID must be persistent. With Entra ID the owner is the UPN, and with LDAP it + is the user name with the letter case typed at login. Deleting a user leaves the user's tags; + delete the ones no longer needed on this screen. +- **Existing indexes work too.** At startup, when the document index has no mapping for the + ``tag`` field, it is added as ``keyword``. Existing fields are not changed. +- The tags are stored in the ``fess_config.tag_type`` index. They are included in ``fess_config.bulk`` + of a backup, but not in ``fess_basic_config.bulk``. diff --git a/en/15.9/api/admin/api-admin-overview.rst b/en/15.9/api/admin/api-admin-overview.rst index f3ce7629..7277cc79 100644 --- a/en/15.9/api/admin/api-admin-overview.rst +++ b/en/15.9/api/admin/api-admin-overview.rst @@ -452,6 +452,8 @@ Search Tuning - Description * - :doc:`api-admin-labeltype` - Label types + * - :doc:`api-admin-tagtype` + - Tags * - :doc:`api-admin-keymatch` - Key match * - :doc:`api-admin-boostdoc` diff --git a/en/15.9/api/admin/api-admin-tagtype.rst b/en/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..5cf1a44a --- /dev/null +++ b/en/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,393 @@ +=========== +TagType API +=========== + +Overview +======== + +TagType API is an API for managing the tags of users in |Fess|, the per-user tags that logged-in users +put on documents (see :doc:`../../admin/tagtype-guide`). It manages the tags of every user, whether +``user.tag.enabled`` is ``true`` or not. + +For common specifications regarding authentication, responses (``status`` codes, ``version`` field, +error format, HTTP status codes, etc.), refer to :doc:`api-admin-overview`. +To access this API, you must provide an access token with admin API permission (``admin-api``) +in the ``Authorization: Bearer `` header. + +The JSON field names of this API are snake_case (``sort_order``, ``virtual_host``, ``seq_no``, +``primary_term``, ...). + +Base URL +======== + +:: + + /api/admin/tagtype + +Endpoint List +============= + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - Method + - Path + - Description + * - GET + - /settings + - List tags + * - GET + - /setting/{id} + - Get a tag + * - POST + - /setting + - Create a tag + * - PUT + - /setting + - Update a tag + * - DELETE + - /setting/{id} + - Delete a tag + +List Tags +========= + +Request +------- + +:: + + GET /api/admin/tagtype/settings + +Parameters +~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Parameter + - Type + - Required + - Description + * - ``size`` + - Integer + - No + - Number of items per page. Default is the ``paging.page.size`` setting value (``25`` by default). + * - ``page`` + - Integer + - No + - Page number (starts from 1). Default is ``1``. + * - ``name`` + - String + - No + - Filter by tag name (wildcard search: matches the names that contain the text). + * - ``owner`` + - String + - No + - Filter by owner (wildcard search: matches the owners that contain the text). + +The tags are sorted by sort order, name and owner. + +Response +-------- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + The list leaves out the paths of the tags, which can be long, so the entries have no ``paths``. + PUT replaces the whole tag: to edit a tag, get it with ``GET /setting/{id}`` first so that its + ``paths`` are kept. + +Get a Tag +========= + +Request +------- + +:: + + GET /api/admin/tagtype/setting/{id} + +Response +-------- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` and ``primary_term`` identify the version of the tag that was read. ``paths`` and +``permissions`` hold one entry per line. + +Create a Tag +============ + +Request +------- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +Request Body +~~~~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +Field Descriptions +~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Field + - Type + - Required + - Description + * - ``name`` + - String + - Yes + - Tag name. It is NFKC-normalized, runs of whitespace are collapsed and the ends are trimmed; + the result must be 1 to ``user.tag.name.max.length`` (default: ``50``) characters without a + control or format character. + * - ``owner`` + - String + - Yes + - Login user ID of the user who owns the tag (max 1000 characters). + * - ``paths`` + - String + - No + - URLs of the documents to put the tag on, separated by a newline (``\n``). Each must equal the + ``url`` field of a document. At most ``user.tag.max.paths`` (default: ``10000``). + * - ``permissions`` + - String + - No + - Users/groups/roles that can see the tag (e.g. ``{role}guest``), separated by a newline + (``\n``). When empty, only the owner can see the tag. ``{role}guest`` (the value of + ``role.search.guest.permissions``) shares the tag with every logged-in user. + * - ``virtual_host`` + - String + - No + - Virtual host (max 1000 characters). + * - ``sort_order`` + - Integer + - No + - Display order (non-negative integer). Defaults to ``0`` if not specified. + +The ID of a tag is the SHA-256 of its value, which is made from the name and the owner, so it is +decided by the server. The owner and the name together identify a tag: creating a tag whose owner +already has a tag of the name fails with a validation error (``status: 1``, "A tag with the same +name and owner already exists."). + +Response +-------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +On successful creation, ``created`` is ``true``. + +Update a Tag +============ + +Request +------- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +Request Body +~~~~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +The body has all the fields used at creation time, and the following fields in addition. The tag +is replaced as a whole, so send the ``paths`` you want to keep as well. + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Field + - Type + - Required + - Description + * - ``id`` + - String + - Yes + - The ID of the tag to update. + * - ``seq_no`` + - Integer + - Yes + - The ``seq_no`` of the tag returned by ``GET /setting/{id}``. + * - ``primary_term`` + - Integer + - Yes + - The ``primary_term`` of the tag returned by ``GET /setting/{id}``. + +- When the tag was changed after it was read, that is, ``seq_no`` and ``primary_term`` no longer + match, the update fails with a validation error (``status: 1``, "The tag was changed by someone + else. Reload it and try again."). Get the tag again and retry. +- Changing ``name`` or ``owner`` gives the tag a new ID; the response ``id`` is the new one. When the + owner already has a tag of the new name, the update fails with "A tag with the same name and owner + already exists.". +- When the owner changes, the user permission of the old owner in ``permissions`` is replaced with + that of the new owner. + +Response +-------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +On update, ``created`` is ``false``. + +Delete a Tag +============ + +Request +------- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +Response +-------- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +When the tag is changed while it is being deleted, the deletion fails with "The tag was changed by +someone else. Reload it and try again.". + +How Changes Reach Documents +=========================== + +Creating, updating and deleting a tag through this API is saved to the tags at once. While +``user.tag.enabled`` is ``true``, the change is queued for the documents (the added and removed +paths, a rename or a deletion) and applied by the per-minute "Log Aggregator" job +(``log_aggregator``). While it is ``false``, nothing is queued; run the "Tag Updater" job +(``tag_updater``) after enabling tags. See :doc:`../../admin/tagtype-guide`. + +Usage Examples +============== + +Share a Tag with Every Logged-in User +------------------------------------- + +.. code-block:: bash + + # Read the tag, including paths, seq_no and primary_term + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # Send it back with {role}guest added to the permissions + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +List the Tags of a User +----------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +See Also +======== + +- :doc:`api-admin-overview` - Admin API Overview +- :doc:`../api-tag` - Tags API +- :doc:`../../admin/tagtype-guide` - Tag Management Guide diff --git a/en/15.9/api/admin/index.rst b/en/15.9/api/admin/index.rst index 2363b3de..cb21c0c2 100644 --- a/en/15.9/api/admin/index.rst +++ b/en/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Admin API Reference :caption: Search Tuning api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/en/15.9/api/api-tag.rst b/en/15.9/api/api-tag.rst index 7103bb70..aff3e76c 100644 --- a/en/15.9/api/api-tag.rst +++ b/en/15.9/api/api-tag.rst @@ -2,7 +2,8 @@ Tags API ======== -This document describes the v2 Tags API of |Fess|, which lets users tag documents. +This document describes the v2 Tags API of |Fess|, with which logged-in users manage their own +tags and put them on documents. For the common response envelope, error model, and CSRF, see :doc:`api-overview`. The base URL is ``http:///api/v2/`` (local environment example: ``http://localhost:8080/api/v2``). @@ -11,29 +12,230 @@ The base URL is ``http:///api/v2/`` (local environment example: ``h Tags are disabled by default. To use them, set ``user.tag.enabled=true`` in ``fess_config.properties``. ``features.user_tag`` of ``/api/v2/ui/config`` reports the state. + While tags are disabled, a request that passes the CSRF and Origin checks and uses a + supported method gets ``invalid_request`` (400) from the tag endpoints. + +How Tags Work +============= + +- Tags are kept per user. The user who creates a tag owns it, and the owner is the login user ID. + Two users can use the same name and still have two separate tags. +- Only logged-in users can use tags. Every tag endpoint acts as the user of the login session; an + access token does not stand in for a login. A caller without a login gets ``auth_required`` + (401). +- A new tag is private: only its owner sees it. When the owner shares the tag, every logged-in + user can see it and filter by it. A user who is not logged in sees no tag, shared or not. +- Only the owner can change or delete a tag, or put it on and take it off documents. A shared tag of + another user can only be shown and filtered on. Administrators manage all tags on the admin + screen (see :doc:`../admin/tagtype-guide`). +- A tag is put on the URL of a document, so every indexed document with that URL gets it. + +Each tag has two identifiers. + +``value`` + The tag value, ``base64url(name):base64url(owner)`` (UTF-8, without padding), stored in the + ``tag`` field of the index. Treat it as an opaque value to filter search results with. + +``id`` + The tag ID, the SHA-256 of ``value`` in lowercase hex (64 characters). It goes into paths such + as ``/api/v2/tags/{tagId}``. Renaming a tag changes both ``value`` and ``id``. + +A tag name is NFKC-normalized, runs of whitespace are collapsed to one space and the ends are +trimmed. The result must be 1 to ``user.tag.name.max.length`` (default: ``50``) characters, and +names with a control or format character (such as a zero-width character or a bidi override) are +refused. + +Tags in Search +============== + +While ``user.tag.enabled`` is ``true``, the search API (``/api/v2/search``) handles tags as follows. + +- Each hit carries the tags that the caller can see as ``tags``. Each entry has ``value``, + ``name``, ``owner``, ``mine`` (``true`` when the caller owns the tag) and ``shared`` (``true`` + for a shared tag). ``tags`` is absent when there is none. The ``tag`` index field itself is never + returned. +- ``facet.field=tag`` returns in ``facet_field`` a facet of the tags that the caller can see. Besides + ``value`` and ``count``, each bucket has ``label`` (the tag name), ``owner``, ``mine`` and + ``shared``. +- ``fields.tag=`` narrows the results to the documents with a tag. Pass the ``value`` of a + hit's ``tags`` or of a facet bucket as is. + +A condition on tags (``fields.tag``, ``tag:``, ``ex_q``, ``facet.query``) matches only an exact +value of a tag that the caller can see. The value of a tag the caller cannot see, and wildcard, +prefix, fuzzy and range conditions, match nothing. A caller without a login gets no tags and no tag +facet, and a tag condition matches nothing. -A tag is a label of the kind "Tag" (see :doc:`../admin/labeltype-guide`): the label name is the tag -name, the value is the SHA-256 of the name in hex, the included paths are the tagged URLs, and the -permissions decide who can see the tag. A tag is visible only when its label is visible to the -caller. +One user sees at most ``user.tag.visible.max.size`` (default: ``1000``) tags, the user's own tags +first. Tags beyond that do not appear in ``tags`` of the hits or in the facet, but can still be +filtered on. -The search API (``/api/v2/search``) returns the tags of each hit that the caller can see as -``tags``. ``fields.tag=`` narrows the results to the documents with a tag, and -``facet.field=tag`` returns a tag facet. The ``tag`` index field itself is not returned. +When Documents Reflect Changes +============================== -Getting Tags +Creating, changing and deleting tags, and putting them on and taking them off documents, show in the +tag endpoints at once. The ``tag`` field of the indexed documents, however, is updated through an +in-memory queue that the "Log Aggregator" job (``log_aggregator``) applies in bulk every minute. The +search hits, the facet and the filters therefore reflect a change after up to about a minute. After +a rename, the documents keep the old value until the queue is next processed, and the tag does not +show on them in the meantime. + +For the queue and the jobs, see :doc:`../admin/tagtype-guide`. + +Listing Tags ============ Request ------- +================== ==================================================== +HTTP Method GET +Endpoint ``/api/v2/tags`` +================== ==================================================== + +Returns the tags that the caller owns, by sort order and name. Shared tags of other users are not +included. + +Response +-------- + +On success (200), the following fields are returned directly under ``response`` of the common envelope. + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "value": "dG8tcmV2aWV3:YWxpY2U", + "name": "to-review", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Response Fields + + * - ``tags`` + - The caller's tags. Each has ``id``, ``value``, ``name``, ``shared`` (``true`` for a shared + tag), ``sort_order`` and ``path_count`` (the number of URLs the tag is on). + +Table: Response Fields + +Creating a Tag +============== + +Request +------- + +================== ==================================================== +HTTP Method POST +Endpoint ``/api/v2/tags`` +================== ==================================================== + +Creates a tag of the caller. As a state-changing request, it requires the ``X-Fess-CSRF-Token`` +header (see :doc:`api-overview`). + +- A user can have at most ``user.tag.max.tags`` (default: ``1000``) tags. Beyond that, the + endpoint answers ``invalid_request`` (400). +- When the caller already has a tag of the name, the endpoint answers ``conflict`` (409). Another + user having a tag of the same name does not matter. + +Send ``Content-Type: application/json``; the body can be at most 1 KiB (1024 bytes). + +:: + + { + "name": "to-review", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Request Body + + * - ``name`` + - Tag name (str, required). + * - ``shared`` + - ``true`` lets every logged-in user see the tag (bool, default: ``false``). + +Table: Request Body + +Response +-------- + +On success (200), ``tag`` directly under ``response`` holds the new tag, in the form of an entry of +``GET /api/v2/tags`` with a ``path_count`` of ``0``. + +Changing a Tag +============== + +Request +------- + +================== ==================================================== +HTTP Method PUT +Endpoint ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Renames a tag of the caller or changes whether it is shared. The ``X-Fess-CSRF-Token`` header is +required. + +- The body has ``name``, ``shared`` or both. +- A new ``name`` renames the tag, which gives it a new ``id`` and ``value``. The documents with the + old value get the new one when the queue is next processed. Renaming to a name the caller already + uses answers ``conflict`` (409) and leaves the tag unchanged. +- ``shared`` only changes who sees the tag; no document is updated. Setting ``shared`` to ``false`` + keeps the roles and groups an administrator added to the permissions. +- A shared tag of another user answers ``forbidden`` (403), and a tag the caller cannot see + ``not_found`` (404). +- A write that keeps losing a race with another update also answers ``conflict`` (409). + +:: + + { + "name": "reviewed", + "shared": true + } + +On success (200), ``response`` holds ``tag`` (the tag as changed) and ``renamed`` (``true`` when the +tag was renamed, in which case ``tag.id`` and ``tag.value`` are new). + +Deleting a Tag +============== + +Request +------- + +================== ==================================================== +HTTP Method DELETE +Endpoint ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Deletes a tag of the caller. The documents lose its value when the queue is next processed. The +``X-Fess-CSRF-Token`` header is required. A shared tag of another user answers ``forbidden`` (403), +and a tag the caller cannot see ``not_found`` (404). + +On success (200), ``response`` holds ``id`` (the deleted tag ID) and ``deleted`` (always ``true``). + +Getting the Tags of a Document +============================== + +Request +------- + ================== ==================================================== HTTP Method GET Endpoint ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Returns the tags of the document that the caller can see. When the caller cannot search the -document, the endpoint responds with ``not_found`` (404). +Returns the tags on the document's URL that the caller can see, and the caller's own tags that are +not on it. The document is looked up with the caller's roles, so a document the caller cannot +search answers ``not_found`` (404). Response -------- @@ -46,10 +248,25 @@ On success (200), the following fields are returned directly under ``response`` "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "to-review", "mine": true } - ] + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "value": "dG8tcmV2aWV3:YWxpY2U", + "name": "to-review", + "owner": "alice", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -58,21 +275,23 @@ On success (200), the following fields are returned directly under ``response`` * - ``doc_id`` - Document ID (str). + * - ``tags`` + - The tags on the document's URL that the caller can see. Each has ``id``, ``value``, + ``name``, ``owner``, ``mine`` (``true`` when the caller owns the tag) and ``shared`` + (``true`` for a shared tag). * - ``addable`` - - ``true`` when the caller is logged in and can add tags (bool). + - The caller's tags that are not on the document's URL, in the same form as ``tags``. * - ``added`` - - POST only. ``false`` when the caller had already tagged the document (bool). + - POST only. ``false`` when the tag was already on the document (bool). + * - ``tag`` + - POST only. The tag put on the document, in the same form as ``tags``. * - ``removed`` - - DELETE only (bool). - * - ``tags`` - - The tags that the caller can see. Each has ``value`` (the label value, used with - ``fields.tag``), ``name`` (the tag name) and ``mine`` (``true`` when the caller is in the - permissions of the tag). + - DELETE only. ``false`` when the tag was not on the document (bool). Table: Response Fields -Adding a Tag -============ +Putting a Tag on a Document +=========================== Request ------- @@ -82,17 +301,10 @@ HTTP Method POST Endpoint ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Tags the document's URL for the logged-in user; an access token does not stand in for a login. As a -state-changing request, it requires the ``X-Fess-CSRF-Token`` header. +Adds the document's URL to a tag of the caller. The ``X-Fess-CSRF-Token`` header is required. -- When a tag of the name exists, the URL is added to its included paths and the user to its - permissions. Otherwise, a tag that only the user can see is created. Tags with the same name - therefore merge into one, and users who added a tag of the same name can see where each other's - tags are. -- Tagging the same document again answers ``added: false``. -- A document can have at most ``user.tag.max.document.tags`` (default: ``100``) tags. - -Send ``Content-Type: application/json`` with the tag name in ``name``. +The body (``Content-Type: application/json``, at most 1 KiB) gives either ``id``, an existing tag, +or ``name``, a tag name. When both are given, ``id`` wins. :: @@ -100,50 +312,99 @@ Send ``Content-Type: application/json`` with the tag name in ``name``. "name": "to-review" } -The name is NFKC-normalized, runs of whitespace are collapsed and it is trimmed. It must be 1 to -``user.tag.name.max.length`` (default: ``50``) characters, and names with a control or format -character (such as a zero-width character or a bidi override) are refused. +- With ``name``, a private tag of the name is created and put on the document when the caller has + none. The new tag counts against ``user.tag.max.tags``. +- A tag can be on at most ``user.tag.max.paths`` (default: ``10000``) URLs. Beyond that, the + endpoint answers ``invalid_request`` (400). +- An ``id`` of another user's tag answers ``forbidden`` (403) when the caller can see the tag and + ``not_found`` (404) otherwise. +- On success, the response has the fields of Getting the Tags of a Document plus ``added`` and + ``tag``. The tag endpoints show the tag at once; the search results of the documents with the URL + reflect it when the queue is next processed (about a minute later). -Removing a Tag -============== +Taking a Tag off a Document +=========================== Request ------- ================== ==================================================== HTTP Method DELETE -Endpoint ``/api/v2/documents/{docId}/tags?value=`` +Endpoint ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -Removes the logged-in user from the permissions of the tag given by ``value``. When no permission of -a user, a group or a role is left, the tag is deleted and removed from the documents. When the user -is not in the permissions of the tag, the endpoint responds with ``forbidden`` (403). The -``X-Fess-CSRF-Token`` header is required. +Removes the document's URL from the caller's tag given by ``tagId``. The ``X-Fess-CSRF-Token`` +header is required. Another user's tag answers ``forbidden`` (403) when the caller can see it and +``not_found`` (404) otherwise. On success, the response has the fields of Getting the Tags of a +Document plus ``removed``. Error Response ============== +For details on the error model, see :doc:`api-overview`. The tag endpoints return the following +HTTP statuses. + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: Error Response * - Status Code - Description * - 400 Bad Request - - When the request is invalid (including when tags are disabled, the tag name is invalid or a - tag limit is exceeded). + - When the request is invalid, including when tags are disabled, the tag name is invalid, a + required field is missing, or ``user.tag.max.tags`` or ``user.tag.max.paths`` would be + exceeded. * - 401 Unauthorized - - POST or DELETE without a login. + - Without a login (an access token does not stand in for one). * - 403 Forbidden - - A missing or expired CSRF token, or a DELETE of a tag the user did not add. + - A missing or expired CSRF token, or a change to another user's tag. The CSRF check comes + before the login check, so a state-changing request without a session gets 403, not 401. * - 404 Not Found - - When the document is not found or the caller cannot search it. + - When the tag does not exist or the caller cannot see it, or the document is not found or the + caller cannot search it. * - 405 Method Not Allowed - When the HTTP method is not allowed. + * - 409 Conflict + - When a tag of the name already exists, or a write lost a race with another update. * - 413 Payload Too Large - - When the request body exceeds the size limit. + - When the request body exceeds the size limit (1 KiB). * - 415 Unsupported Media Type - When the ``Content-Type`` is not supported. * - 500 Internal Server Error - When an internal server error occurs. Table: Error Response + +Settings +======== + +The following settings in ``fess_config.properties`` adjust tags. + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - Property + - Description + - Default + * - ``user.tag.enabled`` + - Whether logged-in users can use tags. + - ``false`` + * - ``user.tag.name.max.length`` + - Maximum length of a tag name, in code points. + - ``50`` + * - ``user.tag.max.tags`` + - Maximum number of tags one user can own. + - ``1000`` + * - ``user.tag.max.paths`` + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - ``user.tag.queue.max.size`` + - Maximum number of changes held in memory until they reach the documents. A change beyond it + is dropped with a WARN log. + - ``10000`` + * - ``user.tag.process.batch.size`` + - Number of URLs updated per bulk request when changes are applied to the documents. + - ``100`` + * - ``user.tag.visible.max.size`` + - Maximum number of tags visible to one user in a search. + - ``1000`` diff --git a/en/15.9/api/api-uiconfig.rst b/en/15.9/api/api-uiconfig.rst index 39592fe4..805d39a0 100644 --- a/en/15.9/api/api-uiconfig.rst +++ b/en/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ All fields are required. - Whether search result export (``GET /api/v2/documents/export``) is enabled (``api.search.export``). * - ``user_tag`` - boolean - - Whether tags (``/api/v2/documents/{docId}/tags``) are enabled (``user.tag.enabled``). + - Whether per-user tags are enabled (``user.tag.enabled``): the tag endpoints (``/api/v2/tags``, ``/api/v2/documents/{docId}/tags``) answer and search hits carry ``tags``. * - ``popular_word`` - boolean - Whether the popular word feature is enabled. diff --git a/en/15.9/config/properties.rst b/en/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/en/15.9/config/properties.rst +++ b/en/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/es/15.9/admin/index.rst b/es/15.9/admin/index.rst index a62d3bb1..7f0652c1 100644 --- a/es/15.9/admin/index.rst +++ b/es/15.9/admin/index.rst @@ -28,6 +28,7 @@ roles, los registros y las copias de seguridad. fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/es/15.9/admin/labeltype-guide.rst b/es/15.9/admin/labeltype-guide.rst index 9dcc23d4..f0cf62cb 100644 --- a/es/15.9/admin/labeltype-guide.rst +++ b/es/15.9/admin/labeltype-guide.rst @@ -85,49 +85,11 @@ Orden de clasificación Especifique el orden de clasificación de las etiquetas. -Tipo -:::: - -Indique "Etiqueta" o "Etiqueta de usuario". Una etiqueta normal es "Etiqueta". "Etiqueta de usuario" -es una etiqueta que los usuarios añaden desde la pantalla de búsqueda (consulte "Etiquetas de -usuario" más abajo). Una etiqueta existente sin tipo se trata como "Etiqueta". - - Eliminar configuración ---------------------- Haga clic en el nombre de la configuración en la página de lista y haga clic en el botón de eliminar para que aparezca una pantalla de confirmación. Al presionar el botón de eliminar, se eliminará la configuración. -Etiquetas de usuario --------------------- - -Con ``user.tag.enabled=true`` (predeterminado: ``false``) en ``fess_config.properties``, los -usuarios que han iniciado sesión pueden etiquetar los resultados de búsqueda. En el tema incluido -``bootstrap``, las etiquetas se muestran en los resultados, los usuarios pueden añadir etiquetas y -quitar las suyas, y una faceta "Etiquetas" acota los resultados. Para la API, consulte -:doc:`../api/api-tag`. - -Una etiqueta de usuario se guarda como una etiqueta del tipo "Etiqueta de usuario": el nombre es el -nombre de la etiqueta, el valor es el SHA-256 del nombre, las rutas incluidas son las URL etiquetadas -(una por línea, coincidencia exacta) y los permisos deciden quién puede verla. El usuario que añade -una etiqueta se agrega a sus permisos. - -- Una etiqueta solo es visible cuando los permisos de su etiqueta coinciden con quien llama. Los - administradores pueden editarla en esta página para compartirla con un rol o un grupo, o - eliminarla. -- Las etiquetas con el mismo nombre se combinan en una sola, por lo que los usuarios que añadieron una - etiqueta con el mismo nombre ven dónde están las etiquetas de los demás. -- Las etiquetas de usuario no se incluyen en la API de lista de etiquetas (``/api/v2/labels``) ni en - las opciones de etiqueta de la pantalla de búsqueda. -- Cuentan para el límite de etiquetas (``page.labeltype.max.fetch.size``, predeterminado: 1000). Al - alcanzarlo, no se pueden crear nuevas. -- Después de que un administrador cambie o elimine una etiqueta de usuario en esta página, los - documentos indexados conservan los valores anteriores hasta que se vuelven a rastrear o se ejecuta - el trabajo "Label Updater". -- Un documento puede tener hasta ``user.tag.max.document.tags`` (predeterminado: 100) etiquetas de - usuario, y un nombre puede tener hasta ``user.tag.name.max.length`` (predeterminado: 50) - caracteres. - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png diff --git a/es/15.9/admin/tagtype-guide.rst b/es/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..0443567e --- /dev/null +++ b/es/15.9/admin/tagtype-guide.rst @@ -0,0 +1,160 @@ +=================== +Etiqueta de usuario +=================== + +Descripción general +=================== + +Aquí se explica la pantalla que gestiona las etiquetas de los usuarios. + +Una etiqueta de usuario es una marca que un usuario que ha iniciado sesión asigna a documentos de los +resultados de búsqueda. Se gestionan por usuario: quien crea una etiqueta es su propietario, y dos +usuarios pueden usar el mismo nombre y tener aun así dos etiquetas distintas. Las etiquetas de usuario +no son :doc:`etiquetas `, que los administradores definen mediante patrones de URL; +los usuarios las crean ellos mismos y las asignan a documentos concretos. + +Las etiquetas de usuario están deshabilitadas de forma predeterminada. Para usarlas, configure +``user.tag.enabled=true`` en ``fess_config.properties``. Una vez habilitadas, el tema ``bootstrap`` +incluido permite a los usuarios que han iniciado sesión asignar etiquetas a los resultados de búsqueda +y quitarlas, y filtrar con una faceta de etiquetas. En "Mis etiquetas" pueden renombrar, compartir y +eliminar sus propias etiquetas. Las etiquetas compartidas de otros usuarios se muestran con el +prefijo "Compartida:". Para la API de usuario y la configuración, consulte :doc:`../api/api-tag`. + +En esta pantalla, los administradores pueden listar, crear, editar y eliminar las etiquetas de todos +los usuarios. + +Método de gestión +================= + +Método de visualización +----------------------- + +Para abrir la página de lista de etiquetas de usuario, haga clic en [Rastreador > Etiqueta de usuario] +en el menú izquierdo. Para verla se necesita el rol ``admin-tagtype`` o ``admin-tagtype-view``, y para +crear, editar y eliminar, ``admin-tagtype``. + +La lista muestra el nombre y el propietario de cada etiqueta, por orden de clasificación, nombre y +propietario. Puede buscar por nombre y por propietario; cada uno coincide con las etiquetas que +contienen el texto introducido. + +Para editar una etiqueta, haga clic en su nombre. + +Crear configuración +------------------- + +Para abrir la página de creación de etiquetas, haga clic en el botón de nueva creación. + +Parámetros de configuración +--------------------------- + +Nombre +:::::: + +Especifica el nombre de la etiqueta. El nombre se normaliza con NFKC, los espacios consecutivos se +reducen a uno y se recortan los extremos. El resultado debe tener entre 1 y +``user.tag.name.max.length`` (predeterminado: 50) caracteres y no puede contener caracteres de +control ni de formato. + +Propietario +::::::::::: + +Especifica el ID de usuario de inicio de sesión del usuario propietario de la etiqueta. El +propietario y el nombre juntos identifican una etiqueta, por lo que un propietario no puede tener dos +etiquetas con el mismo nombre, ni siquiera en hosts virtuales distintos. + +Si cambia el propietario, el permiso de usuario del propietario anterior en Permisos se sustituye por +el del nuevo propietario. + +Rutas +::::: + +Especifica las URL de los documentos a los que se asigna la etiqueta, una por línea. Una URL debe ser +igual al campo ``url`` de un documento indexado; no se usan expresiones regulares. Una etiqueta puede +tener como máximo ``user.tag.max.paths`` (predeterminado: 10000) URL. + +Permisos +:::::::: + +Especifica los usuarios, grupos y roles que pueden ver la etiqueta, igual que en las etiquetas: +{user}nombre de usuario para un usuario, {group}nombre de grupo para un grupo y {role}nombre de rol +para un rol. Si se deja vacío, solo el propietario puede ver la etiqueta. + +El propietario siempre ve sus propias etiquetas, sean cuales sean los permisos. Un usuario que no ha +iniciado sesión nunca ve una etiqueta, sean cuales sean los permisos. + +Host virtual +:::::::::::: + +Especifica el nombre de host del host virtual en el que se muestra la etiqueta. Una etiqueta creada +por un usuario recibe el host virtual por el que accedía el usuario. En una pantalla de búsqueda a la +que se accede mediante un host virtual, solo son visibles las etiquetas que tienen aquí ese nombre de +host virtual. Un acceso que no coincide con ningún host virtual ve las etiquetas sea cual sea el valor +de este campo. Para obtener más información, consulte +:doc:`Host virtual en la guía de configuración <../config/security-virtual-host>`. + +Orden de clasificación +:::::::::::::::::::::: + +Especifica el orden de visualización de la etiqueta. + +Eliminar configuración +---------------------- + +Haga clic en un nombre en la página de lista y luego en el botón de eliminar para que aparezca una +pantalla de confirmación. Al presionar el botón de eliminar, se elimina la etiqueta y su valor se +quita de los documentos. + +Compartir +========= + +Cuando un usuario comparte una etiqueta, los valores de ``role.search.guest.permissions`` +(predeterminado: ``{role}guest``) se añaden a sus permisos. La visibilidad de una etiqueta se decide +añadiendo estos valores a los roles del usuario que ha iniciado sesión, por lo que una etiqueta +compartida es visible para todos los usuarios que han iniciado sesión, que también pueden filtrar por +ella. Dejar de compartirla quita solo estos valores. + +En esta pantalla, un administrador también puede añadir grupos o roles a los permisos para mostrar +una etiqueta solo a algunos usuarios. Solo el propietario y los administradores pueden cambiar una +etiqueta; los demás usuarios solo pueden mostrar y filtrar por las etiquetas que ven. + +Cómo llegan los cambios a los documentos +======================================== + +Un documento guarda sus etiquetas de usuario en el campo ``tag`` del índice, como +``base64url(nombre):base64url(propietario)``. + +- Crear, editar y eliminar etiquetas, y que los usuarios las asignen a documentos o las quiten, se + guarda de inmediato en las etiquetas (el índice ``fess_config.tag_type``). Los documentos se + actualizan mediante una cola en memoria que el trabajo "Log Aggregator" (``log_aggregator``) aplica + en bloque cada minuto, por lo que los resultados de búsqueda reflejan un cambio al cabo de hasta un + minuto aproximadamente. +- Cambiar las rutas en esta pantalla actualiza los documentos de las URL añadidas y quitadas. Cambiar + el nombre o el propietario sustituye el valor anterior en los documentos por el nuevo. +- Cuando un rastreo o un almacén de datos indexa documentos, su campo ``tag`` se establece a partir + de las rutas de las etiquetas, por lo que las etiquetas se conservan al volver a rastrear. +- El trabajo "Tag Updater" (``tag_updater``) reconstruye el campo ``tag`` de todos los documentos a + partir de las etiquetas. No tiene programación; ejecútelo desde el programador cuando sea necesario. + +Notas para la operación +======================= + +- **Ejecute Log Aggregator en todos los nodos.** Cada JVM tiene su propia cola, que solo procesa el + Log Aggregator de ese nodo. Mantenga el destino del trabajo ``log_aggregator`` en el valor + predeterminado ``all``; si se limita a algunos nodos, los cambios recibidos por los demás nodos + nunca llegan a los documentos. +- **Ejecute Tag Updater en los siguientes casos.** La cola está en memoria, por lo que los cambios + aún no aplicados se pierden cuando |Fess| se reinicia. Mientras ``user.tag.enabled=false``, los + cambios de etiquetas no llegan a los documentos y volver a rastrear borra su campo ``tag``. Después + de restaurar desde una copia de seguridad, también hay que reconstruir las etiquetas de los + documentos. Y cuando la cola supera ``user.tag.queue.max.size`` (predeterminado: 10000), los + cambios que sobran se descartan con un registro WARN. En todos estos casos, ejecutar + ``tag_updater`` reconstruye las etiquetas de los documentos. +- **El propietario de una etiqueta es el ID de usuario de inicio de sesión.** Si un ID de usuario + cambia, las etiquetas se quedan con el ID anterior. Con SAML, el NameID debe ser persistente. Con + Entra ID el propietario es el UPN, y con LDAP es el nombre de usuario con las mayúsculas y + minúsculas escritas al iniciar sesión. Eliminar un usuario no elimina sus etiquetas; elimine en + esta pantalla las que ya no se necesiten. +- **También funciona con índices existentes.** Al iniciar, si el índice de documentos no tiene + asignación para el campo ``tag``, se añade como ``keyword``. Los campos existentes no se modifican. +- Las etiquetas de usuario se guardan en el índice ``fess_config.tag_type``. Se incluyen en + ``fess_config.bulk`` de una copia de seguridad, pero no en ``fess_basic_config.bulk``. diff --git a/es/15.9/api/admin/api-admin-overview.rst b/es/15.9/api/admin/api-admin-overview.rst index dd437445..2dee674f 100644 --- a/es/15.9/api/admin/api-admin-overview.rst +++ b/es/15.9/api/admin/api-admin-overview.rst @@ -451,6 +451,8 @@ Ajuste de Búsqueda - Descripción * - :doc:`api-admin-labeltype` - Tipos de etiqueta + * - :doc:`api-admin-tagtype` + - Etiquetas de usuario * - :doc:`api-admin-keymatch` - Coincidencia de claves * - :doc:`api-admin-boostdoc` diff --git a/es/15.9/api/admin/api-admin-tagtype.rst b/es/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..44e70316 --- /dev/null +++ b/es/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,399 @@ +=================== +API de TagType +=================== + +Descripción general +=================== + +La API de TagType es una API para gestionar las etiquetas de usuario de |Fess|, es decir, las +etiquetas propias de cada usuario que los usuarios que han iniciado sesión asignan a documentos +(consulte :doc:`../../admin/tagtype-guide`). Gestiona las etiquetas de todos los usuarios, tanto si +``user.tag.enabled`` es ``true`` como si no. + +Para conocer el método de autenticación y las especificaciones comunes de la Respuesta +(código ``status``, campo ``version``, formato de errores, códigos de estado HTTP, etc.), +consulte :doc:`api-admin-overview`. +Para acceder a esta API, es necesario especificar un token de acceso con el permiso de Admin API +(``admin-api``) en el encabezado ``Authorization: Bearer ``. + +Los nombres de los campos JSON de esta API están en snake_case (``sort_order``, ``virtual_host``, +``seq_no``, ``primary_term``, etc.). + +URL base +======== + +:: + + /api/admin/tagtype + +Lista de endpoints +================== + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - Método + - Ruta + - Descripción + * - GET + - /settings + - Obtener la lista de etiquetas de usuario + * - GET + - /setting/{id} + - Obtener una etiqueta de usuario + * - POST + - /setting + - Crear una etiqueta de usuario + * - PUT + - /setting + - Actualizar una etiqueta de usuario + * - DELETE + - /setting/{id} + - Eliminar una etiqueta de usuario + +Obtener la lista de etiquetas de usuario +======================================== + +Solicitud +--------- + +:: + + GET /api/admin/tagtype/settings + +Parámetros +~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Parámetro + - Tipo + - Obligatorio + - Descripción + * - ``size`` + - Integer + - No + - Número de elementos por página. El valor predeterminado es el de ``paging.page.size`` (``25`` de forma predeterminada). + * - ``page`` + - Integer + - No + - Número de página (empieza en 1). El valor predeterminado es ``1``. + * - ``name`` + - String + - No + - Filtrar por nombre (búsqueda con comodines: coincide con los nombres que contienen el texto). + * - ``owner`` + - String + - No + - Filtrar por propietario (búsqueda con comodines: coincide con los propietarios que contienen el texto). + +Las etiquetas se ordenan por orden de clasificación, nombre y propietario. + +Respuesta +--------- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + La lista no lee las rutas de las etiquetas, que pueden ser largas, por lo que sus elementos no + tienen ``paths``. PUT sustituye la etiqueta por completo: para editarla, obténgala antes con + ``GET /setting/{id}`` para conservar sus ``paths``. + +Obtener una etiqueta de usuario +=============================== + +Solicitud +--------- + +:: + + GET /api/admin/tagtype/setting/{id} + +Respuesta +--------- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` y ``primary_term`` identifican la versión leída de la etiqueta. ``paths`` y +``permissions`` contienen un valor por línea. + +Crear una etiqueta de usuario +============================= + +Solicitud +--------- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +Cuerpo de la solicitud +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +Descripción de campos +~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Campo + - Tipo + - Obligatorio + - Descripción + * - ``name`` + - String + - Sí + - Nombre de la etiqueta. Se normaliza con NFKC, los espacios consecutivos se reducen a uno y se + recortan los extremos; el resultado debe tener entre 1 y ``user.tag.name.max.length`` + (predeterminado: ``50``) caracteres sin caracteres de control ni de formato. + * - ``owner`` + - String + - Sí + - ID de usuario de inicio de sesión del propietario (máximo 1000 caracteres). + * - ``paths`` + - String + - No + - URL de los documentos a los que se asigna la etiqueta, separadas por un salto de línea + (``\n``). Cada una debe ser igual al campo ``url`` de un documento. Como máximo + ``user.tag.max.paths`` (predeterminado: ``10000``). + * - ``permissions`` + - String + - No + - Usuarios/grupos/roles que pueden ver la etiqueta (p. ej. ``{role}guest``), separados por un + salto de línea (``\n``). Si está vacío, solo el propietario la ve. ``{role}guest`` (el valor + de ``role.search.guest.permissions``) la comparte con todos los usuarios que han iniciado + sesión. + * - ``virtual_host`` + - String + - No + - Host virtual (máximo 1000 caracteres). + * - ``sort_order`` + - Integer + - No + - Orden de visualización (entero no negativo). Si se omite, ``0``. + +El ID de una etiqueta es el SHA-256 de su valor, formado a partir del nombre y el propietario, por +lo que lo decide el servidor. El propietario y el nombre identifican juntos una etiqueta: si el +propietario ya tiene una etiqueta con ese nombre, la creación falla con un error de validación +(``status: 1``, "A tag with the same name and owner already exists."). + +Respuesta +--------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +Si la creación tiene éxito, ``created`` es ``true``. + +Actualizar una etiqueta de usuario +================================== + +Solicitud +--------- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +Cuerpo de la solicitud +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +El cuerpo contiene todos los campos de la creación y, además, los siguientes. La etiqueta se +sustituye por completo, así que envíe también las ``paths`` que quiera conservar. + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Campo + - Tipo + - Obligatorio + - Descripción + * - ``id`` + - String + - Sí + - El ID de la etiqueta que se actualiza. + * - ``seq_no`` + - Integer + - Sí + - El ``seq_no`` de la etiqueta devuelto por ``GET /setting/{id}``. + * - ``primary_term`` + - Integer + - Sí + - El ``primary_term`` de la etiqueta devuelto por ``GET /setting/{id}``. + +- Si la etiqueta cambió después de leerla, es decir, ``seq_no`` y ``primary_term`` ya no + coinciden, la actualización falla con un error de validación (``status: 1``, "The tag was + changed by someone else. Reload it and try again."). Vuelva a obtener la etiqueta y repita la + operación. +- Cambiar ``name`` u ``owner`` da a la etiqueta un ID nuevo; el ``id`` de la respuesta es el nuevo. + Si el propietario ya tiene una etiqueta con el nuevo nombre, la actualización falla con "A tag + with the same name and owner already exists.". +- Al cambiar el propietario, el permiso de usuario del propietario anterior en ``permissions`` se + sustituye por el del nuevo propietario. + +Respuesta +--------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +En una actualización, ``created`` es ``false``. + +Eliminar una etiqueta de usuario +================================ + +Solicitud +--------- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +Respuesta +--------- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +Si la etiqueta cambia mientras se elimina, la eliminación falla con "The tag was changed by someone +else. Reload it and try again.". + +Cómo llegan los cambios a los documentos +======================================== + +Crear, actualizar y eliminar una etiqueta con esta API se guarda de inmediato en las etiquetas. +Mientras ``user.tag.enabled`` sea ``true``, el cambio para los documentos (rutas añadidas y +quitadas, un cambio de nombre o una eliminación) se pone en cola y lo aplica cada minuto el trabajo +"Log Aggregator" (``log_aggregator``). Mientras sea ``false`` no se pone nada en cola; ejecute el +trabajo "Tag Updater" (``tag_updater``) después de habilitar las etiquetas. Consulte +:doc:`../../admin/tagtype-guide`. + +Ejemplos de uso +=============== + +Compartir una etiqueta con todos los usuarios que han iniciado sesión +--------------------------------------------------------------------- + +.. code-block:: bash + + # Leer la etiqueta, con paths, seq_no y primary_term + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # Devolverla con {role}guest añadido a los permisos + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +Obtener las etiquetas de un usuario +----------------------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +Véase también +============= + +- :doc:`api-admin-overview` - Descripción general de Admin API +- :doc:`../api-tag` - API de etiquetas de usuario +- :doc:`../../admin/tagtype-guide` - Guía de gestión de etiquetas de usuario diff --git a/es/15.9/api/admin/index.rst b/es/15.9/api/admin/index.rst index 75130fe4..69c42729 100644 --- a/es/15.9/api/admin/index.rst +++ b/es/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Referencia de Admin API :caption: Ajuste de Búsqueda api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/es/15.9/api/api-tag.rst b/es/15.9/api/api-tag.rst index 7b24ab4b..27578cd3 100644 --- a/es/15.9/api/api-tag.rst +++ b/es/15.9/api/api-tag.rst @@ -2,9 +2,9 @@ API de etiquetas de usuario =========================== -Este documento describe la API de etiquetas de usuario v2 de |Fess|, que permite a los usuarios -etiquetar documentos. Para el sobre de respuesta común, el modelo de errores y CSRF, consulte -:doc:`api-overview`. +Este documento describe la API de etiquetas de usuario v2 de |Fess|, con la que los usuarios que han +iniciado sesión gestionan sus propias etiquetas y las asignan a documentos. Para el sobre de +respuesta común, el modelo de errores y CSRF, consulte :doc:`api-overview`. La URL base es ``http:///api/v2/`` (ejemplo en entorno local: ``http://localhost:8080/api/v2``). @@ -12,31 +12,243 @@ La URL base es ``http:///api/v2/`` (ejemplo en entorno local: ``htt Las etiquetas de usuario están deshabilitadas de forma predeterminada. Para usarlas, configure ``user.tag.enabled=true`` en ``fess_config.properties``. ``features.user_tag`` de - ``/api/v2/ui/config`` indica el estado. + ``/api/v2/ui/config`` indica el estado. Mientras estén deshabilitadas, los endpoints de + etiquetas responden ``invalid_request`` (400) a una solicitud que supera las comprobaciones de + CSRF y Origin y usa un método admitido. + +Funcionamiento de las etiquetas de usuario +========================================== + +- Las etiquetas de usuario se gestionan por usuario. Quien crea una etiqueta es su propietario, y el + propietario es el ID de usuario con el que inició sesión. Dos usuarios pueden usar el mismo nombre + y tener aun así dos etiquetas distintas. +- Solo los usuarios que han iniciado sesión pueden usar etiquetas. Cada endpoint actúa como el + usuario de la sesión iniciada; un token de acceso no sustituye al inicio de sesión. Quien llama sin + haber iniciado sesión recibe ``auth_required`` (401). +- Una etiqueta nueva es privada: solo su propietario la ve. Cuando el propietario la comparte, todos + los usuarios que han iniciado sesión pueden verla y filtrar por ella. Un usuario que no ha iniciado + sesión no ve ninguna etiqueta, ni siquiera las compartidas. +- Solo el propietario puede cambiar o eliminar una etiqueta, o asignarla a documentos y quitarla. Una + etiqueta compartida de otro usuario solo se puede mostrar y usar para filtrar. Los administradores + gestionan todas las etiquetas en la pantalla de administración (consulte + :doc:`../admin/tagtype-guide`). +- Una etiqueta se asigna a la URL de un documento, por lo que todos los documentos indexados con esa + URL la reciben. + +Cada etiqueta tiene dos identificadores. + +``value`` + El valor de la etiqueta, ``base64url(nombre):base64url(propietario)`` (UTF-8, sin relleno), que se + guarda en el campo ``tag`` del índice. Trátelo como un valor opaco para filtrar los resultados de + búsqueda. + +``id`` + El ID de la etiqueta, el SHA-256 de ``value`` en hexadecimal en minúsculas (64 caracteres). Se + indica en rutas como ``/api/v2/tags/{tagId}``. Al renombrar una etiqueta cambian tanto ``value`` + como ``id``. + +El nombre de una etiqueta se normaliza con NFKC, los espacios consecutivos se reducen a uno y se +recortan los extremos. El resultado debe tener entre 1 y ``user.tag.name.max.length`` +(predeterminado: ``50``) caracteres, y se rechazan los nombres con un carácter de control o de +formato (como un carácter de ancho cero o una anulación bidireccional). + +Etiquetas de usuario en la búsqueda +=================================== + +Mientras ``user.tag.enabled`` sea ``true``, la API de búsqueda (``/api/v2/search``) trata las +etiquetas de usuario de la siguiente manera. + +- Cada resultado incluye en ``tags`` las etiquetas que quien llama puede ver. Cada elemento tiene + ``value``, ``name``, ``owner``, ``mine`` (``true`` cuando quien llama es el propietario) y + ``shared`` (``true`` para una etiqueta compartida). Si no hay ninguna, ``tags`` no aparece. El + campo de índice ``tag`` nunca se devuelve. +- ``facet.field=tag`` devuelve en ``facet_field`` una faceta de las etiquetas que quien llama puede + ver. Además de ``value`` y ``count``, cada grupo tiene ``label`` (el nombre de la etiqueta), + ``owner``, ``mine`` y ``shared``. +- ``fields.tag=`` acota los resultados a los documentos con una etiqueta. Indique tal cual el + ``value`` de ``tags`` de un resultado o de un grupo de la faceta. + +Una condición sobre etiquetas (``fields.tag``, ``tag:``, ``ex_q``, ``facet.query``) solo coincide +con el valor exacto de una etiqueta que quien llama puede ver. El valor de una etiqueta que no puede +ver y las condiciones con comodines, de prefijo, difusas y de rango no coinciden con nada. Quien llama +sin haber iniciado sesión no recibe etiquetas ni faceta de etiquetas, y una condición sobre +etiquetas no coincide con nada. + +Un usuario ve como máximo ``user.tag.visible.max.size`` (predeterminado: ``1000``) etiquetas, primero +las suyas. Las que superan ese número no aparecen en ``tags`` de los resultados ni en la faceta, pero +se pueden seguir usando para filtrar. + +Cuándo se reflejan los cambios en los documentos +================================================ + +Crear, cambiar y eliminar etiquetas, y asignarlas a documentos o quitarlas, se refleja de inmediato +en los endpoints de etiquetas. En cambio, el campo ``tag`` de los documentos indexados se actualiza +mediante una cola en memoria que el trabajo "Log Aggregator" (``log_aggregator``) aplica en bloque +cada minuto. Por ello, los resultados, la faceta y los filtros reflejan un cambio al cabo de hasta un +minuto aproximadamente. Tras renombrar una etiqueta, los documentos conservan el valor anterior hasta +que se procesa la cola, y mientras tanto la etiqueta no se muestra en ellos. + +Para la cola y los trabajos, consulte :doc:`../admin/tagtype-guide`. + +Listar las etiquetas +==================== -Una etiqueta de usuario es una etiqueta del tipo "Etiqueta de usuario" (consulte -:doc:`../admin/labeltype-guide`): el nombre de la etiqueta es el nombre, el valor es el SHA-256 del -nombre en hexadecimal, las rutas incluidas son las URL etiquetadas y los permisos deciden quién puede -verla. Solo es visible cuando su etiqueta es visible para quien llama. +Solicitud +--------- + +================== ==================================================== +Método HTTP GET +Endpoint ``/api/v2/tags`` +================== ==================================================== + +Devuelve las etiquetas de quien llama, por orden de clasificación y nombre. No incluye las etiquetas +compartidas de otros usuarios. + +Respuesta +--------- + +Si tiene éxito (200), se devuelven los siguientes campos directamente bajo ``response`` del sobre común. + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "cb15c50dbcf7a9c8b3010895b5969bd81663741e550ae832146066dc7e0d3bf2", + "value": "cmV2aXNhcg:bHVjaWE", + "name": "revisar", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Campos de respuesta + + * - ``tags`` + - Las etiquetas de quien llama. Cada una tiene ``id``, ``value``, ``name``, ``shared`` + (``true`` para una etiqueta compartida), ``sort_order`` y ``path_count`` (el número de URL + con la etiqueta). + +Tabla: Campos de respuesta + +Crear una etiqueta +================== + +Solicitud +--------- + +================== ==================================================== +Método HTTP POST +Endpoint ``/api/v2/tags`` +================== ==================================================== + +Crea una etiqueta de quien llama. Como solicitud que cambia el estado, requiere la cabecera +``X-Fess-CSRF-Token`` (consulte :doc:`api-overview`). + +- Un usuario puede tener como máximo ``user.tag.max.tags`` (predeterminado: ``1000``) etiquetas. Si + se supera, el endpoint responde ``invalid_request`` (400). +- Si quien llama ya tiene una etiqueta con ese nombre, el endpoint responde ``conflict`` (409). Que + otro usuario tenga una etiqueta con el mismo nombre no importa. + +Envíe ``Content-Type: application/json``; el cuerpo puede ocupar como máximo 1 KiB (1024 bytes). + +:: + + { + "name": "revisar", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Cuerpo de la solicitud + + * - ``name`` + - Nombre de la etiqueta (str, obligatorio). + * - ``shared`` + - ``true`` permite que todos los usuarios que han iniciado sesión vean la etiqueta (bool, + predeterminado: ``false``). + +Tabla: Cuerpo de la solicitud + +Respuesta +--------- + +Si tiene éxito (200), ``tag`` directamente bajo ``response`` contiene la etiqueta nueva, con la forma +de un elemento de ``GET /api/v2/tags`` y ``path_count`` igual a ``0``. + +Cambiar una etiqueta +==================== + +Solicitud +--------- + +================== ==================================================== +Método HTTP PUT +Endpoint ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Renombra una etiqueta de quien llama o cambia si está compartida. Se requiere la cabecera +``X-Fess-CSRF-Token``. + +- El cuerpo contiene ``name``, ``shared`` o ambos. +- Un ``name`` nuevo renombra la etiqueta, lo que le da un ``id`` y un ``value`` nuevos. Los + documentos con el valor anterior reciben el nuevo cuando se procesa la cola. Renombrar a un nombre + que quien llama ya usa responde ``conflict`` (409) y deja la etiqueta sin cambios. +- ``shared`` solo cambia quién ve la etiqueta; no se actualiza ningún documento. Al poner ``shared`` + en ``false`` se conservan los roles y grupos que un administrador añadió a los permisos. +- Una etiqueta compartida de otro usuario responde ``forbidden`` (403), y una etiqueta que quien + llama no puede ver, ``not_found`` (404). +- Una escritura que pierde repetidamente frente a otra actualización también responde ``conflict`` + (409). + +:: + + { + "name": "revisada", + "shared": true + } -La API de búsqueda (``/api/v2/search``) devuelve en ``tags`` las etiquetas de usuario de cada -resultado que quien llama puede ver. ``fields.tag=`` acota los resultados a los documentos con -una etiqueta, y ``facet.field=tag`` devuelve una faceta de etiquetas. El campo de índice ``tag`` no se -devuelve. +Si tiene éxito (200), ``response`` contiene ``tag`` (la etiqueta modificada) y ``renamed`` (``true`` +si la etiqueta se renombró; en ese caso ``tag.id`` y ``tag.value`` son nuevos). -Obtener las etiquetas +Eliminar una etiqueta ===================== Solicitud --------- +================== ==================================================== +Método HTTP DELETE +Endpoint ``/api/v2/tags/{tagId}`` +================== ==================================================== + +Elimina una etiqueta de quien llama. Los documentos pierden su valor cuando se procesa la cola. Se +requiere la cabecera ``X-Fess-CSRF-Token``. Una etiqueta compartida de otro usuario responde +``forbidden`` (403), y una etiqueta que quien llama no puede ver, ``not_found`` (404). + +Si tiene éxito (200), ``response`` contiene ``id`` (el ID de la etiqueta eliminada) y ``deleted`` +(siempre ``true``). + +Obtener las etiquetas de un documento +===================================== + +Solicitud +--------- + ================== ==================================================== Método HTTP GET Endpoint ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Devuelve las etiquetas de usuario del documento que quien llama puede ver. Si quien llama no puede -buscar el documento, el endpoint responde con ``not_found`` (404). +Devuelve las etiquetas de la URL del documento que quien llama puede ver y las etiquetas propias de +quien llama que aún no están asignadas. El documento se busca con los roles de quien llama, por lo que +un documento que no puede buscar responde ``not_found`` (404). Respuesta --------- @@ -49,10 +261,25 @@ Si tiene éxito (200), se devuelven los siguientes campos directamente bajo ``re "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "revisar", "mine": true } - ] + { + "id": "cb15c50dbcf7a9c8b3010895b5969bd81663741e550ae832146066dc7e0d3bf2", + "value": "cmV2aXNhcg:bHVjaWE", + "name": "revisar", + "owner": "lucia", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -61,21 +288,24 @@ Si tiene éxito (200), se devuelven los siguientes campos directamente bajo ``re * - ``doc_id`` - ID del documento (str). + * - ``tags`` + - Las etiquetas de la URL del documento que quien llama puede ver. Cada una tiene ``id``, + ``value``, ``name``, ``owner``, ``mine`` (``true`` cuando quien llama es el propietario) y + ``shared`` (``true`` para una etiqueta compartida). * - ``addable`` - - ``true`` cuando quien llama ha iniciado sesión y puede añadir etiquetas (bool). + - Las etiquetas de quien llama que no están asignadas a la URL del documento, con la misma forma + que ``tags``. * - ``added`` - - Solo POST. ``false`` cuando quien llama ya había etiquetado el documento (bool). + - Solo POST. ``false`` cuando la etiqueta ya estaba asignada al documento (bool). + * - ``tag`` + - Solo POST. La etiqueta asignada al documento, con la misma forma que ``tags``. * - ``removed`` - - Solo DELETE (bool). - * - ``tags`` - - Las etiquetas de usuario que quien llama puede ver. Cada una tiene ``value`` (el valor de la - etiqueta, usado con ``fields.tag``), ``name`` (el nombre) y ``mine`` (``true`` cuando quien - llama está en los permisos de la etiqueta). + - Solo DELETE. ``false`` cuando la etiqueta no estaba asignada al documento (bool). Tabla: Campos de respuesta -Añadir una etiqueta -=================== +Asignar una etiqueta a un documento +=================================== Solicitud --------- @@ -85,18 +315,11 @@ Método HTTP POST Endpoint ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -Etiqueta la URL del documento para el usuario que ha iniciado sesión; un token de acceso no sustituye -al inicio de sesión. Como solicitud que cambia el estado, requiere la cabecera ``X-Fess-CSRF-Token``. - -- Si ya existe una etiqueta con ese nombre, la URL se añade a sus rutas incluidas y el usuario a sus - permisos. Si no, se crea una etiqueta que solo ese usuario puede ver. Por eso las etiquetas con el - mismo nombre se combinan en una, y los usuarios que añadieron una etiqueta con el mismo nombre ven - dónde están las etiquetas de los demás. -- Volver a etiquetar el mismo documento responde ``added: false``. -- Un documento puede tener como máximo ``user.tag.max.document.tags`` (predeterminado: ``100``) - etiquetas de usuario. +Añade la URL del documento a una etiqueta de quien llama. Se requiere la cabecera +``X-Fess-CSRF-Token``. -Envíe ``Content-Type: application/json`` con el nombre en ``name``. +El cuerpo (``Content-Type: application/json``, como máximo 1 KiB) indica ``id``, una etiqueta +existente, o ``name``, un nombre de etiqueta. Si se indican ambos, prevalece ``id``. :: @@ -104,51 +327,102 @@ Envíe ``Content-Type: application/json`` con el nombre en ``name``. "name": "revisar" } -El nombre se normaliza con NFKC, los espacios consecutivos se reducen a uno y se recorta. Debe tener -entre 1 y ``user.tag.name.max.length`` (predeterminado: ``50``) caracteres, y se rechazan los nombres -con un carácter de control o de formato (como un carácter de ancho cero o una anulación -bidireccional). +- Con ``name``, si quien llama no tiene ninguna etiqueta con ese nombre, se crea una etiqueta privada + y se asigna. La etiqueta nueva cuenta para ``user.tag.max.tags``. +- Una etiqueta puede estar asignada como máximo a ``user.tag.max.paths`` (predeterminado: + ``10000``) URL. Si se supera, el endpoint responde ``invalid_request`` (400). +- El ``id`` de una etiqueta de otro usuario responde ``forbidden`` (403) si quien llama puede verla y + ``not_found`` (404) en caso contrario. +- Si tiene éxito, la respuesta contiene los campos de "Obtener las etiquetas de un documento" más + ``added`` y ``tag``. Los endpoints de etiquetas muestran la etiqueta de inmediato; los resultados de + búsqueda de los documentos con esa URL la reflejan cuando se procesa la cola (aproximadamente un + minuto después). -Quitar una etiqueta -=================== +Quitar una etiqueta de un documento +=================================== Solicitud --------- ================== ==================================================== Método HTTP DELETE -Endpoint ``/api/v2/documents/{docId}/tags?value=`` +Endpoint ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -Quita al usuario que ha iniciado sesión de los permisos de la etiqueta indicada en ``value``. Cuando no -queda ningún permiso de usuario, grupo o rol, la etiqueta se elimina y se quita de los documentos. Si -el usuario no está en los permisos de la etiqueta, el endpoint responde con ``forbidden`` (403). Se -requiere la cabecera ``X-Fess-CSRF-Token``. +Quita la URL del documento de la etiqueta de quien llama indicada por ``tagId``. Se requiere la +cabecera ``X-Fess-CSRF-Token``. Una etiqueta de otro usuario responde ``forbidden`` (403) si quien +llama puede verla y ``not_found`` (404) en caso contrario. Si tiene éxito, la respuesta contiene los +campos de "Obtener las etiquetas de un documento" más ``removed``. Respuesta de error ================== +Para obtener detalles sobre el modelo de errores, consulte :doc:`api-overview`. Los endpoints de +etiquetas devuelven los siguientes estados HTTP. + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: Respuesta de error * - Código de estado - Descripción * - 400 Bad Request - - Cuando la solicitud no es válida (también cuando las etiquetas de usuario están deshabilitadas, - el nombre no es válido o se supera un límite). + - Cuando la solicitud no es válida, también cuando las etiquetas de usuario están + deshabilitadas, el nombre no es válido, falta un campo obligatorio o se superaría + ``user.tag.max.tags`` o ``user.tag.max.paths``. * - 401 Unauthorized - - POST o DELETE sin iniciar sesión. + - Sin iniciar sesión (un token de acceso no lo sustituye). * - 403 Forbidden - - Un token CSRF ausente o caducado, o un DELETE de una etiqueta que el usuario no añadió. + - Un token CSRF ausente o caducado, o un cambio en la etiqueta de otro usuario. La comprobación + de CSRF se hace antes que la del inicio de sesión, por lo que una solicitud que cambia el + estado sin sesión recibe 403, no 401. * - 404 Not Found - - Cuando el documento no se encuentra o quien llama no puede buscarlo. + - Cuando la etiqueta no existe o quien llama no puede verla, o el documento no se encuentra o + quien llama no puede buscarlo. * - 405 Method Not Allowed - Cuando el método HTTP no está permitido. + * - 409 Conflict + - Cuando ya existe una etiqueta con ese nombre, o una escritura perdió frente a otra + actualización. * - 413 Payload Too Large - - Cuando el cuerpo de la solicitud supera el límite de tamaño. + - Cuando el cuerpo de la solicitud supera el límite de tamaño (1 KiB). * - 415 Unsupported Media Type - Cuando el ``Content-Type`` no es compatible. * - 500 Internal Server Error - Cuando se produce un error interno del servidor. Tabla: Respuesta de error + +Configuración +============= + +Los siguientes ajustes de ``fess_config.properties`` regulan las etiquetas de usuario. + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - Propiedad + - Descripción + - Predeterminado + * - ``user.tag.enabled`` + - Si los usuarios que han iniciado sesión pueden usar etiquetas. + - ``false`` + * - ``user.tag.name.max.length`` + - Longitud máxima del nombre de una etiqueta, en puntos de código. + - ``50`` + * - ``user.tag.max.tags`` + - Número máximo de etiquetas que puede tener un usuario. + - ``1000`` + * - ``user.tag.max.paths`` + - Número máximo de URL a las que se puede asignar una etiqueta. + - ``10000`` + * - ``user.tag.queue.max.size`` + - Número máximo de cambios que se mantienen en memoria hasta que llegan a los documentos. Un + cambio que lo supere se descarta con un registro WARN. + - ``10000`` + * - ``user.tag.process.batch.size`` + - Número de URL actualizadas por solicitud en bloque al aplicar los cambios a los documentos. + - ``100`` + * - ``user.tag.visible.max.size`` + - Número máximo de etiquetas visibles para un usuario en una búsqueda. + - ``1000`` diff --git a/es/15.9/api/api-uiconfig.rst b/es/15.9/api/api-uiconfig.rst index 450009f3..1cb39b97 100644 --- a/es/15.9/api/api-uiconfig.rst +++ b/es/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ Todos los campos son obligatorios. - Si la exportación de resultados de búsqueda (``GET /api/v2/documents/export``) está habilitada (``api.search.export``). * - ``user_tag`` - boolean - - Si las etiquetas de usuario (``/api/v2/documents/{docId}/tags``) están habilitadas (``user.tag.enabled``). + - Si las etiquetas de usuario están habilitadas (``user.tag.enabled``): los endpoints de etiquetas (``/api/v2/tags``, ``/api/v2/documents/{docId}/tags``) responden y los resultados de búsqueda incluyen ``tags``. * - ``popular_word`` - boolean - Si la función de palabras populares está habilitada. diff --git a/es/15.9/config/properties.po b/es/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/es/15.9/config/properties.po +++ b/es/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/es/15.9/config/properties.rst b/es/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/es/15.9/config/properties.rst +++ b/es/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/fr/15.9/admin/index.rst b/fr/15.9/admin/index.rst index 88da8cf0..ab0a6e7b 100644 --- a/fr/15.9/admin/index.rst +++ b/fr/15.9/admin/index.rst @@ -28,6 +28,7 @@ et rôles, journaux et sauvegardes. fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/fr/15.9/admin/labeltype-guide.rst b/fr/15.9/admin/labeltype-guide.rst index b9d2aae5..b56d48d4 100644 --- a/fr/15.9/admin/labeltype-guide.rst +++ b/fr/15.9/admin/labeltype-guide.rst @@ -85,47 +85,11 @@ Ordre de tri Spécifie l'ordre d'affichage des étiquettes. -Type -:::: - -Indiquez « Étiquette » ou « Tag ». Une étiquette ordinaire est une « Étiquette ». Un « Tag » est un tag -que les utilisateurs ajoutent depuis l'écran de recherche (voir « Tags » ci-dessous). Une étiquette -existante sans type est traitée comme une « Étiquette ». - - Suppression de configuration ---------------------------- Cliquez sur le nom de la configuration dans la page de liste, puis cliquez sur le bouton Supprimer pour afficher l'écran de confirmation. Appuyer sur le bouton Supprimer supprimera la configuration. -Tags ----- - -Avec ``user.tag.enabled=true`` (par défaut : ``false``) dans ``fess_config.properties``, les -utilisateurs connectés peuvent taguer les résultats de recherche. Dans le thème fourni -``bootstrap``, les tags s'affichent sur les résultats, les utilisateurs peuvent ajouter des tags et -retirer les leurs, et une facette « Tags » restreint les résultats. Pour l'API, voir -:doc:`../api/api-tag`. - -Un tag est enregistré comme une étiquette du type « Tag » : le nom est le nom du tag, la valeur est le -SHA-256 du nom, les chemins inclus sont les URL taguées (une par ligne, correspondance exacte) et les -permissions décident qui peut voir le tag. L'utilisateur qui ajoute un tag est ajouté à ses -permissions. - -- Un tag n'est visible que si les permissions de son étiquette correspondent à l'appelant. Les - administrateurs peuvent modifier un tag sur cette page pour le partager avec un rôle ou un groupe, - ou le supprimer. -- Les tags de même nom sont fusionnés en une seule étiquette ; les utilisateurs qui ont ajouté un tag - de même nom voient donc où se trouvent les tags des autres. -- Les tags ne figurent ni dans l'API de liste des étiquettes (``/api/v2/labels``) ni dans les choix - d'étiquettes de l'écran de recherche. -- Les tags comptent dans la limite des étiquettes (``page.labeltype.max.fetch.size``, par défaut : - 1000). Une fois la limite atteinte, aucun nouveau tag ne peut être créé. -- Après qu'un administrateur a modifié ou supprimé un tag sur cette page, les documents indexés - conservent les anciennes valeurs jusqu'à un nouveau crawl ou l'exécution du job « Label Updater ». -- Un document peut avoir jusqu'à ``user.tag.max.document.tags`` (par défaut : 100) tags, et un nom - de tag peut compter jusqu'à ``user.tag.name.max.length`` (par défaut : 50) caractères. - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png diff --git a/fr/15.9/admin/tagtype-guide.rst b/fr/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..564cde9a --- /dev/null +++ b/fr/15.9/admin/tagtype-guide.rst @@ -0,0 +1,158 @@ +=== +Tag +=== + +Présentation +============ + +Cette section explique l'écran qui gère les tags des utilisateurs. + +Un tag est une marque qu'un utilisateur connecté pose sur des documents des résultats de recherche. +Les tags sont gérés par utilisateur : l'utilisateur qui crée un tag en est le propriétaire, et deux +utilisateurs peuvent employer le même nom et avoir malgré tout deux tags distincts. Les tags ne sont +pas des :doc:`étiquettes `, que les administrateurs définissent par des motifs +d'URL ; les utilisateurs créent eux-mêmes leurs tags et les posent sur des documents précis. + +Les tags sont désactivés par défaut. Pour les utiliser, définissez ``user.tag.enabled=true`` dans +``fess_config.properties``. Une fois activés, le thème ``bootstrap`` fourni permet aux utilisateurs +connectés de poser des tags sur les résultats de recherche et de les retirer, et de filtrer avec une +facette de tags. « Mes tags » leur permet de renommer, partager et supprimer leurs propres tags. Les +tags partagés des autres utilisateurs s'affichent avec le préfixe « Partagé : ». Pour l'API +utilisateur et les paramètres, voir :doc:`../api/api-tag`. + +Dans cet écran, les administrateurs listent, créent, modifient et suppriment les tags de tous les +utilisateurs. + +Gestion +======= + +Affichage +--------- + +Pour ouvrir la page de liste des tags, cliquez sur [Robot d'exploration > Tag] dans le menu de gauche. +L'affichage requiert le rôle ``admin-tagtype`` ou ``admin-tagtype-view`` ; la création, la +modification et la suppression requièrent ``admin-tagtype``. + +La liste affiche le nom et le propriétaire de chaque tag, par ordre de tri, nom et propriétaire. Vous +pouvez rechercher par nom et par propriétaire ; chacun correspond aux tags qui contiennent le texte +saisi. + +Cliquez sur un nom pour modifier le tag. + +Création de configuration +------------------------- + +Cliquez sur le bouton Nouvelle création pour ouvrir la page de création d'un tag. + +Paramètres de configuration +--------------------------- + +Nom +::: + +Spécifie le nom du tag. Le nom est normalisé en NFKC, les suites d'espaces sont réduites à une seule +et les extrémités sont rognées. Le résultat doit compter de 1 à ``user.tag.name.max.length`` (par +défaut : 50) caractères et ne peut contenir ni caractère de contrôle ni caractère de format. + +Propriétaire +:::::::::::: + +Spécifie l'identifiant de connexion de l'utilisateur à qui appartient le tag. Le propriétaire et le +nom identifient ensemble un tag : un propriétaire ne peut donc pas avoir deux tags de même nom, même +sur des hôtes virtuels différents. + +Lorsque vous changez le propriétaire, la permission utilisateur de l'ancien propriétaire dans +Autorisations est remplacée par celle du nouveau propriétaire. + +Chemins +::::::: + +Spécifie les URL des documents sur lesquels poser le tag, une par ligne. Une URL doit être égale au +champ ``url`` d'un document indexé ; les expressions régulières ne sont pas utilisées. Un tag peut +avoir au plus ``user.tag.max.paths`` (par défaut : 10000) URL. + +Autorisations +::::::::::::: + +Spécifie les utilisateurs, groupes et rôles qui peuvent voir le tag, comme pour les étiquettes : +{user}nom d'utilisateur pour un utilisateur, {group}nom de groupe pour un groupe et {role}nom de rôle +pour un rôle. Laissé vide, seul le propriétaire peut voir le tag. + +Le propriétaire voit toujours ses propres tags, quelles que soient les autorisations. Un utilisateur +non connecté ne voit jamais de tag, quelles que soient les autorisations. + +Hôte virtuel +:::::::::::: + +Spécifie le nom d'hôte de l'hôte virtuel sur lequel le tag est affiché. Un tag créé par un +utilisateur reçoit l'hôte virtuel par lequel l'utilisateur accédait. Sur un écran de recherche +accédé par un hôte virtuel, seuls les tags portant ici ce nom d'hôte virtuel sont visibles. Un accès +qui ne correspond à aucun hôte virtuel voit les tags quelle que soit la valeur de ce champ. Pour plus +de détails, consultez :doc:`Hôte virtuel dans le guide de configuration <../config/security-virtual-host>`. + +Ordre de tri +:::::::::::: + +Spécifie l'ordre d'affichage du tag. + +Suppression de configuration +---------------------------- + +Cliquez sur un nom dans la page de liste, puis sur le bouton Supprimer pour afficher l'écran de +confirmation. Appuyer sur le bouton Supprimer supprime le tag, et sa valeur est retirée des documents. + +Partage +======= + +Quand un utilisateur partage un tag, les valeurs de ``role.search.guest.permissions`` (par défaut : +``{role}guest``) sont ajoutées à ses autorisations. La visibilité d'un tag est décidée en ajoutant ces +valeurs aux rôles de l'utilisateur connecté : un tag partagé est donc visible par tout utilisateur +connecté, qui peut aussi filtrer avec. Annuler le partage retire uniquement ces valeurs. + +Dans cet écran, un administrateur peut aussi ajouter des groupes ou des rôles aux autorisations pour +ne montrer un tag qu'à certains utilisateurs. Seuls le propriétaire et les administrateurs peuvent +modifier un tag ; les autres utilisateurs peuvent seulement afficher les tags qu'ils voient et filtrer +avec. + +Comment les modifications atteignent les documents +================================================== + +Un document conserve ses tags dans le champ ``tag`` de l'index, sous la forme +``base64url(nom):base64url(propriétaire)``. + +- La création, la modification et la suppression des tags, ainsi que leur pose et leur retrait par + les utilisateurs, sont enregistrées immédiatement dans les tags (l'index ``fess_config.tag_type``). + Les documents sont mis à jour via une file d'attente en mémoire que la tâche « Log Aggregator » + (``log_aggregator``) applique en bloc chaque minute ; les résultats de recherche reflètent donc une + modification au bout d'une minute environ au plus. +- Modifier les chemins dans cet écran met à jour les documents des URL ajoutées et retirées. Modifier + le nom ou le propriétaire remplace l'ancienne valeur des documents par la nouvelle. +- Lorsque des documents sont indexés par un crawl ou un magasin de données, leur champ ``tag`` est + défini à partir des chemins des tags ; les tags survivent donc à un nouveau crawl. +- La tâche « Tag Updater » (``tag_updater``) reconstruit le champ ``tag`` de tous les documents à + partir des tags. Elle n'a pas de planification ; exécutez-la depuis le planificateur au besoin. + +Remarques pour l'exploitation +============================= + +- **Exécutez Log Aggregator sur chaque nœud.** Chaque JVM a sa propre file d'attente, que seul le + Log Aggregator de ce nœud traite. Laissez la cible de la tâche ``log_aggregator`` à la valeur par + défaut ``all`` ; si elle est limitée à certains nœuds, les modifications reçues par les autres + nœuds n'atteignent jamais les documents. +- **Exécutez Tag Updater dans les cas suivants.** La file d'attente est en mémoire : les + modifications pas encore appliquées sont perdues au redémarrage de |Fess|. Tant que + ``user.tag.enabled=false``, les modifications de tags n'atteignent pas les documents et un nouveau + crawl efface leur champ ``tag``. Après une restauration depuis une sauvegarde, les tags des + documents doivent aussi être reconstruits. Enfin, lorsque la file dépasse + ``user.tag.queue.max.size`` (par défaut : 10000), les modifications en trop sont abandonnées avec + un journal WARN. Dans chacun de ces cas, exécuter ``tag_updater`` reconstruit les tags des + documents. +- **Le propriétaire d'un tag est l'identifiant de connexion.** Si un identifiant change, les tags + restent attachés à l'ancien. Avec SAML, le NameID doit être persistant. Avec Entra ID, le + propriétaire est l'UPN, et avec LDAP, le nom d'utilisateur avec la casse saisie à la connexion. + Supprimer un utilisateur laisse ses tags ; supprimez dans cet écran ceux qui ne servent plus. +- **Les index existants fonctionnent aussi.** Au démarrage, si l'index des documents n'a pas de + mapping pour le champ ``tag``, il est ajouté en ``keyword``. Les champs existants ne sont pas + modifiés. +- Les tags sont stockés dans l'index ``fess_config.tag_type``. Ils sont inclus dans + ``fess_config.bulk`` d'une sauvegarde, mais pas dans ``fess_basic_config.bulk``. diff --git a/fr/15.9/api/admin/api-admin-overview.rst b/fr/15.9/api/admin/api-admin-overview.rst index 099ad829..789f56e4 100644 --- a/fr/15.9/api/admin/api-admin-overview.rst +++ b/fr/15.9/api/admin/api-admin-overview.rst @@ -454,6 +454,8 @@ Optimisation de la recherche - Description * - :doc:`api-admin-labeltype` - Types de labels + * - :doc:`api-admin-tagtype` + - Tags * - :doc:`api-admin-keymatch` - Key Match * - :doc:`api-admin-boostdoc` diff --git a/fr/15.9/api/admin/api-admin-tagtype.rst b/fr/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..a6f98259 --- /dev/null +++ b/fr/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,398 @@ +=========== +TagType API +=========== + +Vue d'ensemble +============== + +L'API TagType permet de gérer les tags des utilisateurs de |Fess|, c'est-à-dire les tags propres à +chaque utilisateur que les utilisateurs connectés posent sur des documents (voir +:doc:`../../admin/tagtype-guide`). Elle gère les tags de tous les utilisateurs, que +``user.tag.enabled`` vaille ``true`` ou non. + +Pour les méthodes d'authentification et les spécifications communes des réponses +(code ``status``, champ ``version``, format des erreurs, codes de statut HTTP, etc.), +consultez :doc:`api-admin-overview`. +Pour accéder à cette API, un jeton d'accès disposant de la permission d'API d'administration +(``admin-api``) doit être indiqué dans l'en-tête ``Authorization: Bearer ``. + +Les noms des champs JSON de cette API sont en snake_case (``sort_order``, ``virtual_host``, +``seq_no``, ``primary_term``, etc.). + +URL de base +=========== + +:: + + /api/admin/tagtype + +Liste des endpoints +=================== + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - Méthode + - Chemin + - Description + * - GET + - /settings + - Obtention de la liste des tags + * - GET + - /setting/{id} + - Obtention d'un tag + * - POST + - /setting + - Création d'un tag + * - PUT + - /setting + - Mise à jour d'un tag + * - DELETE + - /setting/{id} + - Suppression d'un tag + +Obtention de la liste des tags +============================== + +Requête +------- + +:: + + GET /api/admin/tagtype/settings + +Paramètres +~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Paramètre + - Type + - Obligatoire + - Description + * - ``size`` + - Integer + - Non + - Nombre d'éléments par page. Par défaut, la valeur de ``paging.page.size`` (``25`` par défaut). + * - ``page`` + - Integer + - Non + - Numéro de page (commence à 1). Par défaut ``1``. + * - ``name`` + - String + - Non + - Filtre sur le nom du tag (recherche avec joker : correspond aux noms qui contiennent le texte). + * - ``owner`` + - String + - Non + - Filtre sur le propriétaire (recherche avec joker : correspond aux propriétaires qui contiennent le texte). + +Les tags sont triés par ordre de tri, nom et propriétaire. + +Réponse +------- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + La liste ne lit pas les chemins des tags, qui peuvent être longs : ses éléments n'ont donc pas de + ``paths``. PUT remplace le tag en entier : pour modifier un tag, obtenez-le d'abord avec + ``GET /setting/{id}`` afin de conserver ses ``paths``. + +Obtention d'un tag +================== + +Requête +------- + +:: + + GET /api/admin/tagtype/setting/{id} + +Réponse +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` et ``primary_term`` identifient la version lue du tag. ``paths`` et ``permissions`` +contiennent une valeur par ligne. + +Création d'un tag +================= + +Requête +------- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +Corps de la requête +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +Description des champs +~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Champ + - Type + - Obligatoire + - Description + * - ``name`` + - String + - Oui + - Nom du tag. Il est normalisé en NFKC, les suites d'espaces sont réduites et les extrémités + rognées ; le résultat doit compter de 1 à ``user.tag.name.max.length`` (par défaut : ``50``) + caractères, sans caractère de contrôle ni de format. + * - ``owner`` + - String + - Oui + - Identifiant de connexion du propriétaire (1000 caractères au maximum). + * - ``paths`` + - String + - Non + - URL des documents sur lesquels poser le tag, séparées par un saut de ligne (``\n``). Chacune + doit être égale au champ ``url`` d'un document. Au plus ``user.tag.max.paths`` (par défaut : + ``10000``). + * - ``permissions`` + - String + - Non + - Utilisateurs/groupes/rôles qui peuvent voir le tag (ex. ``{role}guest``), séparés par un saut + de ligne (``\n``). Vide, seul le propriétaire voit le tag. ``{role}guest`` (la valeur de + ``role.search.guest.permissions``) partage le tag avec tous les utilisateurs connectés. + * - ``virtual_host`` + - String + - Non + - Hôte virtuel (1000 caractères au maximum). + * - ``sort_order`` + - Integer + - Non + - Ordre d'affichage (entier positif ou nul). ``0`` s'il est omis. + +L'identifiant d'un tag est le SHA-256 de sa valeur, formée du nom et du propriétaire ; il est donc +décidé par le serveur. Le propriétaire et le nom identifient ensemble un tag : si le propriétaire a +déjà un tag de ce nom, la création échoue avec une erreur de validation (``status: 1``, « A tag with +the same name and owner already exists. »). + +Réponse +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +En cas de création réussie, ``created`` vaut ``true``. + +Mise à jour d'un tag +==================== + +Requête +------- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +Corps de la requête +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +Le corps contient tous les champs de la création, plus les champs suivants. Le tag est remplacé en +entier : envoyez aussi les ``paths`` à conserver. + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - Champ + - Type + - Obligatoire + - Description + * - ``id`` + - String + - Oui + - L'identifiant du tag à mettre à jour. + * - ``seq_no`` + - Integer + - Oui + - Le ``seq_no`` du tag renvoyé par ``GET /setting/{id}``. + * - ``primary_term`` + - Integer + - Oui + - Le ``primary_term`` du tag renvoyé par ``GET /setting/{id}``. + +- Si le tag a été modifié après sa lecture, c'est-à-dire que ``seq_no`` et ``primary_term`` ne + correspondent plus, la mise à jour échoue avec une erreur de validation (``status: 1``, « The tag + was changed by someone else. Reload it and try again. »). Obtenez à nouveau le tag et + recommencez. +- Modifier ``name`` ou ``owner`` donne au tag un nouvel identifiant ; l'``id`` de la réponse est le + nouveau. Si le propriétaire a déjà un tag du nouveau nom, la mise à jour échoue avec « A tag with + the same name and owner already exists. ». +- Lorsque le propriétaire change, la permission utilisateur de l'ancien propriétaire dans + ``permissions`` est remplacée par celle du nouveau propriétaire. + +Réponse +------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +Lors d'une mise à jour, ``created`` vaut ``false``. + +Suppression d'un tag +==================== + +Requête +------- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +Réponse +------- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +Si le tag est modifié pendant sa suppression, celle-ci échoue avec « The tag was changed by someone +else. Reload it and try again. ». + +Comment les modifications atteignent les documents +================================================== + +La création, la mise à jour et la suppression d'un tag par cette API sont enregistrées +immédiatement dans les tags. Tant que ``user.tag.enabled`` vaut ``true``, la modification destinée +aux documents (chemins ajoutés et retirés, renommage ou suppression) est mise en file d'attente et +appliquée par la tâche « Log Aggregator » (``log_aggregator``) chaque minute. Tant qu'il vaut +``false``, rien n'est mis en file ; exécutez la tâche « Tag Updater » (``tag_updater``) après avoir +activé les tags. Voir :doc:`../../admin/tagtype-guide`. + +Exemples d'utilisation +====================== + +Partager un tag avec tous les utilisateurs connectés +---------------------------------------------------- + +.. code-block:: bash + + # Lire le tag, avec paths, seq_no et primary_term + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # Le renvoyer avec {role}guest ajouté aux permissions + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +Obtention des tags d'un utilisateur +----------------------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +Informations complémentaires +============================ + +- :doc:`api-admin-overview` - Vue d'ensemble de l'API Admin +- :doc:`../api-tag` - API des tags +- :doc:`../../admin/tagtype-guide` - Guide de gestion des tags diff --git a/fr/15.9/api/admin/index.rst b/fr/15.9/api/admin/index.rst index 4f85fb53..7a56d85d 100644 --- a/fr/15.9/api/admin/index.rst +++ b/fr/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ L'API d'administration |Fess| est une API RESTful permettant d'accéder aux fonc :caption: Optimisation de la recherche api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/fr/15.9/api/api-tag.rst b/fr/15.9/api/api-tag.rst index 57e4e222..3be17933 100644 --- a/fr/15.9/api/api-tag.rst +++ b/fr/15.9/api/api-tag.rst @@ -2,7 +2,8 @@ API des tags ============ -Ce document décrit l'API des tags v2 de |Fess|, qui permet aux utilisateurs de taguer des documents. +Ce document décrit l'API des tags v2 de |Fess|, avec laquelle les utilisateurs connectés gèrent leurs +propres tags et les posent sur des documents. Pour l'enveloppe de réponse commune, le modèle d'erreur et les jetons CSRF, voir :doc:`api-overview`. L'URL de base est ``http:///api/v2/`` (exemple en environnement local : ``http://localhost:8080/api/v2``). @@ -10,31 +11,240 @@ L'URL de base est ``http:///api/v2/`` (exemple en environnement loc .. note:: Les tags sont désactivés par défaut. Pour les utiliser, définissez ``user.tag.enabled=true`` dans - ``fess_config.properties``. ``features.user_tag`` de ``/api/v2/ui/config`` indique l'état. + ``fess_config.properties``. ``features.user_tag`` de ``/api/v2/ui/config`` indique l'état. Tant + que les tags sont désactivés, les endpoints des tags répondent ``invalid_request`` (400) à une + requête qui passe les contrôles CSRF et Origin et utilise une méthode prise en charge. + +Fonctionnement des tags +======================= + +- Les tags sont gérés par utilisateur. L'utilisateur qui crée un tag en est le propriétaire, et le + propriétaire est l'identifiant de connexion. Deux utilisateurs peuvent employer le même nom et avoir + malgré tout deux tags distincts. +- Seuls les utilisateurs connectés peuvent utiliser les tags. Chaque endpoint agit en tant + qu'utilisateur de la session de connexion ; un jeton d'accès ne remplace pas une connexion. Un + appelant non connecté reçoit ``auth_required`` (401). +- Un nouveau tag est privé : seul son propriétaire le voit. Quand le propriétaire partage le tag, + tout utilisateur connecté peut le voir et filtrer avec. Un utilisateur non connecté ne voit aucun + tag, partagé ou non. +- Seul le propriétaire peut modifier ou supprimer un tag, ou le poser sur des documents et l'en + retirer. Un tag partagé d'un autre utilisateur sert uniquement à l'affichage et au filtrage. Les + administrateurs gèrent tous les tags dans l'écran d'administration (voir + :doc:`../admin/tagtype-guide`). +- Un tag est posé sur l'URL d'un document : tous les documents indexés ayant cette URL le reçoivent. + +Chaque tag a deux identifiants. + +``value`` + La valeur du tag, ``base64url(nom):base64url(propriétaire)`` (UTF-8, sans remplissage), stockée + dans le champ ``tag`` de l'index. Traitez-la comme une valeur opaque servant à filtrer les + résultats de recherche. + +``id`` + L'identifiant du tag, le SHA-256 de ``value`` en hexadécimal minuscule (64 caractères). Il + s'indique dans des chemins comme ``/api/v2/tags/{tagId}``. Renommer un tag change à la fois + ``value`` et ``id``. + +Le nom d'un tag est normalisé en NFKC, les suites d'espaces sont réduites à une seule et les +extrémités sont rognées. Le résultat doit compter de 1 à ``user.tag.name.max.length`` (par défaut : +``50``) caractères, et les noms contenant un caractère de contrôle ou de format (comme un caractère +de largeur nulle ou un forçage bidirectionnel) sont refusés. + +Les tags dans la recherche +========================== + +Tant que ``user.tag.enabled`` vaut ``true``, l'API de recherche (``/api/v2/search``) traite les tags +comme suit. + +- Chaque résultat porte dans ``tags`` les tags que l'appelant peut voir. Chaque entrée a ``value``, + ``name``, ``owner``, ``mine`` (``true`` lorsque l'appelant est le propriétaire) et ``shared`` + (``true`` pour un tag partagé). ``tags`` est absent s'il n'y en a aucun. Le champ d'index ``tag`` + lui-même n'est jamais renvoyé. +- ``facet.field=tag`` renvoie dans ``facet_field`` une facette des tags que l'appelant peut voir. + Outre ``value`` et ``count``, chaque compartiment a ``label`` (le nom du tag), ``owner``, ``mine`` + et ``shared``. +- ``fields.tag=`` restreint les résultats aux documents portant un tag. Passez tel quel le + ``value`` des ``tags`` d'un résultat ou d'un compartiment de la facette. + +Une condition sur les tags (``fields.tag``, ``tag:``, ``ex_q``, ``facet.query``) ne correspond qu'à +la valeur exacte d'un tag que l'appelant peut voir. La valeur d'un tag qu'il ne peut pas voir, ainsi +que les conditions avec joker, par préfixe, approximatives et par plage, ne correspondent à rien. Un +appelant non connecté ne reçoit ni tags ni facette de tags, et une condition sur les tags ne +correspond à rien. + +Un utilisateur voit au plus ``user.tag.visible.max.size`` (par défaut : ``1000``) tags, les siens en +premier. Au-delà, les tags n'apparaissent ni dans ``tags`` des résultats ni dans la facette, mais +peuvent toujours servir au filtrage. + +Quand les documents reflètent les modifications +=============================================== + +La création, la modification et la suppression des tags, ainsi que leur pose et leur retrait sur +les documents, apparaissent immédiatement dans les endpoints des tags. Le champ ``tag`` des documents +indexés, en revanche, est mis à jour via une file d'attente en mémoire que la tâche « Log Aggregator » +(``log_aggregator``) applique en bloc chaque minute. Les résultats, la facette et les filtres +reflètent donc une modification au bout d'une minute environ au plus. Après un renommage, les +documents gardent l'ancienne valeur jusqu'au prochain traitement de la file, et le tag n'y est pas +affiché entre-temps. + +Pour la file d'attente et les tâches, voir :doc:`../admin/tagtype-guide`. + +Lister les tags +=============== -Un tag est une étiquette du type « Tag » (voir :doc:`../admin/labeltype-guide`) : le nom de -l'étiquette est le nom du tag, la valeur est le SHA-256 du nom en hexadécimal, les chemins inclus sont -les URL taguées et les permissions décident qui peut voir le tag. Un tag n'est visible que si son -étiquette est visible pour l'appelant. +Requête +------- + +==================== ==================================================== +Méthode HTTP GET +Point de terminaison ``/api/v2/tags`` +==================== ==================================================== + +Renvoie les tags de l'appelant, par ordre de tri et par nom. Les tags partagés des autres utilisateurs +ne sont pas inclus. + +Réponse +------- + +En cas de succès (200), les champs suivants sont renvoyés directement sous ``response`` de l'enveloppe commune. + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "54788d242d35bdc53a2573eb7485b1d79c6c82a024c716ef6e27fc22064fb084", + "value": "YS1yZWxpcmU:Y2xhaXJl", + "name": "a-relire", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Champs de réponse + + * - ``tags`` + - Les tags de l'appelant. Chacun a ``id``, ``value``, ``name``, ``shared`` (``true`` pour un + tag partagé), ``sort_order`` et ``path_count`` (le nombre d'URL portant le tag). + +Tableau : Champs de réponse + +Créer un tag +============ + +Requête +------- + +==================== ==================================================== +Méthode HTTP POST +Point de terminaison ``/api/v2/tags`` +==================== ==================================================== + +Crée un tag de l'appelant. Comme requête qui modifie l'état, elle exige l'en-tête +``X-Fess-CSRF-Token`` (voir :doc:`api-overview`). + +- Un utilisateur peut avoir au plus ``user.tag.max.tags`` (par défaut : ``1000``) tags. Au-delà, + l'endpoint répond ``invalid_request`` (400). +- Si l'appelant a déjà un tag de ce nom, l'endpoint répond ``conflict`` (409). Qu'un autre + utilisateur ait un tag de même nom n'a pas d'importance. + +Envoyez ``Content-Type: application/json`` ; le corps fait au plus 1 Kio (1024 octets). + +:: + + { + "name": "a-relire", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: Corps de la requête + + * - ``name`` + - Nom du tag (str, obligatoire). + * - ``shared`` + - ``true`` rend le tag visible par tout utilisateur connecté (bool, par défaut : ``false``). + +Tableau : Corps de la requête + +Réponse +------- + +En cas de succès (200), ``tag`` directement sous ``response`` contient le nouveau tag, sous la forme +d'une entrée de ``GET /api/v2/tags`` avec un ``path_count`` de ``0``. + +Modifier un tag +=============== + +Requête +------- + +==================== ==================================================== +Méthode HTTP PUT +Point de terminaison ``/api/v2/tags/{tagId}`` +==================== ==================================================== + +Renomme un tag de l'appelant ou change son partage. L'en-tête ``X-Fess-CSRF-Token`` est requis. + +- Le corps contient ``name``, ``shared`` ou les deux. +- Un nouveau ``name`` renomme le tag, ce qui lui donne un nouvel ``id`` et une nouvelle ``value``. + Les documents portant l'ancienne valeur reçoivent la nouvelle au prochain traitement de la file. + Renommer vers un nom que l'appelant utilise déjà répond ``conflict`` (409) et laisse le tag + inchangé. +- ``shared`` change seulement qui voit le tag ; aucun document n'est mis à jour. Passer ``shared`` à + ``false`` conserve les rôles et groupes qu'un administrateur a ajoutés aux permissions. +- Un tag partagé d'un autre utilisateur répond ``forbidden`` (403), et un tag que l'appelant ne peut + pas voir ``not_found`` (404). +- Une écriture qui perd plusieurs fois face à une autre mise à jour répond aussi ``conflict`` (409). + +:: + + { + "name": "relu", + "shared": true + } -L'API de recherche (``/api/v2/search``) renvoie dans ``tags`` les tags de chaque résultat que -l'appelant peut voir. ``fields.tag=`` restreint les résultats aux documents portant un tag, -et ``facet.field=tag`` renvoie une facette de tags. Le champ d'index ``tag`` lui-même n'est pas -renvoyé. +En cas de succès (200), ``response`` contient ``tag`` (le tag modifié) et ``renamed`` (``true`` si le +tag a été renommé, auquel cas ``tag.id`` et ``tag.value`` sont nouveaux). -Obtenir les tags +Supprimer un tag ================ Requête ------- +==================== ==================================================== +Méthode HTTP DELETE +Point de terminaison ``/api/v2/tags/{tagId}`` +==================== ==================================================== + +Supprime un tag de l'appelant. Les documents perdent sa valeur au prochain traitement de la file. +L'en-tête ``X-Fess-CSRF-Token`` est requis. Un tag partagé d'un autre utilisateur répond +``forbidden`` (403), et un tag que l'appelant ne peut pas voir ``not_found`` (404). + +En cas de succès (200), ``response`` contient ``id`` (l'identifiant du tag supprimé) et ``deleted`` +(toujours ``true``). + +Obtenir les tags d'un document +============================== + +Requête +------- + ==================== ==================================================== Méthode HTTP GET Point de terminaison ``/api/v2/documents/{docId}/tags`` ==================== ==================================================== -Renvoie les tags du document que l'appelant peut voir. Si l'appelant ne peut pas rechercher le -document, l'endpoint répond ``not_found`` (404). +Renvoie les tags posés sur l'URL du document que l'appelant peut voir, ainsi que les tags de +l'appelant qui n'y sont pas encore posés. Le document est recherché avec les rôles de l'appelant : +un document qu'il ne peut pas rechercher répond ``not_found`` (404). Réponse ------- @@ -47,10 +257,25 @@ En cas de succès (200), les champs suivants sont renvoyés directement sous ``r "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "a-relire", "mine": true } - ] + { + "id": "54788d242d35bdc53a2573eb7485b1d79c6c82a024c716ef6e27fc22064fb084", + "value": "YS1yZWxpcmU:Y2xhaXJl", + "name": "a-relire", + "owner": "claire", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -59,21 +284,24 @@ En cas de succès (200), les champs suivants sont renvoyés directement sous ``r * - ``doc_id`` - ID du document (str). + * - ``tags`` + - Les tags posés sur l'URL du document que l'appelant peut voir. Chacun a ``id``, ``value``, + ``name``, ``owner``, ``mine`` (``true`` lorsque l'appelant est le propriétaire) et ``shared`` + (``true`` pour un tag partagé). * - ``addable`` - - ``true`` lorsque l'appelant est connecté et peut ajouter des tags (bool). + - Les tags de l'appelant qui ne sont pas posés sur l'URL du document, sous la même forme que + ``tags``. * - ``added`` - - POST uniquement. ``false`` lorsque l'appelant avait déjà tagué le document (bool). + - POST uniquement. ``false`` lorsque le tag était déjà posé sur le document (bool). + * - ``tag`` + - POST uniquement. Le tag posé sur le document, sous la même forme que ``tags``. * - ``removed`` - - DELETE uniquement (bool). - * - ``tags`` - - Les tags que l'appelant peut voir. Chacun a ``value`` (la valeur de l'étiquette, utilisée avec - ``fields.tag``), ``name`` (le nom du tag) et ``mine`` (``true`` lorsque l'appelant figure dans - les permissions du tag). + - DELETE uniquement. ``false`` lorsque le tag n'était pas posé sur le document (bool). Tableau : Champs de réponse -Ajouter un tag -============== +Poser un tag sur un document +============================ Requête ------- @@ -83,17 +311,10 @@ Méthode HTTP POST Point de terminaison ``/api/v2/documents/{docId}/tags`` ==================== ==================================================== -Tague l'URL du document pour l'utilisateur connecté ; un jeton d'accès ne remplace pas une connexion. -Comme requête qui modifie l'état, elle exige l'en-tête ``X-Fess-CSRF-Token``. - -- Si un tag de ce nom existe, l'URL est ajoutée à ses chemins inclus et l'utilisateur à ses - permissions. Sinon, un tag visible par ce seul utilisateur est créé. Les tags de même nom - fusionnent donc en un seul, et les utilisateurs qui ont ajouté un tag de même nom voient où se - trouvent les tags des autres. -- Taguer à nouveau le même document renvoie ``added: false``. -- Un document peut avoir au plus ``user.tag.max.document.tags`` (par défaut : ``100``) tags. +Ajoute l'URL du document à un tag de l'appelant. L'en-tête ``X-Fess-CSRF-Token`` est requis. -Envoyez ``Content-Type: application/json`` avec le nom du tag dans ``name``. +Le corps (``Content-Type: application/json``, 1 Kio au plus) indique soit ``id``, un tag existant, +soit ``name``, un nom de tag. Si les deux sont indiqués, ``id`` l'emporte. :: @@ -101,51 +322,102 @@ Envoyez ``Content-Type: application/json`` avec le nom du tag dans ``name``. "name": "a-relire" } -Le nom est normalisé en NFKC, les suites d'espaces sont réduites et il est rogné. Il doit compter de -1 à ``user.tag.name.max.length`` (par défaut : ``50``) caractères, et les noms contenant un caractère -de contrôle ou de format (comme un caractère de largeur nulle ou un forçage bidirectionnel) sont -refusés. +- Avec ``name``, si l'appelant n'a aucun tag de ce nom, un tag privé est créé et posé. Le nouveau tag + compte dans ``user.tag.max.tags``. +- Un tag peut être posé sur au plus ``user.tag.max.paths`` (par défaut : ``10000``) URL. Au-delà, + l'endpoint répond ``invalid_request`` (400). +- L'``id`` d'un tag d'un autre utilisateur répond ``forbidden`` (403) si l'appelant peut voir le tag, + et ``not_found`` (404) sinon. +- En cas de succès, la réponse contient les champs de « Obtenir les tags d'un document » plus + ``added`` et ``tag``. Les endpoints des tags montrent le tag immédiatement ; les résultats de + recherche des documents ayant cette URL le reflètent au prochain traitement de la file (environ une + minute plus tard). -Retirer un tag -============== +Retirer un tag d'un document +============================ Requête ------- ==================== ==================================================== Méthode HTTP DELETE -Point de terminaison ``/api/v2/documents/{docId}/tags?value=`` +Point de terminaison ``/api/v2/documents/{docId}/tags/{tagId}`` ==================== ==================================================== -Retire l'utilisateur connecté des permissions du tag indiqué par ``value``. Lorsqu'il ne reste aucune -permission d'utilisateur, de groupe ou de rôle, le tag est supprimé et retiré des documents. Si -l'utilisateur ne figure pas dans les permissions du tag, l'endpoint répond ``forbidden`` (403). -L'en-tête ``X-Fess-CSRF-Token`` est requis. +Retire l'URL du document du tag de l'appelant indiqué par ``tagId``. L'en-tête ``X-Fess-CSRF-Token`` +est requis. Un tag d'un autre utilisateur répond ``forbidden`` (403) si l'appelant peut le voir, et +``not_found`` (404) sinon. En cas de succès, la réponse contient les champs de « Obtenir les tags +d'un document » plus ``removed``. Réponses d'erreur ================= +Pour le détail du modèle d'erreur, voir :doc:`api-overview`. Les endpoints des tags renvoient les +statuts HTTP suivants. + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: Réponses d'erreur * - Code de statut - Description * - 400 Bad Request - - Lorsque la requête est invalide (y compris lorsque les tags sont désactivés, que le nom est - invalide ou qu'une limite est dépassée). + - Lorsque la requête est invalide, y compris lorsque les tags sont désactivés, que le nom est + invalide, qu'un champ obligatoire manque ou que ``user.tag.max.tags`` ou + ``user.tag.max.paths`` serait dépassé. * - 401 Unauthorized - - POST ou DELETE sans connexion. + - Sans connexion (un jeton d'accès ne la remplace pas). * - 403 Forbidden - - Un jeton CSRF absent ou expiré, ou un DELETE d'un tag que l'utilisateur n'a pas ajouté. + - Un jeton CSRF absent ou expiré, ou une modification du tag d'un autre utilisateur. Le contrôle + CSRF précède celui de la connexion : une requête qui modifie l'état sans session reçoit 403 et + non 401. * - 404 Not Found - - Lorsque le document est introuvable ou que l'appelant ne peut pas le rechercher. + - Lorsque le tag n'existe pas ou que l'appelant ne peut pas le voir, ou que le document est + introuvable ou que l'appelant ne peut pas le rechercher. * - 405 Method Not Allowed - Lorsque la méthode HTTP n'est pas autorisée. + * - 409 Conflict + - Lorsqu'un tag de ce nom existe déjà, ou qu'une écriture a perdu face à une autre mise à jour. * - 413 Payload Too Large - - Lorsque le corps de la requête dépasse la taille maximale. + - Lorsque le corps de la requête dépasse la taille maximale (1 Kio). * - 415 Unsupported Media Type - Lorsque le ``Content-Type`` n'est pas pris en charge. * - 500 Internal Server Error - Lorsqu'une erreur interne du serveur se produit. Tableau : Réponses d'erreur + +Paramètres +========== + +Les paramètres suivants de ``fess_config.properties`` règlent les tags. + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - Propriété + - Description + - Par défaut + * - ``user.tag.enabled`` + - Indique si les utilisateurs connectés peuvent utiliser les tags. + - ``false`` + * - ``user.tag.name.max.length`` + - Longueur maximale d'un nom de tag, en points de code. + - ``50`` + * - ``user.tag.max.tags`` + - Nombre maximal de tags qu'un utilisateur peut posséder. + - ``1000`` + * - ``user.tag.max.paths`` + - Nombre maximal d'URL sur lesquelles un tag peut être posé. + - ``10000`` + * - ``user.tag.queue.max.size`` + - Nombre maximal de modifications gardées en mémoire jusqu'à ce qu'elles atteignent les + documents. Une modification au-delà est abandonnée avec un journal WARN. + - ``10000`` + * - ``user.tag.process.batch.size`` + - Nombre d'URL mises à jour par requête en bloc lors de l'application des modifications aux + documents. + - ``100`` + * - ``user.tag.visible.max.size`` + - Nombre maximal de tags visibles par un utilisateur dans une recherche. + - ``1000`` diff --git a/fr/15.9/api/api-uiconfig.rst b/fr/15.9/api/api-uiconfig.rst index b4bc8606..afa0be2f 100644 --- a/fr/15.9/api/api-uiconfig.rst +++ b/fr/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ Tous les champs sont obligatoires. - Si l'exportation des résultats de recherche (``GET /api/v2/documents/export``) est activée (``api.search.export``). * - ``user_tag`` - boolean - - Si les tags (``/api/v2/documents/{docId}/tags``) sont activés (``user.tag.enabled``). + - Si les tags propres à chaque utilisateur sont activés (``user.tag.enabled``) : les endpoints des tags (``/api/v2/tags``, ``/api/v2/documents/{docId}/tags``) répondent et les résultats de recherche portent ``tags``. * - ``popular_word`` - boolean - Indique si la fonctionnalité de mots populaires est activée. diff --git a/fr/15.9/config/properties.po b/fr/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/fr/15.9/config/properties.po +++ b/fr/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/fr/15.9/config/properties.rst b/fr/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/fr/15.9/config/properties.rst +++ b/fr/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/ja/15.9/admin/index.rst b/ja/15.9/admin/index.rst index a645b622..54500b9c 100644 --- a/ja/15.9/admin/index.rst +++ b/ja/15.9/admin/index.rst @@ -27,6 +27,7 @@ fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/ja/15.9/admin/labeltype-guide.rst b/ja/15.9/admin/labeltype-guide.rst index 19d74f67..cbaf0317 100644 --- a/ja/15.9/admin/labeltype-guide.rst +++ b/ja/15.9/admin/labeltype-guide.rst @@ -85,31 +85,11 @@ ラベルの表示順を指定します。 -種類 -:::: - -「ラベル」または「タグ」を指定します。通常のラベルは「ラベル」です。「タグ」は、ユーザーが検索画面から追加するタグです(下の「タグ」を参照)。種類を指定していない既存のラベルは「ラベル」として扱われます。 - - 設定の削除 -------- 一覧ページの設定名をクリックし、削除ボタンをクリックすると確認画面が表示されます。 削除ボタンを押すと設定が削除されます。 -タグ ----- - -``fess_config.properties`` で ``user.tag.enabled=true`` (デフォルト: ``false`` )にすると、ログインしたユーザーが検索結果にタグを付けられるようになります。同梱の ``bootstrap`` テーマでは、結果にタグが表示され、タグの追加と自分が付けたタグの削除ができ、「タグ」のファセットで絞り込めます。API については :doc:`../api/api-tag` を参照してください。 - -タグは種類が「タグ」のラベルとして保存されます。名前がタグ名、値がタグ名の SHA-256、対象とするパスがタグを付けた URL(1 行に 1 つ、完全一致)、パーミッションがタグを見られるユーザーです。タグを付けたユーザーはパーミッションに追加されます。 - -- タグが見えるのは、そのラベルのパーミッションが呼び出し元に一致する場合だけです。管理者はこの画面でタグを編集して、ロールやグループと共有したり、削除したりできます。 -- 同じ名前のタグは 1 つのラベルにまとまります。そのため、同じ名前のタグを付けたユーザーどうしは、互いのタグの付与先を見られます。 -- タグはラベルの一覧 API( ``/api/v2/labels`` )や検索画面のラベルの選択肢には含まれません。 -- タグはラベルの件数の上限( ``page.labeltype.max.fetch.size`` 、デフォルト: 1000)に含まれます。上限に達すると新しいタグを作成できません。 -- 管理者がこの画面でタグを変更または削除した後、インデックスのドキュメントは、再クロールするか「Label Updater」ジョブを実行するまで以前の値のままです。 -- 1 つのドキュメントのタグの数は ``user.tag.max.document.tags`` (デフォルト: 100)、タグ名の長さは ``user.tag.name.max.length`` (デフォルト: 50)文字までです。 - .. |image0| image:: ../../../resources/images/ja/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/ja/15.9/admin/labeltype-2.png diff --git a/ja/15.9/admin/tagtype-guide.rst b/ja/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..cbc4aa5d --- /dev/null +++ b/ja/15.9/admin/tagtype-guide.rst @@ -0,0 +1,99 @@ +===== +タグ +===== + +概要 +==== + +ここでは、ユーザーのタグを管理する画面について説明します。 + +タグは、ログインしたユーザーが検索結果のドキュメントに付ける目印です。タグはユーザーごとに管理され、タグを作成したユーザーがその所有者です。同じ名前のタグでも、所有者が違えば別のタグです。タグは管理者が URL のパターンで定義する :doc:`ラベル ` とは別のもので、ユーザーが自分で作成し、個々のドキュメントに付けます。 + +タグ機能はデフォルトで無効です。利用するには ``fess_config.properties`` で ``user.tag.enabled=true`` を設定します。有効にすると、同梱の ``bootstrap`` テーマでは、ログインしたユーザーが検索結果にタグを付けたり外したりでき、タグのファセットで絞り込めます。「マイタグ」では自分のタグの名前の変更、共有の切り替え、削除ができます。他のユーザーの共有タグには「共有:」が付いて表示されます。ユーザー向けの API と設定については :doc:`../api/api-tag` を参照してください。 + +この画面では、管理者がすべてのユーザーのタグを一覧、作成、編集、削除できます。 + +管理方法 +======== + +表示方法 +-------- + +下図のタグの一覧ページを開くには、左メニューの [クローラー > タグ] をクリックします。閲覧には ``admin-tagtype`` または ``admin-tagtype-view`` のロールが必要で、作成・編集・削除には ``admin-tagtype`` が必要です。 + +一覧には各タグの名前と所有者が、表示順序、名前、所有者の順に表示されます。名前と所有者で検索でき、どちらも入力した文字列を含むタグに一致します。 + +編集するには名前をクリックします。 + +設定の作成 +---------- + +タグの作成ページを開くには新規作成ボタンをクリックします。 + +設定項目 +-------- + +名前 +:::: + +タグ名を指定します。名前は NFKC で正規化され、連続する空白は 1 つにまとめられ、前後の空白は取り除かれます。正規化後の長さは 1 〜 ``user.tag.name.max.length`` (デフォルト: 50)文字で、制御文字や書式文字を含む名前は指定できません。 + +所有者 +:::::: + +タグを所有するユーザーのログインユーザー ID を指定します。所有者と名前の組み合わせはタグごとに一意で、同じ所有者が同じ名前のタグを 2 つ持つことはできません(仮想ホストが違っても同じです)。 + +所有者を変更すると、パーミッションに含まれる元の所有者のユーザーのパーミッションは、新しい所有者のものに置き換わります。 + +パス +:::: + +タグを付けるドキュメントの URL を 1 行に 1 つ指定します。インデックスのドキュメントの ``url`` フィールドとの完全一致で照合され、正規表現は使えません。指定できる URL は最大 ``user.tag.max.paths`` (デフォルト: 10000)個です。 + +パーミッション +:::::::::::::: + +タグを見られるユーザー、グループ、ロールを指定します。指定方法はラベルと同じで、ユーザー単位は {user}ユーザー名、グループ単位は {group}グループ名、ロール単位は {role}ロール名で指定します。空のまま保存すると、所有者だけが見られるタグになります。 + +所有者は、パーミッションに関係なく常に自分のタグを見られます。ログインしていないユーザーには、パーミッションに関係なくタグは見えません。 + +仮想ホスト +:::::::::: + +タグを表示する仮想ホストのホスト名を指定します。ユーザーがタグを作成したときは、そのときアクセスした仮想ホストが入ります。仮想ホストでアクセスされた検索画面では、この欄にその仮想ホスト名が指定されたタグだけが見えます。どの仮想ホストにも一致しないアクセスでは、この欄に関係なくタグが見えます。詳しくは :doc:`設定ガイドの仮想ホスト <../config/security-virtual-host>` を参照してください。 + +表示順序 +:::::::: + +タグの表示順を指定します。 + +設定の削除 +---------- + +一覧ページの名前をクリックし、削除ボタンをクリックすると確認画面が表示されます。削除ボタンを押すとタグが削除され、ドキュメントからもタグの値が取り除かれます。 + +共有 +==== + +ユーザーがタグを「共有」にすると、パーミッションに ``role.search.guest.permissions`` の値(デフォルト: ``{role}guest`` )が追加されます。タグが見えるかどうかは、ログインしたユーザーのロールにこの値を加えて判定されるため、共有タグはログインしたすべてのユーザーに見え、絞り込みに使えます。共有を解除すると、この値だけが取り除かれます。 + +管理者はこの画面でパーミッションにグループやロールを追加して、特定のユーザーだけにタグを見せることもできます。ただし、タグを変更できるのは所有者と管理者だけです。他のユーザーは、見えるタグで表示や絞り込みをするだけです。 + +ドキュメントへの反映 +==================== + +ドキュメントのタグは、インデックスの ``tag`` フィールドに ``base64url(名前):base64url(所有者)`` の形式で格納されます。 + +- タグの作成・編集・削除や、ユーザーによるタグの付け外しは、すぐにタグの情報( ``fess_config.tag_type`` インデックス)に保存されます。ドキュメントの更新は、変更をメモリ上のキューに入れ、1 分ごとに実行される「Log Aggregator」( ``log_aggregator`` )ジョブがまとめて行います。そのため、検索結果に反映されるまで最大 1 分ほどかかります。 +- この画面でパスを変更すると、追加・削除した URL の分だけドキュメントが更新されます。名前や所有者を変更すると、古い値を持つドキュメントが新しい値に置き換わります。 +- クロールやデータストアでドキュメントをインデックスするときは、タグのパスと照合して ``tag`` フィールドを設定します。そのため、再クロールしてもタグは失われません。 +- 「Tag Updater」( ``tag_updater`` )ジョブは、すべてのドキュメントの ``tag`` フィールドをタグの情報から作り直します。スケジュールは設定されていないため、必要なときにスケジューラから手動で実行します。 + +運用上の注意 +============ + +- **Log Aggregator はすべてのノードで実行してください。** キューは JVM ごとにあり、そのノードの Log Aggregator だけが処理します。 ``log_aggregator`` ジョブの対象( ``target`` )はデフォルトの ``all`` のままにしてください。特定のノードに限定すると、他のノードで受け付けた変更がドキュメントに反映されません。 +- **次の場合は Tag Updater を実行してください。** キューはメモリ上にあるため、反映前の変更は |Fess| の再起動で失われます。 ``user.tag.enabled=false`` の間は、タグの変更がドキュメントに反映されず、再クロールするとドキュメントの ``tag`` フィールドは消えます。バックアップから復元した後も、ドキュメントのタグを作り直す必要があります。また、キューが ``user.tag.queue.max.size`` (デフォルト: 10000)を超えると、超えた変更は破棄され WARN ログが出力されます。いずれの場合も、 ``tag_updater`` を実行するとドキュメントのタグが作り直されます。 +- **タグの所有者はログインユーザー ID です。** ユーザー ID が変わると、そのユーザーのタグは元の ID に残ったままになります。SAML では NameID が永続的(persistent)な形式である必要があります。Entra ID では UPN、LDAP ではログイン時に入力した大文字小文字のままのユーザー名が所有者になります。ユーザーを削除しても、そのユーザーのタグは残るため、不要なタグはこの画面で削除してください。 +- **既存のインデックスでも利用できます。** 起動時に、ドキュメントのインデックスに ``tag`` フィールドのマッピングがなければ、 ``keyword`` 型で追加されます。既存のフィールドは変更されません。 +- タグの情報は ``fess_config.tag_type`` インデックスに保存されます。バックアップの ``fess_config.bulk`` には含まれますが、 ``fess_basic_config.bulk`` には含まれません。 diff --git a/ja/15.9/api/admin/api-admin-overview.rst b/ja/15.9/api/admin/api-admin-overview.rst index 120ef186..c1903158 100644 --- a/ja/15.9/api/admin/api-admin-overview.rst +++ b/ja/15.9/api/admin/api-admin-overview.rst @@ -450,6 +450,8 @@ Admin APIは、ほとんどの場合 HTTP ステータス ``200`` を返し、 - 説明 * - :doc:`api-admin-labeltype` - ラベルタイプ + * - :doc:`api-admin-tagtype` + - タグ * - :doc:`api-admin-keymatch` - キーマッチ * - :doc:`api-admin-boostdoc` diff --git a/ja/15.9/api/admin/api-admin-tagtype.rst b/ja/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..c069a2a6 --- /dev/null +++ b/ja/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,368 @@ +=========== +TagType API +=========== + +概要 +==== + +TagType APIは、|Fess| のユーザーのタグ(ログインしたユーザーがドキュメントに付けるユーザーごとのタグ)を管理するためのAPIです( :doc:`../../admin/tagtype-guide` を参照)。 ``user.tag.enabled`` の値に関係なく、すべてのユーザーのタグを管理できます。 + +認証方法やレスポンスの共通仕様(``status`` コード、``version`` フィールド、エラー形式、 +HTTPステータスコードなど)については :doc:`api-admin-overview` を参照してください。 +本APIにアクセスするには、管理API権限(``admin-api``)を持つアクセストークンを +``Authorization: Bearer <アクセストークン>`` ヘッダーで指定する必要があります。 + +本APIの JSON のフィールド名はスネークケース( ``sort_order`` 、 ``virtual_host`` 、 ``seq_no`` 、 ``primary_term`` など)です。 + +ベースURL +========= + +:: + + /api/admin/tagtype + +エンドポイント一覧 +================== + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - メソッド + - パス + - 説明 + * - GET + - /settings + - タグ一覧取得 + * - GET + - /setting/{id} + - タグ取得 + * - POST + - /setting + - タグ作成 + * - PUT + - /setting + - タグ更新 + * - DELETE + - /setting/{id} + - タグ削除 + +タグ一覧取得 +============ + +リクエスト +---------- + +:: + + GET /api/admin/tagtype/settings + +パラメーター +~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - パラメーター + - 型 + - 必須 + - 説明 + * - ``size`` + - Integer + - いいえ + - 1ページあたりの件数。デフォルトは ``paging.page.size`` の設定値(既定 ``25`` )です。 + * - ``page`` + - Integer + - いいえ + - ページ番号(1から開始)。デフォルトは ``1`` です。 + * - ``name`` + - String + - いいえ + - タグ名で絞り込み(ワイルドカード検索。入力した文字列を含む名前に一致)。 + * - ``owner`` + - String + - いいえ + - 所有者で絞り込み(ワイルドカード検索。入力した文字列を含む所有者に一致)。 + +タグは表示順序、名前、所有者の順に並びます。 + +レスポンス +---------- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + 一覧では、長くなりうるタグのパスを取得しないため、各要素には ``paths`` がありません。PUT はタグ全体を置き換えるため、タグを編集するときは、 ``paths`` を残せるよう先に ``GET /setting/{id}`` で取得してください。 + +タグ取得 +======== + +リクエスト +---------- + +:: + + GET /api/admin/tagtype/setting/{id} + +レスポンス +---------- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` と ``primary_term`` は、読み取ったタグのバージョンを表します。 ``paths`` と ``permissions`` は 1 行に 1 つの値を持ちます。 + +タグ作成 +======== + +リクエスト +---------- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +リクエストボディ +~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +フィールド説明 +~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - フィールド + - 型 + - 必須 + - 説明 + * - ``name`` + - String + - はい + - タグ名。NFKC で正規化され、連続する空白は 1 つにまとめられ、前後の空白は取り除かれます。正規化後の長さは 1 〜 ``user.tag.name.max.length`` (デフォルト: ``50`` )文字で、制御文字や書式文字は使えません。 + * - ``owner`` + - String + - はい + - タグを所有するユーザーのログインユーザー ID(最大1000文字)。 + * - ``paths`` + - String + - いいえ + - タグを付けるドキュメントの URL。複数指定する場合は改行( ``\n`` )で区切ります。それぞれドキュメントの ``url`` フィールドと完全に一致する必要があります。最大 ``user.tag.max.paths`` (デフォルト: ``10000`` )個。 + * - ``permissions`` + - String + - いいえ + - タグを見られるユーザー・グループ・ロール(例: ``{role}guest`` )。複数指定する場合は改行( ``\n`` )で区切ります。空の場合は所有者だけが見られます。 ``{role}guest`` ( ``role.search.guest.permissions`` の値)を含めると、ログインしたすべてのユーザーと共有されます。 + * - ``virtual_host`` + - String + - いいえ + - 仮想ホスト(最大1000文字)。 + * - ``sort_order`` + - Integer + - いいえ + - 表示順序(0以上の整数)。省略時は ``0`` です。 + +タグの ID は、名前と所有者から作られるタグの値の SHA-256 で、サーバーが決めます。所有者と名前の組み合わせでタグが識別されるため、所有者が同じ名前のタグをすでに持っている場合は、バリデーションエラー( ``status: 1`` 、「同じ名前と所有者のタグがすでに存在します。」)になります。 + +レスポンス +---------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +作成に成功すると ``created`` は ``true`` になります。 + +タグ更新 +======== + +リクエスト +---------- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +リクエストボディ +~~~~~~~~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +作成時のすべてのフィールドに加えて、以下のフィールドが必要です。タグは全体が置き換わるため、残したい ``paths`` も送ってください。 + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - フィールド + - 型 + - 必須 + - 説明 + * - ``id`` + - String + - はい + - 更新するタグの ID。 + * - ``seq_no`` + - Integer + - はい + - ``GET /setting/{id}`` が返したタグの ``seq_no`` 。 + * - ``primary_term`` + - Integer + - はい + - ``GET /setting/{id}`` が返したタグの ``primary_term`` 。 + +- 読み取った後にタグが変更され、 ``seq_no`` と ``primary_term`` が一致しなくなっている場合は、バリデーションエラー( ``status: 1`` 、「タグが他のユーザーによって変更されました。再読み込みしてからやり直してください。」)になります。タグを取得し直してから再実行してください。 +- ``name`` または ``owner`` を変更するとタグの ID が変わり、レスポンスの ``id`` は新しい ID になります。所有者が変更後の名前のタグをすでに持っている場合は、「同じ名前と所有者のタグがすでに存在します。」になります。 +- 所有者を変更すると、 ``permissions`` に含まれる元の所有者のユーザーのパーミッションは、新しい所有者のものに置き換わります。 + +レスポンス +---------- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +更新時は ``created`` が ``false`` になります。 + +タグ削除 +======== + +リクエスト +---------- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +レスポンス +---------- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +削除の途中でタグが変更された場合は、「タグが他のユーザーによって変更されました。再読み込みしてからやり直してください。」になります。 + +ドキュメントへの反映 +==================== + +本APIによるタグの作成・更新・削除は、すぐにタグの情報に保存されます。 ``user.tag.enabled`` が ``true`` の間は、ドキュメントへの変更(追加・削除したパス、名前の変更、削除)がキューに入り、1 分ごとの「Log Aggregator」( ``log_aggregator`` )ジョブで反映されます。 ``false`` の間はキューに入らないため、タグ機能を有効にした後に「Tag Updater」( ``tag_updater`` )ジョブを実行してください。 :doc:`../../admin/tagtype-guide` を参照してください。 + +使用例 +====== + +ログインしたすべてのユーザーとタグを共有 +---------------------------------------- + +.. code-block:: bash + + # paths、seq_no、primary_term を含めてタグを取得 + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # パーミッションに {role}guest を加えて送り返す + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +ユーザーのタグ一覧取得 +---------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +参考情報 +======== + +- :doc:`api-admin-overview` - 管理API概要 +- :doc:`../api-tag` - タグAPI +- :doc:`../../admin/tagtype-guide` - タグ管理ガイド diff --git a/ja/15.9/api/admin/index.rst b/ja/15.9/api/admin/index.rst index 10fee228..fa812d2d 100644 --- a/ja/15.9/api/admin/index.rst +++ b/ja/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Admin API リファレンス :caption: 検索チューニング api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/ja/15.9/api/api-tag.rst b/ja/15.9/api/api-tag.rst index caab7d62..8337fb5c 100644 --- a/ja/15.9/api/api-tag.rst +++ b/ja/15.9/api/api-tag.rst @@ -2,30 +2,192 @@ タグAPI ======= -このドキュメントでは、ドキュメントにタグを付ける |Fess| の v2 タグ API について説明します。共通のレスポンスエンベロープ・エラーモデル・CSRF については :doc:`api-overview` を参照してください。 +このドキュメントでは、ログインしたユーザーが自分のタグを管理し、ドキュメントに付ける |Fess| の v2 タグ API について説明します。共通のレスポンスエンベロープ・エラーモデル・CSRF については :doc:`api-overview` を参照してください。 ベースURLは ``http:///api/v2/`` です(ローカル環境の例: ``http://localhost:8080/api/v2`` )。 .. note:: - タグ機能はデフォルトで無効です。利用するには ``fess_config.properties`` で ``user.tag.enabled=true`` を設定してください。 ``/api/v2/ui/config`` の ``features.user_tag`` で状態を確認できます。 + タグ機能はデフォルトで無効です。利用するには ``fess_config.properties`` で ``user.tag.enabled=true`` を設定してください。 ``/api/v2/ui/config`` の ``features.user_tag`` で状態を確認できます。無効な間は、CSRF・Origin の検証を通過し、許可された HTTP メソッドを使うリクエストに対して、タグ API は ``invalid_request`` (400) を返します。 -タグは、種類が「タグ」のラベルです( :doc:`../admin/labeltype-guide` を参照)。ラベルの名前がタグ名、値がタグ名の SHA-256(16 進数)、対象とするパスがタグを付けた URL、パーミッションがタグを見られるユーザーです。タグが見えるのは、そのラベルが呼び出し元に見える場合だけです。 +タグの仕組み +============ -検索 API( ``/api/v2/search`` )は、各ヒットに呼び出し元に見えるタグを ``tags`` として返します。 ``fields.tag=<値>`` でタグの付いたドキュメントに絞り込め、 ``facet.field=tag`` でタグのファセットを取得できます。インデックスの ``tag`` フィールドそのものはレスポンスに含まれません。 +- タグはユーザーごとに管理されます。タグを作成したユーザーがそのタグの所有者です。所有者はログインユーザー ID です。同じ名前のタグでも、所有者が違えば別のタグです。 +- タグを使えるのはログインしたユーザーだけです。すべてのタグ API はセッションのログインユーザーとして動作し、アクセストークンはログインの代わりになりません。ログインしていない呼び出し元は ``auth_required`` (401) になります。 +- タグは作成時には非公開で、所有者だけが見られます。所有者がタグを「共有」にすると、ログインしたすべてのユーザーがそのタグを見て、絞り込みに使えるようになります。ログインしていないユーザーには、共有タグも見えません。 +- タグを変更、削除、ドキュメントに付け外しできるのは所有者だけです。他のユーザーの共有タグは表示と絞り込みにだけ使えます。管理者は管理画面ですべてのタグを管理できます( :doc:`../admin/tagtype-guide` を参照)。 +- タグはドキュメントの URL に付きます。同じ URL を持つインデックス上のすべてのドキュメントにタグが付きます。 -タグの取得 +各タグには次の識別子があります。 + +``value`` + タグの値です。 ``base64url(名前):base64url(所有者)`` (パディングなし、UTF-8)の形式で、インデックスの ``tag`` フィールドに格納されます。検索の絞り込みに使う不透明な値として扱ってください。 + +``id`` + タグ ID です。 ``value`` の SHA-256 を小文字の 16 進数で表した 64 文字の文字列です。 ``/api/v2/tags/{tagId}`` などのパスに指定します。名前を変更すると ``value`` と ``id`` の両方が変わります。 + +タグ名は NFKC で正規化され、連続する空白は 1 つにまとめられ、前後の空白は取り除かれます。正規化後の長さは 1 〜 ``user.tag.name.max.length`` (デフォルト: ``50`` )文字で、制御文字や書式文字(ゼロ幅文字や双方向の上書きなど)を含む名前は拒否されます。 + +検索での利用 +============ + +``user.tag.enabled`` が ``true`` の間、検索 API( ``/api/v2/search`` )は次のようにタグを扱います。 + +- 各ヒットに、呼び出し元に見えるタグを ``tags`` として返します。各要素は ``value`` 、 ``name`` 、 ``owner`` 、 ``mine`` (呼び出し元が所有者なら ``true`` )、 ``shared`` (共有タグなら ``true`` )です。見えるタグがなければ ``tags`` は返りません。インデックスの ``tag`` フィールドそのものは返りません。 +- ``facet.field=tag`` を指定すると、 ``facet_field`` に呼び出し元に見えるタグだけのファセットが返ります。各バケットには ``value`` と ``count`` に加えて、 ``label`` (タグ名)、 ``owner`` 、 ``mine`` 、 ``shared`` が付きます。 +- ``fields.tag=`` で、タグの付いたドキュメントに絞り込めます。値にはヒットの ``tags`` またはファセットの ``value`` をそのまま指定します。 + +タグを指定する条件( ``fields.tag`` 、 ``tag:`` 、 ``ex_q`` 、 ``facet.query`` )は、呼び出し元に見えるタグの値との完全一致だけが有効です。見えないタグの値や、ワイルドカード・前方一致・あいまい・範囲の条件は何にも一致しません。ログインしていない呼び出し元には、タグもタグのファセットも返らず、タグの条件は何にも一致しません。 + +1 人のユーザーに見えるタグは、自分のタグを優先して最大 ``user.tag.visible.max.size`` (デフォルト: ``1000`` )個です。これを超えたタグは、ヒットの ``tags`` とファセットには現れません(絞り込みには使えます)。 + +ドキュメントへの反映 +==================== + +タグの作成・変更・削除とドキュメントへの付け外しは、タグ API にはすぐに反映されます。一方、インデックスのドキュメントの ``tag`` フィールドは、変更をメモリ上のキューに入れ、1 分ごとに実行される「Log Aggregator」( ``log_aggregator`` )ジョブがまとめて更新します。そのため、検索結果のヒットやファセット、絞り込みに反映されるまで最大 1 分ほどかかります。名前を変更したタグは、次にキューが処理されるまで、ドキュメント上の古い値が見えないため検索結果に表示されません。 + +キューの扱いとジョブについては :doc:`../admin/tagtype-guide` を参照してください。 + +タグ一覧の取得 +============== + +リクエスト +---------- + +================== ==================================================== +HTTPメソッド GET +エンドポイント ``/api/v2/tags`` +================== ==================================================== + +呼び出し元が所有するタグを、表示順序と名前の順に返します。他のユーザーの共有タグは含まれません。 + +レスポンス +---------- + +成功時(200)は、共通エンベロープの ``response`` 直下に以下のフィールドが返ります。 + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "9667e32d74c547190e8f47b5e59ef88eb4c28ed40cf569126385db4545f6dfc5", + "value": "6KaB56K66KqN:dGFybw", + "name": "要確認", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: レスポンスフィールド + + * - ``tags`` + - 呼び出し元のタグの配列。各要素は ``id`` 、 ``value`` 、 ``name`` 、 ``shared`` (共有タグなら ``true`` )、 ``sort_order`` (表示順序)、 ``path_count`` (タグを付けた URL の数)。 + +表: レスポンスフィールド + +タグの作成 +========== + +リクエスト +---------- + +================== ==================================================== +HTTPメソッド POST +エンドポイント ``/api/v2/tags`` +================== ==================================================== + +呼び出し元のタグを作成します。状態を変更するリクエストのため、 ``X-Fess-CSRF-Token`` ヘッダーが必要です( :doc:`api-overview` を参照)。 + +- 1 人のユーザーが持てるタグは最大 ``user.tag.max.tags`` (デフォルト: ``1000`` )個です。超える場合は ``invalid_request`` (400) になります。 +- 呼び出し元が同じ名前のタグをすでに持っている場合は ``conflict`` (409) になります。他のユーザーが同じ名前のタグを持っていても作成できます。 + +リクエストボディは ``Content-Type: application/json`` で、最大サイズは 1 KiB(1024 バイト)です。 + +:: + + { + "name": "要確認", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: リクエストボディ + + * - ``name`` + - タグ名(str, 必須)。 + * - ``shared`` + - ``true`` にすると、ログインしたすべてのユーザーがタグを見られます(bool, デフォルト: ``false`` )。 + +表: リクエストボディ + +レスポンス +---------- + +成功時(200)は、 ``response`` 直下の ``tag`` に作成したタグ( ``GET /api/v2/tags`` の要素と同じ形式、 ``path_count`` は ``0`` )が返ります。 + +タグの変更 +========== + +リクエスト +---------- + +================== ==================================================== +HTTPメソッド PUT +エンドポイント ``/api/v2/tags/{tagId}`` +================== ==================================================== + +呼び出し元のタグの名前の変更と、共有の切り替えを行います。 ``X-Fess-CSRF-Token`` ヘッダーが必要です。 + +- リクエストボディには ``name`` と ``shared`` の少なくとも一方を指定します。 +- ``name`` で名前を変更すると、タグの ``id`` と ``value`` が新しくなります。古い値を持つドキュメントは、次にキューが処理されたときに新しい値に置き換わります。呼び出し元がすでに使っている名前に変更しようとすると ``conflict`` (409) になり、タグは変更されません。 +- ``shared`` は、タグを見られるユーザーだけを変えます。ドキュメントの更新は不要です。 ``shared`` を ``false`` にしても、管理者がパーミッションに追加したロールやグループはそのまま残ります。 +- 他のユーザーの共有タグは ``forbidden`` (403)、呼び出し元に見えないタグは ``not_found`` (404) になります。 +- 他の更新と競合して書き込みに繰り返し失敗した場合も ``conflict`` (409) になります。 + +:: + + { + "name": "確認済み", + "shared": true + } + +成功時(200)は、 ``response`` 直下に ``tag`` (変更後のタグ)と ``renamed`` (名前を変更した場合 ``true`` 。このとき ``tag.id`` と ``tag.value`` は新しい値)が返ります。 + +タグの削除 ========== リクエスト ---------- +================== ==================================================== +HTTPメソッド DELETE +エンドポイント ``/api/v2/tags/{tagId}`` +================== ==================================================== + +呼び出し元のタグを削除します。ドキュメントからは、次にキューが処理されたときにタグの値が取り除かれます。 ``X-Fess-CSRF-Token`` ヘッダーが必要です。他のユーザーの共有タグは ``forbidden`` (403)、呼び出し元に見えないタグは ``not_found`` (404) になります。 + +成功時(200)は、 ``response`` 直下に ``id`` (削除したタグ ID)と ``deleted`` (常に ``true`` )が返ります。 + +ドキュメントのタグの取得 +======================== + +リクエスト +---------- + ================== ==================================================== HTTPメソッド GET エンドポイント ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -指定したドキュメントのタグのうち、呼び出し元に見えるものを返します。呼び出し元がそのドキュメントを検索できない場合は ``not_found`` (404) になります。 +ドキュメントの URL に付いているタグのうち呼び出し元に見えるものと、まだ付いていない呼び出し元のタグを返します。ドキュメントは呼び出し元のロールで検索されるため、呼び出し元が検索できないドキュメントは ``not_found`` (404) になります。 レスポンス ---------- @@ -38,10 +200,25 @@ HTTPメソッド GET "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "要確認", "mine": true } - ] + { + "id": "9667e32d74c547190e8f47b5e59ef88eb4c28ed40cf569126385db4545f6dfc5", + "value": "6KaB56K66KqN:dGFybw", + "name": "要確認", + "owner": "taro", + "mine": true, + "shared": false + }, + { + "id": "303c4b8db4750ec89c37582674e67027df02170efe1449637384f8f73a17d105", + "value": "5LuV5qeY5pu4:aGFuYWtv", + "name": "仕様書", + "owner": "hanako", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -50,19 +227,21 @@ HTTPメソッド GET * - ``doc_id`` - ドキュメント ID(str)。 + * - ``tags`` + - ドキュメントの URL に付いているタグのうち、呼び出し元に見えるものの配列。各要素は ``id`` 、 ``value`` 、 ``name`` 、 ``owner`` (所有者)、 ``mine`` (呼び出し元が所有者なら ``true`` )、 ``shared`` (共有タグなら ``true`` )。 * - ``addable`` - - 呼び出し元がログインしている(タグを追加できる)場合 ``true`` (bool)。 + - ドキュメントの URL にまだ付いていない呼び出し元のタグの配列(要素の形式は ``tags`` と同じ)。 * - ``added`` - - POST のみ。呼び出し元が既にそのドキュメントにタグを付けていた場合は ``false`` (bool)。 + - POST のみ。タグがすでに付いていた場合は ``false`` (bool)。 + * - ``tag`` + - POST のみ。ドキュメントに付けたタグ(要素の形式は ``tags`` と同じ)。 * - ``removed`` - - DELETE のみ(bool)。 - * - ``tags`` - - 呼び出し元に見えるタグの配列。各要素は ``value`` (ラベルの値。 ``fields.tag`` に指定する値)、 ``name`` (タグ名)、 ``mine`` (呼び出し元がタグのパーミッションに含まれる場合 ``true`` )。 + - DELETE のみ。タグが付いていなかった場合は ``false`` (bool)。 表: レスポンスフィールド -タグの追加 -========== +ドキュメントへのタグの追加 +========================== リクエスト ---------- @@ -72,13 +251,9 @@ HTTPメソッド POST エンドポイント ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -ログインしているユーザーとして、ドキュメントの URL にタグを付けます。アクセストークンはログインの代わりになりません。状態を変更するリクエストのため、 ``X-Fess-CSRF-Token`` ヘッダーが必要です。 +ドキュメントの URL を呼び出し元のタグに追加します。 ``X-Fess-CSRF-Token`` ヘッダーが必要です。 -- 同じ名前のタグがあれば、その対象とするパスに URL を、パーミッションにユーザーを追加します。なければ、そのユーザーだけが見られるタグを作成します。そのため、同じ名前のタグは 1 つにまとまり、同じ名前のタグを付けた利用者どうしは互いのタグの付与先を見られます。 -- 同じドキュメントにもう一度付けると ``added`` は ``false`` になります。 -- 1 つのドキュメントに付けられるタグは最大 ``user.tag.max.document.tags`` (デフォルト: ``100`` )個です。 - -リクエストボディは ``Content-Type: application/json`` で、 ``name`` にタグ名を指定します。 +リクエストボディ( ``Content-Type: application/json`` 、最大 1 KiB)では、 ``id`` で既存のタグを指定するか、 ``name`` でタグ名を指定します。両方を指定した場合は ``id`` が優先されます。 :: @@ -86,44 +261,85 @@ HTTPメソッド POST "name": "要確認" } -タグ名は NFKC で正規化され、連続する空白は 1 つにまとめられ、前後の空白は取り除かれます。長さは 1 〜 ``user.tag.name.max.length`` (デフォルト: ``50`` )文字で、制御文字や書式文字(ゼロ幅文字や双方向の上書きなど)を含む名前は拒否されます。 +- ``name`` を指定し、呼び出し元がその名前のタグを持っていない場合は、非公開のタグを作成して付けます。作成したタグは ``user.tag.max.tags`` に数えられます。 +- 1 つのタグを付けられる URL は最大 ``user.tag.max.paths`` (デフォルト: ``10000`` )個です。超える場合は ``invalid_request`` (400) になります。 +- 他のユーザーのタグを ``id`` で指定すると、そのタグが見える場合は ``forbidden`` (403)、見えない場合は ``not_found`` (404) になります。 +- 成功時は、ドキュメントのタグの取得と同じフィールドに ``added`` と ``tag`` を加えて返します。タグは API 上ではすぐに付きますが、その URL のドキュメントの検索結果に反映されるのは、次にキューが処理されたとき(1 分ほど後)です。 -タグの削除 -========== +ドキュメントからのタグの削除 +============================ リクエスト ---------- ================== ==================================================== HTTPメソッド DELETE -エンドポイント ``/api/v2/documents/{docId}/tags?value=<タグの値>`` +エンドポイント ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -ログインしているユーザーを、 ``value`` で指定したタグのパーミッションから外します。ユーザー、グループ、ロールのパーミッションが 1 つも残らなくなると、タグは削除され、ドキュメントからも取り除かれます。ユーザーがタグのパーミッションに含まれていない場合は ``forbidden`` (403) になります。 ``X-Fess-CSRF-Token`` ヘッダーが必要です。 +ドキュメントの URL を、 ``tagId`` で指定した呼び出し元のタグから取り除きます。 ``X-Fess-CSRF-Token`` ヘッダーが必要です。他のユーザーのタグは、見える場合は ``forbidden`` (403)、見えない場合は ``not_found`` (404) になります。成功時は、ドキュメントのタグの取得と同じフィールドに ``removed`` を加えて返します。 エラーレスポンス ================ +エラーモデルの詳細は :doc:`api-overview` を参照してください。タグ API が返す HTTP ステータスは以下の通りです。 + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: エラーレスポンス * - ステータスコード - 説明 * - 400 Bad Request - - リクエストが不正な場合(タグ機能が無効な場合、タグ名が不正な場合、タグの上限を超えた場合を含む)。 + - リクエストが不正な場合。タグ機能が無効な場合、タグ名が不正な場合、必須の項目がない場合、 ``user.tag.max.tags`` や ``user.tag.max.paths`` の上限を超える場合を含みます。 * - 401 Unauthorized - - POST・DELETE でログインしていない場合。 + - ログインしていない場合(アクセストークンはログインの代わりになりません)。 * - 403 Forbidden - - CSRF トークンの欠落・失効、または自分が追加していないタグを DELETE した場合。 + - CSRF トークンの欠落・失効、または他のユーザーのタグを変更しようとした場合。CSRF の検証はログインの確認より先に行われるため、セッションのない状態変更リクエストは 401 ではなく 403 になります。 * - 404 Not Found - - ドキュメントが見つからない、または呼び出し元が検索できない場合。 + - タグが存在しないか呼び出し元に見えない場合、またはドキュメントが見つからないか呼び出し元が検索できない場合。 * - 405 Method Not Allowed - HTTP メソッドが許可されていない場合。 + * - 409 Conflict + - 同じ名前のタグがすでにある場合、または他の更新と競合して書き込めなかった場合。 * - 413 Payload Too Large - - リクエストボディがサイズ上限を超えている場合。 + - リクエストボディがサイズ上限(1 KiB)を超えている場合。 * - 415 Unsupported Media Type - サポートされていない ``Content-Type`` の場合。 * - 500 Internal Server Error - サーバー内部エラーが発生した場合。 表: エラーレスポンス + +設定 +==== + +``fess_config.properties`` の次の設定でタグ機能を調整できます。 + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - プロパティ + - 説明 + - デフォルト + * - ``user.tag.enabled`` + - ログインしたユーザーがタグを使えるかどうか。 + - ``false`` + * - ``user.tag.name.max.length`` + - タグ名の最大文字数(コードポイント数)。 + - ``50`` + * - ``user.tag.max.tags`` + - 1 人のユーザーが持てるタグの最大数。 + - ``1000`` + * - ``user.tag.max.paths`` + - 1 つのタグを付けられる URL の最大数。 + - ``10000`` + * - ``user.tag.queue.max.size`` + - ドキュメントに反映されるまでメモリ上に保持する変更の最大数。超えた変更は破棄され、WARN ログが出力されます。 + - ``10000`` + * - ``user.tag.process.batch.size`` + - 変更をドキュメントに反映するときに、1 回のバルクリクエストで更新する URL の数。 + - ``100`` + * - ``user.tag.visible.max.size`` + - 検索で 1 人のユーザーに見えるタグの最大数。 + - ``1000`` diff --git a/ja/15.9/api/api-uiconfig.rst b/ja/15.9/api/api-uiconfig.rst index fdd7203d..5f8f1b48 100644 --- a/ja/15.9/api/api-uiconfig.rst +++ b/ja/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ features - 検索結果のエクスポート( ``GET /api/v2/documents/export`` )が有効かどうか( ``api.search.export`` )。 * - ``user_tag`` - boolean - - タグ機能( ``/api/v2/documents/{docId}/tags`` )が有効かどうか( ``user.tag.enabled`` )。 + - ユーザーごとのタグ( ``/api/v2/tags`` 、 ``/api/v2/documents/{docId}/tags`` )が有効で、検索結果のヒットに ``tags`` が付くかどうか( ``user.tag.enabled`` )。 * - ``popular_word`` - boolean - 人気ワード機能が有効かどうか。 diff --git a/ja/15.9/config/properties.po b/ja/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/ja/15.9/config/properties.po +++ b/ja/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/ja/15.9/config/properties.rst b/ja/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/ja/15.9/config/properties.rst +++ b/ja/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/ko/15.9/admin/index.rst b/ko/15.9/admin/index.rst index d68c9059..ef034f7b 100644 --- a/ko/15.9/admin/index.rst +++ b/ko/15.9/admin/index.rst @@ -27,6 +27,7 @@ fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/ko/15.9/admin/labeltype-guide.rst b/ko/15.9/admin/labeltype-guide.rst index b5cbc82d..8ab0a8cc 100644 --- a/ko/15.9/admin/labeltype-guide.rst +++ b/ko/15.9/admin/labeltype-guide.rst @@ -85,31 +85,11 @@ 라벨의 표시 순서를 지정합니다. -종류 -:::: - -「라벨」 또는 「태그」를 지정합니다. 일반 라벨은 「라벨」입니다. 「태그」는 사용자가 검색 화면에서 추가하는 태그입니다(아래의 「태그」를 참조). 종류를 지정하지 않은 기존 라벨은 「라벨」로 취급됩니다. - - 설정 삭제 -------- 목록 페이지의 설정 이름을 클릭하고 삭제 버튼을 클릭하면 확인 화면이 표시됩니다. 삭제 버튼을 누르면 설정이 삭제됩니다. -태그 ----- - -``fess_config.properties`` 에서 ``user.tag.enabled=true`` (기본값: ``false`` )로 설정하면 로그인한 사용자가 검색 결과에 태그를 붙일 수 있습니다. 기본 제공 ``bootstrap`` 테마에서는 결과에 태그가 표시되고, 태그 추가와 자신이 붙인 태그의 삭제가 가능하며, 「태그」 패싯으로 결과를 좁힐 수 있습니다. API 에 대해서는 :doc:`../api/api-tag` 를 참조하십시오. - -태그는 종류가 「태그」인 라벨로 저장됩니다. 이름이 태그 이름, 값이 태그 이름의 SHA-256, 대상 경로가 태그를 붙인 URL(한 줄에 하나, 정확히 일치), 권한이 태그를 볼 수 있는 사용자입니다. 태그를 붙인 사용자는 권한에 추가됩니다. - -- 태그는 그 라벨의 권한이 호출자와 일치하는 경우에만 보입니다. 관리자는 이 화면에서 태그를 편집하여 역할이나 그룹과 공유하거나 삭제할 수 있습니다. -- 같은 이름의 태그는 하나의 라벨로 합쳐집니다. 따라서 같은 이름의 태그를 붙인 사용자끼리는 서로의 태그가 붙은 곳을 볼 수 있습니다. -- 태그는 라벨 목록 API( ``/api/v2/labels`` )나 검색 화면의 라벨 선택지에 포함되지 않습니다. -- 태그는 라벨 건수 상한( ``page.labeltype.max.fetch.size`` , 기본값: 1000)에 포함됩니다. 상한에 도달하면 새 태그를 만들 수 없습니다. -- 관리자가 이 화면에서 태그를 변경 또는 삭제한 후, 인덱스의 문서는 다시 크롤링하거나 「Label Updater」 작업을 실행할 때까지 이전 값을 유지합니다. -- 문서 하나에 붙일 수 있는 태그 수는 ``user.tag.max.document.tags`` (기본값: 100), 태그 이름의 길이는 ``user.tag.name.max.length`` (기본값: 50)자까지입니다. - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png diff --git a/ko/15.9/admin/tagtype-guide.rst b/ko/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..55a9bdd0 --- /dev/null +++ b/ko/15.9/admin/tagtype-guide.rst @@ -0,0 +1,99 @@ +===== +태그 +===== + +개요 +==== + +여기서는 사용자의 태그를 관리하는 화면에 대해 설명합니다. + +태그는 로그인한 사용자가 검색 결과의 문서에 붙이는 표시입니다. 태그는 사용자별로 관리되며, 태그를 만든 사용자가 그 소유자입니다. 같은 이름의 태그라도 소유자가 다르면 별개의 태그입니다. 태그는 관리자가 URL 패턴으로 정의하는 :doc:`라벨 ` 과는 다른 것으로, 사용자가 직접 만들어 개별 문서에 붙입니다. + +태그 기능은 기본적으로 비활성화되어 있습니다. 사용하려면 ``fess_config.properties`` 에서 ``user.tag.enabled=true`` 를 설정합니다. 활성화하면 기본 제공되는 ``bootstrap`` 테마에서 로그인한 사용자가 검색 결과에 태그를 붙이거나 뗄 수 있고, 태그 패싯으로 필터링할 수 있습니다. 「내 태그」에서는 자신의 태그 이름 변경, 공유 전환, 삭제를 할 수 있습니다. 다른 사용자의 공유 태그에는 「공유:」가 붙어 표시됩니다. 사용자용 API 와 설정에 대해서는 :doc:`../api/api-tag` 를 참조하십시오. + +이 화면에서는 관리자가 모든 사용자의 태그를 목록 표시, 생성, 편집, 삭제할 수 있습니다. + +관리 방법 +========= + +표시 방법 +--------- + +태그 목록 페이지를 열려면 왼쪽 메뉴의 [크롤러 > 태그]를 클릭합니다. 열람에는 ``admin-tagtype`` 또는 ``admin-tagtype-view`` 역할이 필요하며, 생성·편집·삭제에는 ``admin-tagtype`` 이 필요합니다. + +목록에는 각 태그의 이름과 소유자가 표시 순서, 이름, 소유자 순으로 표시됩니다. 이름과 소유자로 검색할 수 있으며, 둘 다 입력한 문자열을 포함하는 태그와 일치합니다. + +편집하려면 이름을 클릭합니다. + +설정 생성 +--------- + +태그 생성 페이지를 열려면 신규 생성 버튼을 클릭합니다. + +설정 항목 +--------- + +이름 +:::: + +태그 이름을 지정합니다. 이름은 NFKC 로 정규화되고, 연속된 공백은 하나로 합쳐지며, 앞뒤 공백은 제거됩니다. 정규화 후의 길이는 1 ~ ``user.tag.name.max.length`` (기본값: 50)자이며, 제어 문자나 서식 문자를 포함한 이름은 지정할 수 없습니다. + +소유자 +:::::: + +태그를 소유하는 사용자의 로그인 사용자 ID 를 지정합니다. 소유자와 이름의 조합은 태그마다 고유하므로, 같은 소유자가 같은 이름의 태그를 두 개 가질 수 없습니다(가상 호스트가 달라도 마찬가지입니다). + +소유자를 변경하면 권한에 포함된 이전 소유자의 사용자 권한이 새 소유자의 것으로 바뀝니다. + +경로 +:::: + +태그를 붙일 문서의 URL 을 한 줄에 하나씩 지정합니다. 인덱스 문서의 ``url`` 필드와 완전 일치로 대조되며, 정규 표현식은 사용할 수 없습니다. 지정할 수 있는 URL 은 최대 ``user.tag.max.paths`` (기본값: 10000)개입니다. + +권한 +:::: + +태그를 볼 수 있는 사용자, 그룹, 역할을 지정합니다. 지정 방법은 라벨과 같으며, 사용자 단위는 {user}사용자 이름, 그룹 단위는 {group}그룹 이름, 역할 단위는 {role}역할 이름으로 지정합니다. 비워 둔 채 저장하면 소유자만 볼 수 있는 태그가 됩니다. + +소유자는 권한과 관계없이 항상 자신의 태그를 볼 수 있습니다. 로그인하지 않은 사용자에게는 권한과 관계없이 태그가 보이지 않습니다. + +가상 호스트 +::::::::::: + +태그를 표시할 가상 호스트의 호스트 이름을 지정합니다. 사용자가 태그를 만들었을 때는 그때 접근한 가상 호스트가 들어갑니다. 가상 호스트로 접근한 검색 화면에서는 이 항목에 그 가상 호스트 이름이 지정된 태그만 보입니다. 어떤 가상 호스트와도 일치하지 않는 접근에서는 이 항목과 관계없이 태그가 보입니다. 자세한 내용은 :doc:`설정 가이드의 가상 호스트 <../config/security-virtual-host>` 를 참조하십시오. + +표시 순서 +::::::::: + +태그의 표시 순서를 지정합니다. + +설정 삭제 +--------- + +목록 페이지의 이름을 클릭하고 삭제 버튼을 클릭하면 확인 화면이 표시됩니다. 삭제 버튼을 누르면 태그가 삭제되고, 문서에서도 태그 값이 제거됩니다. + +공유 +==== + +사용자가 태그를 「공유」하면 권한에 ``role.search.guest.permissions`` 의 값(기본값: ``{role}guest`` )이 추가됩니다. 태그가 보이는지 여부는 로그인한 사용자의 역할에 이 값을 더해 판정되므로, 공유 태그는 로그인한 모든 사용자에게 보이고 필터링에 사용할 수 있습니다. 공유를 해제하면 이 값만 제거됩니다. + +관리자는 이 화면에서 권한에 그룹이나 역할을 추가하여 특정 사용자에게만 태그를 보여 줄 수도 있습니다. 다만 태그를 변경할 수 있는 것은 소유자와 관리자뿐입니다. 다른 사용자는 보이는 태그로 표시나 필터링만 할 수 있습니다. + +문서에 대한 반영 +================ + +문서의 태그는 인덱스의 ``tag`` 필드에 ``base64url(이름):base64url(소유자)`` 형식으로 저장됩니다. + +- 태그의 생성·편집·삭제나 사용자에 의한 태그 붙이기·떼기는 즉시 태그 정보( ``fess_config.tag_type`` 인덱스)에 저장됩니다. 문서 갱신은 변경을 메모리상의 큐에 넣고, 1분마다 실행되는 「Log Aggregator」( ``log_aggregator`` ) 작업이 일괄로 수행합니다. 따라서 검색 결과에 반영되기까지 최대 1분 정도 걸립니다. +- 이 화면에서 경로를 변경하면 추가·삭제한 URL 의 문서만 갱신됩니다. 이름이나 소유자를 변경하면 이전 값을 가진 문서가 새 값으로 바뀝니다. +- 크롤이나 데이터 스토어로 문서를 인덱싱할 때는 태그의 경로와 대조하여 ``tag`` 필드를 설정합니다. 따라서 다시 크롤해도 태그는 사라지지 않습니다. +- 「Tag Updater」( ``tag_updater`` ) 작업은 모든 문서의 ``tag`` 필드를 태그 정보로부터 다시 만듭니다. 스케줄이 설정되어 있지 않으므로 필요할 때 스케줄러에서 수동으로 실행합니다. + +운용상의 주의 +============= + +- **Log Aggregator 는 모든 노드에서 실행하십시오.** 큐는 JVM 마다 있으며, 그 노드의 Log Aggregator 만 처리합니다. ``log_aggregator`` 작업의 대상( ``target`` )은 기본값인 ``all`` 그대로 두십시오. 특정 노드로 한정하면 다른 노드에서 받은 변경이 문서에 반영되지 않습니다. +- **다음의 경우에는 Tag Updater 를 실행하십시오.** 큐는 메모리상에 있으므로 반영 전의 변경은 |Fess| 를 재시작하면 사라집니다. ``user.tag.enabled=false`` 인 동안에는 태그 변경이 문서에 반영되지 않으며, 다시 크롤하면 문서의 ``tag`` 필드가 지워집니다. 백업에서 복원한 후에도 문서의 태그를 다시 만들어야 합니다. 또한 큐가 ``user.tag.queue.max.size`` (기본값: 10000)를 넘으면 초과한 변경은 버려지고 WARN 로그가 출력됩니다. 어느 경우든 ``tag_updater`` 를 실행하면 문서의 태그가 다시 만들어집니다. +- **태그의 소유자는 로그인 사용자 ID 입니다.** 사용자 ID 가 바뀌면 그 사용자의 태그는 원래 ID 에 남습니다. SAML 에서는 NameID 가 영구적(persistent)인 형식이어야 합니다. Entra ID 에서는 UPN, LDAP 에서는 로그인할 때 입력한 대소문자 그대로의 사용자 이름이 소유자가 됩니다. 사용자를 삭제해도 그 사용자의 태그는 남으므로, 필요 없는 태그는 이 화면에서 삭제하십시오. +- **기존 인덱스에서도 사용할 수 있습니다.** 시작할 때 문서 인덱스에 ``tag`` 필드의 매핑이 없으면 ``keyword`` 타입으로 추가됩니다. 기존 필드는 변경되지 않습니다. +- 태그 정보는 ``fess_config.tag_type`` 인덱스에 저장됩니다. 백업의 ``fess_config.bulk`` 에는 포함되지만 ``fess_basic_config.bulk`` 에는 포함되지 않습니다. diff --git a/ko/15.9/api/admin/api-admin-overview.rst b/ko/15.9/api/admin/api-admin-overview.rst index 32c316a1..543995a0 100644 --- a/ko/15.9/api/admin/api-admin-overview.rst +++ b/ko/15.9/api/admin/api-admin-overview.rst @@ -450,6 +450,8 @@ Admin API는 대부분의 경우 HTTP 상태 ``200`` 을 반환하며, 처리 - 설명 * - :doc:`api-admin-labeltype` - 라벨 타입 + * - :doc:`api-admin-tagtype` + - 태그 * - :doc:`api-admin-keymatch` - 키 매치 * - :doc:`api-admin-boostdoc` diff --git a/ko/15.9/api/admin/api-admin-tagtype.rst b/ko/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..bf1bc4cc --- /dev/null +++ b/ko/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,368 @@ +=========== +TagType API +=========== + +개요 +==== + +TagType API는 |Fess| 의 사용자 태그(로그인한 사용자가 문서에 붙이는 사용자별 태그)를 관리하기 위한 API입니다( :doc:`../../admin/tagtype-guide` 참조). ``user.tag.enabled`` 값과 관계없이 모든 사용자의 태그를 관리할 수 있습니다. + +인증 방법 및 응답의 공통 사양(``status`` 코드, ``version`` 필드, 오류 형식, +HTTP 상태 코드 등)에 대해서는 :doc:`api-admin-overview` 를 참조하십시오. +이 API에 접근하려면 관리 API 권한(``admin-api``)을 가진 액세스 토큰을 +``Authorization: Bearer <액세스 토큰>`` 헤더로 지정해야 합니다. + +이 API의 JSON 필드 이름은 스네이크 케이스( ``sort_order`` , ``virtual_host`` , ``seq_no`` , ``primary_term`` 등)입니다. + +기본 URL +======== + +:: + + /api/admin/tagtype + +엔드포인트 목록 +=============== + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - 메서드 + - 경로 + - 설명 + * - GET + - /settings + - 태그 목록 조회 + * - GET + - /setting/{id} + - 태그 조회 + * - POST + - /setting + - 태그 생성 + * - PUT + - /setting + - 태그 업데이트 + * - DELETE + - /setting/{id} + - 태그 삭제 + +태그 목록 조회 +============== + +요청 +---- + +:: + + GET /api/admin/tagtype/settings + +파라미터 +~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - 파라미터 + - 타입 + - 필수 + - 설명 + * - ``size`` + - Integer + - 아니요 + - 페이지당 건수. 기본값은 ``paging.page.size`` 설정값(기본 ``25`` )입니다. + * - ``page`` + - Integer + - 아니요 + - 페이지 번호(1부터 시작). 기본값은 ``1`` 입니다. + * - ``name`` + - String + - 아니요 + - 태그 이름으로 필터링(와일드카드 검색. 입력한 문자열을 포함하는 이름과 일치). + * - ``owner`` + - String + - 아니요 + - 소유자로 필터링(와일드카드 검색. 입력한 문자열을 포함하는 소유자와 일치). + +태그는 표시 순서, 이름, 소유자 순으로 정렬됩니다. + +응답 +---- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + 목록에서는 길어질 수 있는 태그의 경로를 가져오지 않으므로, 각 요소에는 ``paths`` 가 없습니다. PUT 은 태그 전체를 교체하므로, 태그를 편집할 때는 ``paths`` 가 유지되도록 먼저 ``GET /setting/{id}`` 로 가져오십시오. + +태그 조회 +========= + +요청 +---- + +:: + + GET /api/admin/tagtype/setting/{id} + +응답 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` 와 ``primary_term`` 은 읽어 온 태그의 버전을 나타냅니다. ``paths`` 와 ``permissions`` 는 한 줄에 하나의 값을 갖습니다. + +태그 생성 +========= + +요청 +---- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +요청 본문 +~~~~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +필드 설명 +~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - 필드 + - 타입 + - 필수 + - 설명 + * - ``name`` + - String + - 예 + - 태그 이름. NFKC 로 정규화되고, 연속된 공백은 하나로 합쳐지며, 앞뒤 공백은 제거됩니다. 정규화 후의 길이는 1 ~ ``user.tag.name.max.length`` (기본값: ``50`` )자이며, 제어 문자나 서식 문자는 사용할 수 없습니다. + * - ``owner`` + - String + - 예 + - 태그를 소유하는 사용자의 로그인 사용자 ID(최대 1000자). + * - ``paths`` + - String + - 아니요 + - 태그를 붙일 문서의 URL. 여러 개를 지정하려면 줄바꿈( ``\n`` )으로 구분합니다. 각각 문서의 ``url`` 필드와 완전히 일치해야 합니다. 최대 ``user.tag.max.paths`` (기본값: ``10000`` )개. + * - ``permissions`` + - String + - 아니요 + - 태그를 볼 수 있는 사용자·그룹·역할(예: ``{role}guest`` ). 여러 개를 지정하려면 줄바꿈( ``\n`` )으로 구분합니다. 비어 있으면 소유자만 볼 수 있습니다. ``{role}guest`` ( ``role.search.guest.permissions`` 의 값)를 포함하면 로그인한 모든 사용자와 공유됩니다. + * - ``virtual_host`` + - String + - 아니요 + - 가상 호스트(최대 1000자). + * - ``sort_order`` + - Integer + - 아니요 + - 표시 순서(0 이상의 정수). 생략하면 ``0`` 입니다. + +태그 ID 는 이름과 소유자로 만들어지는 태그 값의 SHA-256 이며, 서버가 결정합니다. 소유자와 이름의 조합으로 태그가 식별되므로, 소유자가 같은 이름의 태그를 이미 가지고 있으면 유효성 검사 오류( ``status: 1`` , "A tag with the same name and owner already exists.")가 됩니다. + +응답 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +생성에 성공하면 ``created`` 는 ``true`` 가 됩니다. + +태그 업데이트 +============= + +요청 +---- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +요청 본문 +~~~~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +생성 시의 모든 필드에 더해 다음 필드가 필요합니다. 태그는 전체가 교체되므로, 유지하려는 ``paths`` 도 함께 보내십시오. + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - 필드 + - 타입 + - 필수 + - 설명 + * - ``id`` + - String + - 예 + - 업데이트할 태그의 ID. + * - ``seq_no`` + - Integer + - 예 + - ``GET /setting/{id}`` 가 반환한 태그의 ``seq_no`` . + * - ``primary_term`` + - Integer + - 예 + - ``GET /setting/{id}`` 가 반환한 태그의 ``primary_term`` . + +- 읽어 온 뒤 태그가 변경되어 ``seq_no`` 와 ``primary_term`` 이 일치하지 않으면 유효성 검사 오류( ``status: 1`` , "The tag was changed by someone else. Reload it and try again.")가 됩니다. 태그를 다시 가져온 뒤 재시도하십시오. +- ``name`` 이나 ``owner`` 를 변경하면 태그 ID 가 바뀌며, 응답의 ``id`` 는 새 ID 입니다. 소유자가 변경 후 이름의 태그를 이미 가지고 있으면 "A tag with the same name and owner already exists." 가 됩니다. +- 소유자를 변경하면 ``permissions`` 에 포함된 이전 소유자의 사용자 권한이 새 소유자의 것으로 바뀝니다. + +응답 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +업데이트 시에는 ``created`` 가 ``false`` 가 됩니다. + +태그 삭제 +========= + +요청 +---- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +응답 +---- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +삭제 도중 태그가 변경된 경우 "The tag was changed by someone else. Reload it and try again." 가 됩니다. + +문서에 대한 반영 +================ + +이 API에 의한 태그의 생성·업데이트·삭제는 즉시 태그 정보에 저장됩니다. ``user.tag.enabled`` 가 ``true`` 인 동안에는 문서에 대한 변경(추가·삭제한 경로, 이름 변경, 삭제)이 큐에 들어가 1분마다 실행되는 「Log Aggregator」( ``log_aggregator`` ) 작업으로 반영됩니다. ``false`` 인 동안에는 큐에 들어가지 않으므로, 태그 기능을 활성화한 뒤 「Tag Updater」( ``tag_updater`` ) 작업을 실행하십시오. :doc:`../../admin/tagtype-guide` 를 참조하십시오. + +사용 예시 +========= + +로그인한 모든 사용자와 태그 공유 +-------------------------------- + +.. code-block:: bash + + # paths, seq_no, primary_term 을 포함해 태그를 가져오기 + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # 권한에 {role}guest 를 추가해 다시 보내기 + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +사용자의 태그 목록 조회 +----------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +참고 정보 +========= + +- :doc:`api-admin-overview` - Admin API 개요 +- :doc:`../api-tag` - 태그 API +- :doc:`../../admin/tagtype-guide` - 태그 관리 가이드 diff --git a/ko/15.9/api/admin/index.rst b/ko/15.9/api/admin/index.rst index 2d97bcce..a0932504 100644 --- a/ko/15.9/api/admin/index.rst +++ b/ko/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Admin API 레퍼런스 :caption: 검색 튜닝 api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/ko/15.9/api/api-tag.rst b/ko/15.9/api/api-tag.rst index 89bd708e..6f7850c1 100644 --- a/ko/15.9/api/api-tag.rst +++ b/ko/15.9/api/api-tag.rst @@ -2,21 +2,183 @@ 태그 API ======== -이 문서에서는 문서에 태그를 붙이는 |Fess| 의 v2 태그 API 에 대해 설명합니다. +이 문서에서는 로그인한 사용자가 자신의 태그를 관리하고 문서에 붙이는 |Fess| 의 v2 태그 API 에 대해 설명합니다. 공통 응답 엔벨로프·오류 모델·CSRF 에 대해서는 :doc:`api-overview` 를 참조하십시오. 베이스 URL은 ``http:///api/v2/`` 입니다 (로컬 환경 예: ``http://localhost:8080/api/v2`` ). .. note:: - 태그 기능은 기본적으로 비활성화되어 있습니다. 사용하려면 ``fess_config.properties`` 에서 ``user.tag.enabled=true`` 를 설정하십시오. ``/api/v2/ui/config`` 의 ``features.user_tag`` 로 상태를 확인할 수 있습니다. + 태그 기능은 기본적으로 비활성화되어 있습니다. 사용하려면 ``fess_config.properties`` 에서 ``user.tag.enabled=true`` 를 설정하십시오. ``/api/v2/ui/config`` 의 ``features.user_tag`` 로 상태를 확인할 수 있습니다. 비활성화되어 있는 동안에는 CSRF·Origin 검증을 통과하고 허용된 HTTP 메서드를 사용하는 요청에 대해 태그 API 가 ``invalid_request`` (400)를 반환합니다. -태그는 종류가 「태그」인 라벨입니다( :doc:`../admin/labeltype-guide` 참조). 라벨 이름이 태그 이름, 값이 태그 이름의 SHA-256(16진수), 대상 경로가 태그를 붙인 URL, 권한이 태그를 볼 수 있는 사용자입니다. 태그는 그 라벨이 호출자에게 보이는 경우에만 보입니다. +태그의 구조 +=========== -검색 API( ``/api/v2/search`` )는 각 히트에 호출자에게 보이는 태그를 ``tags`` 로 반환합니다. ``fields.tag=<값>`` 으로 태그가 붙은 문서로 좁힐 수 있고, ``facet.field=tag`` 로 태그 패싯을 가져올 수 있습니다. 인덱스의 ``tag`` 필드 자체는 응답에 포함되지 않습니다. +- 태그는 사용자별로 관리됩니다. 태그를 만든 사용자가 그 태그의 소유자이며, 소유자는 로그인 사용자 ID 입니다. 같은 이름의 태그라도 소유자가 다르면 별개의 태그입니다. +- 태그는 로그인한 사용자만 사용할 수 있습니다. 모든 태그 API 는 세션의 로그인 사용자로서 동작하며, 액세스 토큰은 로그인을 대신하지 않습니다. 로그인하지 않은 호출자는 ``auth_required`` (401)가 됩니다. +- 새 태그는 비공개로, 소유자만 볼 수 있습니다. 소유자가 태그를 「공유」하면 로그인한 모든 사용자가 그 태그를 보고 필터링에 사용할 수 있습니다. 로그인하지 않은 사용자에게는 공유 태그도 보이지 않습니다. +- 태그를 변경·삭제하거나 문서에 붙이고 뗄 수 있는 것은 소유자뿐입니다. 다른 사용자의 공유 태그는 표시와 필터링에만 사용할 수 있습니다. 관리자는 관리 화면에서 모든 태그를 관리할 수 있습니다( :doc:`../admin/tagtype-guide` 참조). +- 태그는 문서의 URL 에 붙습니다. 같은 URL 을 가진 인덱스상의 모든 문서에 태그가 붙습니다. -태그 가져오기 -============= +각 태그에는 다음 식별자가 있습니다. + +``value`` + 태그 값입니다. ``base64url(이름):base64url(소유자)`` (패딩 없음, UTF-8) 형식으로 인덱스의 ``tag`` 필드에 저장됩니다. 검색 결과를 좁히는 데 사용하는 불투명한 값으로 취급하십시오. + +``id`` + 태그 ID 입니다. ``value`` 의 SHA-256 을 소문자 16진수로 나타낸 64자의 문자열입니다. ``/api/v2/tags/{tagId}`` 등의 경로에 지정합니다. 이름을 변경하면 ``value`` 와 ``id`` 가 모두 바뀝니다. + +태그 이름은 NFKC 로 정규화되고, 연속된 공백은 하나로 합쳐지며, 앞뒤 공백은 제거됩니다. 정규화 후의 길이는 1 ~ ``user.tag.name.max.length`` (기본값: ``50`` )자이며, 제어 문자나 서식 문자(폭 없는 문자나 양방향 재정의 등)를 포함한 이름은 거부됩니다. + +검색에서의 이용 +=============== + +``user.tag.enabled`` 가 ``true`` 인 동안 검색 API( ``/api/v2/search`` )는 태그를 다음과 같이 다룹니다. + +- 각 히트에 호출자에게 보이는 태그를 ``tags`` 로 반환합니다. 각 요소는 ``value`` , ``name`` , ``owner`` , ``mine`` (호출자가 소유자이면 ``true`` ), ``shared`` (공유 태그이면 ``true`` )입니다. 보이는 태그가 없으면 ``tags`` 는 반환되지 않습니다. 인덱스의 ``tag`` 필드 자체는 반환되지 않습니다. +- ``facet.field=tag`` 를 지정하면 ``facet_field`` 에 호출자에게 보이는 태그만의 패싯이 반환됩니다. 각 버킷에는 ``value`` 와 ``count`` 외에 ``label`` (태그 이름), ``owner`` , ``mine`` , ``shared`` 가 붙습니다. +- ``fields.tag=`` 로 태그가 붙은 문서로 좁힐 수 있습니다. 값에는 히트의 ``tags`` 또는 패싯의 ``value`` 를 그대로 지정합니다. + +태그를 지정하는 조건( ``fields.tag`` , ``tag:`` , ``ex_q`` , ``facet.query`` )은 호출자에게 보이는 태그 값과의 완전 일치만 유효합니다. 보이지 않는 태그의 값이나 와일드카드·접두사·퍼지·범위 조건은 아무것과도 일치하지 않습니다. 로그인하지 않은 호출자에게는 태그도 태그 패싯도 반환되지 않으며, 태그 조건은 아무것과도 일치하지 않습니다. + +한 사용자에게 보이는 태그는 자신의 태그를 우선하여 최대 ``user.tag.visible.max.size`` (기본값: ``1000`` )개입니다. 이를 넘는 태그는 히트의 ``tags`` 와 패싯에 나타나지 않습니다(필터링에는 사용할 수 있습니다). + +문서에 대한 반영 +================ + +태그의 생성·변경·삭제와 문서에 대한 붙이기·떼기는 태그 API 에 즉시 반영됩니다. 한편 인덱스 문서의 ``tag`` 필드는 변경을 메모리상의 큐에 넣고, 1분마다 실행되는 「Log Aggregator」( ``log_aggregator`` ) 작업이 일괄로 갱신합니다. 따라서 검색 결과의 히트나 패싯, 필터링에 반영되기까지 최대 1분 정도 걸립니다. 이름을 변경한 태그는 다음에 큐가 처리될 때까지 문서상의 이전 값이 보이지 않으므로 검색 결과에 표시되지 않습니다. + +큐의 취급과 작업에 대해서는 :doc:`../admin/tagtype-guide` 를 참조하십시오. + +태그 목록 가져오기 +================== + +요청 +---- + +================== ==================================================== +HTTP 메서드 GET +엔드포인트 ``/api/v2/tags`` +================== ==================================================== + +호출자가 소유한 태그를 표시 순서와 이름 순으로 반환합니다. 다른 사용자의 공유 태그는 포함되지 않습니다. + +응답 +---- + +성공 시(200)에는 공통 엔벨로프의 ``response`` 바로 아래에 다음 필드가 반환됩니다. + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "a75185a5b3226fe910c69a7892e51a2ce3fb6beecaeaa7de18a277f045cc23a0", + "value": "6rKA7YagIO2VhOyalA:bWluc3U", + "name": "검토 필요", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: 응답 필드 + + * - ``tags`` + - 호출자의 태그 배열. 각 요소는 ``id`` , ``value`` , ``name`` , ``shared`` (공유 태그이면 ``true`` ), ``sort_order`` (표시 순서), ``path_count`` (태그를 붙인 URL 의 수). + +표: 응답 필드 + +태그 생성 +========= + +요청 +---- + +================== ==================================================== +HTTP 메서드 POST +엔드포인트 ``/api/v2/tags`` +================== ==================================================== + +호출자의 태그를 생성합니다. 상태를 변경하는 요청이므로 ``X-Fess-CSRF-Token`` 헤더가 필요합니다( :doc:`api-overview` 참조). + +- 한 사용자가 가질 수 있는 태그는 최대 ``user.tag.max.tags`` (기본값: ``1000`` )개입니다. 초과하면 ``invalid_request`` (400)가 됩니다. +- 호출자가 같은 이름의 태그를 이미 가지고 있으면 ``conflict`` (409)가 됩니다. 다른 사용자가 같은 이름의 태그를 가지고 있어도 생성할 수 있습니다. + +요청 본문은 ``Content-Type: application/json`` 이며, 최대 크기는 1 KiB(1024 바이트)입니다. + +:: + + { + "name": "검토 필요", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: 요청 본문 + + * - ``name`` + - 태그 이름(str, 필수). + * - ``shared`` + - ``true`` 로 하면 로그인한 모든 사용자가 태그를 볼 수 있습니다(bool, 기본값: ``false`` ). + +표: 요청 본문 + +응답 +---- + +성공 시(200)에는 ``response`` 바로 아래의 ``tag`` 에 생성한 태그( ``GET /api/v2/tags`` 의 요소와 같은 형식, ``path_count`` 는 ``0`` )가 반환됩니다. + +태그 변경 +========= + +요청 +---- + +================== ==================================================== +HTTP 메서드 PUT +엔드포인트 ``/api/v2/tags/{tagId}`` +================== ==================================================== + +호출자의 태그 이름 변경과 공유 전환을 수행합니다. ``X-Fess-CSRF-Token`` 헤더가 필요합니다. + +- 요청 본문에는 ``name`` 과 ``shared`` 중 적어도 하나를 지정합니다. +- ``name`` 으로 이름을 변경하면 태그의 ``id`` 와 ``value`` 가 새로워집니다. 이전 값을 가진 문서는 다음에 큐가 처리될 때 새 값으로 바뀝니다. 호출자가 이미 사용 중인 이름으로 변경하려 하면 ``conflict`` (409)가 되며 태그는 변경되지 않습니다. +- ``shared`` 는 태그를 볼 수 있는 사용자만 바꿉니다. 문서 갱신은 필요하지 않습니다. ``shared`` 를 ``false`` 로 해도 관리자가 권한에 추가한 역할이나 그룹은 그대로 남습니다. +- 다른 사용자의 공유 태그는 ``forbidden`` (403), 호출자에게 보이지 않는 태그는 ``not_found`` (404)가 됩니다. +- 다른 갱신과 경합하여 쓰기에 반복해서 실패한 경우에도 ``conflict`` (409)가 됩니다. + +:: + + { + "name": "검토 완료", + "shared": true + } + +성공 시(200)에는 ``response`` 바로 아래에 ``tag`` (변경 후의 태그)와 ``renamed`` (이름을 변경한 경우 ``true`` . 이때 ``tag.id`` 와 ``tag.value`` 는 새 값)가 반환됩니다. + +태그 삭제 +========= + +요청 +---- + +================== ==================================================== +HTTP 메서드 DELETE +엔드포인트 ``/api/v2/tags/{tagId}`` +================== ==================================================== + +호출자의 태그를 삭제합니다. 문서에서는 다음에 큐가 처리될 때 태그 값이 제거됩니다. ``X-Fess-CSRF-Token`` 헤더가 필요합니다. 다른 사용자의 공유 태그는 ``forbidden`` (403), 호출자에게 보이지 않는 태그는 ``not_found`` (404)가 됩니다. + +성공 시(200)에는 ``response`` 바로 아래에 ``id`` (삭제한 태그 ID)와 ``deleted`` (항상 ``true`` )가 반환됩니다. + +문서의 태그 가져오기 +==================== 요청 ---- @@ -26,7 +188,7 @@ HTTP 메서드 GET 엔드포인트 ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -지정한 문서의 태그 중 호출자에게 보이는 것을 반환합니다. 호출자가 그 문서를 검색할 수 없는 경우 ``not_found`` (404)가 됩니다. +문서의 URL 에 붙은 태그 중 호출자에게 보이는 것과, 아직 붙지 않은 호출자의 태그를 반환합니다. 문서는 호출자의 역할로 검색되므로 호출자가 검색할 수 없는 문서는 ``not_found`` (404)가 됩니다. 응답 ---- @@ -39,10 +201,25 @@ HTTP 메서드 GET "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "검토 필요", "mine": true } - ] + { + "id": "a75185a5b3226fe910c69a7892e51a2ce3fb6beecaeaa7de18a277f045cc23a0", + "value": "6rKA7YagIO2VhOyalA:bWluc3U", + "name": "검토 필요", + "owner": "minsu", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -51,19 +228,21 @@ HTTP 메서드 GET * - ``doc_id`` - 문서 ID(str). + * - ``tags`` + - 문서의 URL 에 붙은 태그 중 호출자에게 보이는 것의 배열. 각 요소는 ``id`` , ``value`` , ``name`` , ``owner`` (소유자), ``mine`` (호출자가 소유자이면 ``true`` ), ``shared`` (공유 태그이면 ``true`` ). * - ``addable`` - - 호출자가 로그인하여 태그를 추가할 수 있는 경우 ``true`` (bool). + - 문서의 URL 에 아직 붙지 않은 호출자의 태그 배열(요소의 형식은 ``tags`` 와 같음). * - ``added`` - - POST 만. 호출자가 이미 그 문서에 태그를 붙인 경우 ``false`` (bool). + - POST 만. 태그가 이미 붙어 있던 경우 ``false`` (bool). + * - ``tag`` + - POST 만. 문서에 붙인 태그(요소의 형식은 ``tags`` 와 같음). * - ``removed`` - - DELETE 만(bool). - * - ``tags`` - - 호출자에게 보이는 태그의 배열. 각 요소는 ``value`` (라벨 값. ``fields.tag`` 에 지정하는 값), ``name`` (태그 이름), ``mine`` (호출자가 태그 권한에 포함된 경우 ``true`` ). + - DELETE 만. 태그가 붙어 있지 않았던 경우 ``false`` (bool). 표: 응답 필드 -태그 추가 -========= +문서에 태그 추가 +================ 요청 ---- @@ -73,13 +252,9 @@ HTTP 메서드 POST 엔드포인트 ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -로그인한 사용자로서 문서의 URL 에 태그를 붙입니다. 액세스 토큰은 로그인을 대신하지 않습니다. 상태를 변경하는 요청이므로 ``X-Fess-CSRF-Token`` 헤더가 필요합니다. +문서의 URL 을 호출자의 태그에 추가합니다. ``X-Fess-CSRF-Token`` 헤더가 필요합니다. -- 같은 이름의 태그가 있으면 그 대상 경로에 URL 을, 권한에 사용자를 추가합니다. 없으면 그 사용자만 볼 수 있는 태그를 만듭니다. 따라서 같은 이름의 태그는 하나로 합쳐지며, 같은 이름의 태그를 붙인 사용자끼리는 서로의 태그가 붙은 곳을 볼 수 있습니다. -- 같은 문서에 다시 붙이면 ``added`` 는 ``false`` 가 됩니다. -- 문서 하나에 붙일 수 있는 태그는 최대 ``user.tag.max.document.tags`` (기본값: ``100`` )개입니다. - -요청 본문은 ``Content-Type: application/json`` 이며, ``name`` 에 태그 이름을 지정합니다. +요청 본문( ``Content-Type: application/json`` , 최대 1 KiB)에서는 ``id`` 로 기존 태그를 지정하거나 ``name`` 으로 태그 이름을 지정합니다. 둘 다 지정한 경우 ``id`` 가 우선합니다. :: @@ -87,44 +262,85 @@ HTTP 메서드 POST "name": "검토 필요" } -태그 이름은 NFKC 로 정규화되고, 연속된 공백은 하나로 합쳐지며, 앞뒤 공백은 제거됩니다. 길이는 1〜 ``user.tag.name.max.length`` (기본값: ``50`` )자이며, 제어 문자나 서식 문자(폭이 0인 문자나 양방향 재정의 등)를 포함한 이름은 거부됩니다. +- ``name`` 을 지정했는데 호출자가 그 이름의 태그를 가지고 있지 않으면, 비공개 태그를 생성하여 붙입니다. 생성한 태그는 ``user.tag.max.tags`` 에 포함됩니다. +- 하나의 태그를 붙일 수 있는 URL 은 최대 ``user.tag.max.paths`` (기본값: ``10000`` )개입니다. 초과하면 ``invalid_request`` (400)가 됩니다. +- 다른 사용자의 태그를 ``id`` 로 지정하면, 그 태그가 보이는 경우 ``forbidden`` (403), 보이지 않는 경우 ``not_found`` (404)가 됩니다. +- 성공 시에는 문서의 태그 가져오기와 같은 필드에 ``added`` 와 ``tag`` 를 더해 반환합니다. 태그는 API 상에서는 즉시 붙지만, 그 URL 의 문서 검색 결과에 반영되는 것은 다음에 큐가 처리될 때(1분 정도 후)입니다. -태그 삭제 -========= +문서에서 태그 제거 +================== 요청 ---- ================== ==================================================== HTTP 메서드 DELETE -엔드포인트 ``/api/v2/documents/{docId}/tags?value=<태그 값>`` +엔드포인트 ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -로그인한 사용자를 ``value`` 로 지정한 태그의 권한에서 제외합니다. 사용자, 그룹, 역할의 권한이 하나도 남지 않으면 태그는 삭제되고 문서에서도 제거됩니다. 사용자가 태그의 권한에 포함되어 있지 않으면 ``forbidden`` (403)이 됩니다. ``X-Fess-CSRF-Token`` 헤더가 필요합니다. +문서의 URL 을 ``tagId`` 로 지정한 호출자의 태그에서 제거합니다. ``X-Fess-CSRF-Token`` 헤더가 필요합니다. 다른 사용자의 태그는 보이는 경우 ``forbidden`` (403), 보이지 않는 경우 ``not_found`` (404)가 됩니다. 성공 시에는 문서의 태그 가져오기와 같은 필드에 ``removed`` 를 더해 반환합니다. 오류 응답 ========= +오류 모델의 자세한 내용은 :doc:`api-overview` 를 참조하십시오. 태그 API 가 반환하는 HTTP 상태는 다음과 같습니다. + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: 오류 응답 * - 상태 코드 - 설명 * - 400 Bad Request - - 요청이 잘못된 경우(태그 기능이 비활성화된 경우, 태그 이름이 잘못된 경우, 태그 상한을 초과한 경우 포함). + - 요청이 올바르지 않은 경우. 태그 기능이 비활성화된 경우, 태그 이름이 올바르지 않은 경우, 필수 항목이 없는 경우, ``user.tag.max.tags`` 나 ``user.tag.max.paths`` 의 상한을 넘는 경우를 포함합니다. * - 401 Unauthorized - - POST・DELETE 에서 로그인하지 않은 경우. + - 로그인하지 않은 경우(액세스 토큰은 로그인을 대신하지 않습니다). * - 403 Forbidden - - CSRF 토큰의 누락・만료, 또는 자신이 추가하지 않은 태그를 DELETE 한 경우. + - CSRF 토큰이 없거나 만료된 경우, 또는 다른 사용자의 태그를 변경하려 한 경우. CSRF 검증은 로그인 확인보다 먼저 이루어지므로, 세션이 없는 상태 변경 요청은 401 이 아니라 403 이 됩니다. * - 404 Not Found - - 문서를 찾을 수 없거나 호출자가 검색할 수 없는 경우. + - 태그가 존재하지 않거나 호출자에게 보이지 않는 경우, 또는 문서를 찾을 수 없거나 호출자가 검색할 수 없는 경우. * - 405 Method Not Allowed - HTTP 메서드가 허용되지 않는 경우. + * - 409 Conflict + - 같은 이름의 태그가 이미 있는 경우, 또는 다른 갱신과 경합하여 쓸 수 없었던 경우. * - 413 Payload Too Large - - 요청 본문이 크기 상한을 초과한 경우. + - 요청 본문이 크기 상한(1 KiB)을 넘은 경우. * - 415 Unsupported Media Type - 지원되지 않는 ``Content-Type`` 인 경우. * - 500 Internal Server Error - 서버 내부 오류가 발생한 경우. 표: 오류 응답 + +설정 +==== + +``fess_config.properties`` 의 다음 설정으로 태그 기능을 조정할 수 있습니다. + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - 속성 + - 설명 + - 기본값 + * - ``user.tag.enabled`` + - 로그인한 사용자가 태그를 사용할 수 있는지 여부. + - ``false`` + * - ``user.tag.name.max.length`` + - 태그 이름의 최대 길이(코드 포인트 수). + - ``50`` + * - ``user.tag.max.tags`` + - 한 사용자가 가질 수 있는 태그의 최대 수. + - ``1000`` + * - ``user.tag.max.paths`` + - 하나의 태그를 붙일 수 있는 URL 의 최대 수. + - ``10000`` + * - ``user.tag.queue.max.size`` + - 문서에 반영될 때까지 메모리에 보관하는 변경의 최대 수. 초과한 변경은 버려지고 WARN 로그가 출력됩니다. + - ``10000`` + * - ``user.tag.process.batch.size`` + - 변경을 문서에 반영할 때 한 번의 벌크 요청으로 갱신하는 URL 의 수. + - ``100`` + * - ``user.tag.visible.max.size`` + - 검색에서 한 사용자에게 보이는 태그의 최대 수. + - ``1000`` diff --git a/ko/15.9/api/api-uiconfig.rst b/ko/15.9/api/api-uiconfig.rst index a215b0ea..5ee20cff 100644 --- a/ko/15.9/api/api-uiconfig.rst +++ b/ko/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ features - 검색 결과 내보내기( ``GET /api/v2/documents/export`` )가 활성화되어 있는지 여부( ``api.search.export`` ). * - ``user_tag`` - boolean - - 태그 기능( ``/api/v2/documents/{docId}/tags`` )이 활성화되어 있는지 여부( ``user.tag.enabled`` ). + - 사용자별 태그가 활성화되어 있는지 여부( ``user.tag.enabled`` ). 활성화되어 있으면 태그 엔드포인트( ``/api/v2/tags`` , ``/api/v2/documents/{docId}/tags`` )가 응답하고 검색 히트에 ``tags`` 가 포함됩니다. * - ``popular_word`` - boolean - 인기 검색어 기능이 활성화되어 있는지 여부. diff --git a/ko/15.9/config/properties.po b/ko/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/ko/15.9/config/properties.po +++ b/ko/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/ko/15.9/config/properties.rst b/ko/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/ko/15.9/config/properties.rst +++ b/ko/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100`` diff --git a/zh-cn/15.9/admin/index.rst b/zh-cn/15.9/admin/index.rst index 20e15d39..e43f2a27 100644 --- a/zh-cn/15.9/admin/index.rst +++ b/zh-cn/15.9/admin/index.rst @@ -27,6 +27,7 @@ fileconfig-guide dataconfig-guide labeltype-guide + tagtype-guide keymatch-guide boostdoc-guide relatedcontent-guide diff --git a/zh-cn/15.9/admin/labeltype-guide.rst b/zh-cn/15.9/admin/labeltype-guide.rst index 1e59f06d..b3665933 100644 --- a/zh-cn/15.9/admin/labeltype-guide.rst +++ b/zh-cn/15.9/admin/labeltype-guide.rst @@ -85,31 +85,11 @@ 指定标签的排序顺序。 -类型 -:::: - -指定“标签”或“用户标签”。普通标签为“标签”。“用户标签”是用户在搜索页面添加的标签(请参阅下面的“用户标签”)。未指定类型的现有标签按“标签”处理。 - - 删除配置 -------- 点击列表页面中的配置名称,然后点击删除按钮,将显示确认画面。 点击删除按钮将删除配置。 -用户标签 --------- - -在 ``fess_config.properties`` 中设置 ``user.tag.enabled=true`` (默认值: ``false`` )后,已登录的用户可以为搜索结果添加用户标签。在内置的 ``bootstrap`` 主题中,结果上会显示用户标签,用户可以添加用户标签并删除自己添加的用户标签,还可以通过“用户标签”分面缩小结果。关于 API,请参阅 :doc:`../api/api-tag`\ 。 - -用户标签以类型为“用户标签”的标签保存。名称为用户标签名,值为名称的 SHA-256,包含的路径为添加了用户标签的 URL(每行一个,完全匹配),权限决定谁可以查看该用户标签。添加用户标签的用户会被加入其权限中。 - -- 只有当标签的权限与调用者匹配时,用户标签才可见。管理员可以在此页面编辑用户标签,将其与角色或组共享,或将其删除。 -- 同名的用户标签会合并为一个标签。因此,添加了同名用户标签的用户之间可以看到彼此的用户标签添加在哪里。 -- 用户标签不包含在标签列表 API( ``/api/v2/labels`` )和搜索页面的标签选项中。 -- 用户标签计入标签数量上限( ``page.labeltype.max.fetch.size``\ ,默认值:1000)。达到上限后无法创建新的用户标签。 -- 管理员在此页面更改或删除用户标签后,索引中的文档在重新爬取或运行“Label Updater”作业之前仍保留以前的值。 -- 一个文档最多可以有 ``user.tag.max.document.tags`` (默认值:100)个用户标签,用户标签名最长为 ``user.tag.name.max.length`` (默认值:50)个字符。 - .. |image0| image:: ../../../resources/images/en/15.9/admin/labeltype-1.png .. |image1| image:: ../../../resources/images/en/15.9/admin/labeltype-2.png diff --git a/zh-cn/15.9/admin/tagtype-guide.rst b/zh-cn/15.9/admin/tagtype-guide.rst new file mode 100644 index 00000000..8a70ff19 --- /dev/null +++ b/zh-cn/15.9/admin/tagtype-guide.rst @@ -0,0 +1,99 @@ +======== +用户标签 +======== + +概述 +==== + +本节介绍管理用户的用户标签的界面。 + +用户标签是已登录的用户添加到搜索结果中文档上的标记。用户标签按用户管理,创建用户标签的用户是其所有者。即使名称相同,所有者不同的用户标签也是不同的用户标签。用户标签与管理员通过 URL 模式定义的 :doc:`标签 ` 不同,由用户自己创建并添加到各个文档上。 + +用户标签功能默认禁用。要使用此功能,请在 ``fess_config.properties`` 中设置 ``user.tag.enabled=true`` 。启用后,在内置的 ``bootstrap`` 主题中,已登录的用户可以为搜索结果添加或移除用户标签,并通过用户标签的分面进行筛选。在“我的标签”中可以重命名、共享和删除自己的用户标签。其他用户的共享用户标签会带有“共享:”前缀显示。关于面向用户的 API 和设置,请参阅 :doc:`../api/api-tag` 。 + +在此界面中,管理员可以列出、创建、编辑和删除所有用户的用户标签。 + +管理方法 +======== + +显示方法 +-------- + +要打开用户标签列表页面,请点击左侧菜单中的 [爬虫 > 用户标签]。查看需要 ``admin-tagtype`` 或 ``admin-tagtype-view`` 角色,创建、编辑和删除需要 ``admin-tagtype`` 角色。 + +列表按排序顺序、名称、所有者的顺序显示每个用户标签的名称和所有者。可以按名称和所有者搜索,两者都匹配包含所输入字符串的用户标签。 + +点击名称进行编辑。 + +创建配置 +-------- + +要打开用户标签创建页面,请点击新建按钮。 + +配置项 +------ + +名称 +:::: + +指定用户标签名称。名称会经过 NFKC 规范化,连续的空白合并为一个空格,并去除首尾的空白。规范化后的长度必须为 1 ~ ``user.tag.name.max.length`` (默认:50)个字符,不能包含控制字符或格式字符。 + +所有者 +:::::: + +指定拥有该用户标签的用户的登录用户 ID。所有者和名称的组合在用户标签中是唯一的,同一所有者不能拥有两个同名的用户标签(即使虚拟主机不同也是如此)。 + +更改所有者后,权限中原所有者的用户权限会替换为新所有者的用户权限。 + +路径 +:::: + +逐行指定要添加用户标签的文档的 URL。与索引中文档的 ``url`` 字段进行完全一致的比对,不使用正则表达式。最多可以指定 ``user.tag.max.paths`` (默认:10000)个 URL。 + +权限 +:::: + +指定可以查看该用户标签的用户、组和角色。指定方法与标签相同:按用户指定为 {user}用户名,按组指定为 {group}组名,按角色指定为 {role}角色名。留空保存时,只有所有者可以查看该用户标签。 + +无论权限如何,所有者始终可以看到自己的用户标签。无论权限如何,未登录的用户都看不到用户标签。 + +虚拟主机 +:::::::: + +指定显示该用户标签的虚拟主机的主机名。用户创建用户标签时,会填入当时访问的虚拟主机。通过虚拟主机访问的检索界面中,只显示在此项中指定了该虚拟主机名的用户标签。在不匹配任何虚拟主机的访问中,无论此项如何,都会显示用户标签。详细信息请参阅 :doc:`配置指南的虚拟主机 <../config/security-virtual-host>` 。 + +排序顺序 +:::::::: + +指定用户标签的排序顺序。 + +删除配置 +-------- + +点击列表页面中的名称,然后点击删除按钮,将显示确认画面。点击删除按钮将删除该用户标签,并从文档中移除其值。 + +共享 +==== + +用户将用户标签设为“共享”后, ``role.search.guest.permissions`` 的值(默认: ``{role}guest`` )会被添加到其权限中。判断用户标签是否可见时,会在已登录用户的角色上加上这些值,因此共享的用户标签对所有已登录的用户可见,并可用于筛选。取消共享时只移除这些值。 + +管理员也可以在此界面中为权限添加组或角色,使用户标签只对特定用户可见。但只有所有者和管理员可以更改用户标签,其他用户只能用可见的用户标签进行显示和筛选。 + +反映到文档 +========== + +文档的用户标签以 ``base64url(名称):base64url(所有者)`` 的格式存储在索引的 ``tag`` 字段中。 + +- 用户标签的创建、编辑、删除以及用户添加和移除用户标签的操作,会立即保存到用户标签信息( ``fess_config.tag_type`` 索引)中。文档的更新则是先将更改放入内存中的队列,再由每分钟运行一次的“Log Aggregator”( ``log_aggregator`` )作业批量执行。因此,搜索结果最多需要约 1 分钟才能反映更改。 +- 在此界面中更改路径时,只会更新新增和移除的 URL 对应的文档。更改名称或所有者时,带有旧值的文档会替换为新值。 +- 通过爬虫或数据存储为文档建立索引时,会与用户标签的路径进行比对并设置 ``tag`` 字段。因此,重新爬取后用户标签也不会丢失。 +- “Tag Updater”( ``tag_updater`` )作业会根据用户标签信息重新生成所有文档的 ``tag`` 字段。该作业没有设置计划,需要时请从调度器手动执行。 + +运维注意事项 +============ + +- **请在所有节点上运行 Log Aggregator。** 每个 JVM 都有自己的队列,只由该节点的 Log Aggregator 处理。请将 ``log_aggregator`` 作业的目标( ``target`` )保持为默认值 ``all`` 。如果限定为特定节点,其他节点接收的更改将不会反映到文档中。 +- **在以下情况下请运行 Tag Updater。** 队列位于内存中,因此尚未反映的更改会在 |Fess| 重启时丢失。在 ``user.tag.enabled=false`` 期间,用户标签的更改不会反映到文档中,重新爬取会清除文档的 ``tag`` 字段。从备份恢复后,也需要重新生成文档的用户标签。另外,当队列超过 ``user.tag.queue.max.size`` (默认:10000)时,超出的更改会被丢弃并输出 WARN 日志。在上述任何情况下,运行 ``tag_updater`` 都会重新生成文档的用户标签。 +- **用户标签的所有者是登录用户 ID。** 用户 ID 改变后,该用户的用户标签仍保留在原 ID 下。使用 SAML 时,NameID 必须为持久(persistent)格式。使用 Entra ID 时所有者为 UPN,使用 LDAP 时所有者为登录时输入的、保留大小写的用户名。删除用户后,其用户标签仍会保留,请在此界面中删除不再需要的用户标签。 +- **现有索引也可以使用。** 启动时,如果文档索引中没有 ``tag`` 字段的映射,会以 ``keyword`` 类型添加。现有字段不会被更改。 +- 用户标签信息存储在 ``fess_config.tag_type`` 索引中。它包含在备份的 ``fess_config.bulk`` 中,但不包含在 ``fess_basic_config.bulk`` 中。 diff --git a/zh-cn/15.9/api/admin/api-admin-overview.rst b/zh-cn/15.9/api/admin/api-admin-overview.rst index 56209933..684abea2 100644 --- a/zh-cn/15.9/api/admin/api-admin-overview.rst +++ b/zh-cn/15.9/api/admin/api-admin-overview.rst @@ -449,6 +449,8 @@ Admin API在大多数情况下返回 HTTP 状态 ``200``,处理结果通过响 - 说明 * - :doc:`api-admin-labeltype` - 标签类型 + * - :doc:`api-admin-tagtype` + - 用户标签 * - :doc:`api-admin-keymatch` - 关键词匹配 * - :doc:`api-admin-boostdoc` diff --git a/zh-cn/15.9/api/admin/api-admin-tagtype.rst b/zh-cn/15.9/api/admin/api-admin-tagtype.rst new file mode 100644 index 00000000..e4a5c5f4 --- /dev/null +++ b/zh-cn/15.9/api/admin/api-admin-tagtype.rst @@ -0,0 +1,368 @@ +=========== +TagType API +=========== + +概述 +==== + +TagType API 是用于管理 |Fess| 用户标签(已登录的用户添加到文档上的、按用户管理的用户标签)的 API(请参阅 :doc:`../../admin/tagtype-guide` )。无论 ``user.tag.enabled`` 的值如何,都可以管理所有用户的用户标签。 + +关于认证方式及响应的通用规范(``status`` 状态码、``version`` 字段、错误格式、 +HTTP状态码等),请参阅 :doc:`api-admin-overview`。 +访问本API需要使用具有管理API权限(``admin-api``)的访问令牌, +并通过 ``Authorization: Bearer <访问令牌>`` 请求头指定。 + +本 API 的 JSON 字段名为蛇形命名( ``sort_order`` 、 ``virtual_host`` 、 ``seq_no`` 、 ``primary_term`` 等)。 + +基础 URL +======== + +:: + + /api/admin/tagtype + +端点列表 +======== + +.. list-table:: + :header-rows: 1 + :widths: 15 35 50 + + * - 方法 + - 路径 + - 说明 + * - GET + - /settings + - 获取用户标签列表 + * - GET + - /setting/{id} + - 获取用户标签 + * - POST + - /setting + - 创建用户标签 + * - PUT + - /setting + - 更新用户标签 + * - DELETE + - /setting/{id} + - 删除用户标签 + +获取用户标签列表 +================ + +请求 +---- + +:: + + GET /api/admin/tagtype/settings + +参数 +~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - 参数 + - 类型 + - 必填 + - 说明 + * - ``size`` + - Integer + - 否 + - 每页条数。默认为 ``paging.page.size`` 的设置值(默认 ``25`` )。 + * - ``page`` + - Integer + - 否 + - 页码(从 1 开始)。默认为 ``1`` 。 + * - ``name`` + - String + - 否 + - 按名称筛选(通配符搜索,匹配包含所输入字符串的名称)。 + * - ``owner`` + - String + - 否 + - 按所有者筛选(通配符搜索,匹配包含所输入字符串的所有者)。 + +用户标签按排序顺序、名称、所有者排序。 + +响应 +---- + +.. code-block:: json + + { + "response": { + "version": "15.9.0", + "status": 0, + "settings": [ + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + ], + "total": 5 + } + } + +.. note:: + + 列表不读取可能很长的用户标签路径,因此各元素没有 ``paths`` 。PUT 会整体替换用户标签,因此编辑前请先通过 ``GET /setting/{id}`` 获取,以保留其 ``paths`` 。 + +获取用户标签 +============ + +请求 +---- + +:: + + GET /api/admin/tagtype/setting/{id} + +响应 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "setting": { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + } + } + +``seq_no`` 和 ``primary_term`` 表示读取到的用户标签的版本。 ``paths`` 和 ``permissions`` 每行一个值。 + +创建用户标签 +============ + +请求 +---- + +:: + + POST /api/admin/tagtype/setting + Content-Type: application/json + +请求体 +~~~~~~ + +.. code-block:: json + + { + "name": "specs", + "owner": "bob", + "paths": "https://www.example.com/spec.pdf", + "permissions": "{user}bob\n{role}guest", + "sort_order": 0 + } + +字段说明 +~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - 字段 + - 类型 + - 必填 + - 说明 + * - ``name`` + - String + - 是 + - 用户标签名称。会经过 NFKC 规范化,连续的空白合并为一个空格,并去除首尾空白;规范化后的长度必须为 1 ~ ``user.tag.name.max.length`` (默认: ``50`` )个字符,且不能包含控制字符或格式字符。 + * - ``owner`` + - String + - 是 + - 拥有该用户标签的用户的登录用户 ID(最多 1000 个字符)。 + * - ``paths`` + - String + - 否 + - 要添加用户标签的文档的 URL,多个时用换行符( ``\n`` )分隔。每个都必须与文档的 ``url`` 字段完全一致。最多 ``user.tag.max.paths`` (默认: ``10000`` )个。 + * - ``permissions`` + - String + - 否 + - 可以查看该用户标签的用户/组/角色(例如 ``{role}guest`` ),多个时用换行符( ``\n`` )分隔。为空时只有所有者可以查看。包含 ``{role}guest`` ( ``role.search.guest.permissions`` 的值)时,会与所有已登录的用户共享。 + * - ``virtual_host`` + - String + - 否 + - 虚拟主机(最多 1000 个字符)。 + * - ``sort_order`` + - Integer + - 否 + - 显示顺序(非负整数)。省略时为 ``0`` 。 + +用户标签的 ID 是由名称和所有者生成的用户标签值的 SHA-256,由服务器决定。所有者和名称的组合用于识别用户标签,因此所有者已有同名用户标签时,会返回验证错误( ``status: 1`` ,“A tag with the same name and owner already exists.”)。 + +响应 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "created": true + } + } + +创建成功时, ``created`` 为 ``true`` 。 + +更新用户标签 +============ + +请求 +---- + +:: + + PUT /api/admin/tagtype/setting + Content-Type: application/json + +请求体 +~~~~~~ + +.. code-block:: json + + { + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "reviewed", + "owner": "alice", + "paths": "https://www.example.com/a.html", + "permissions": "{user}alice", + "virtual_host": "", + "sort_order": 0 + } + +除创建时的所有字段外,还需要以下字段。用户标签会被整体替换,因此请同时发送要保留的 ``paths`` 。 + +.. list-table:: + :header-rows: 1 + :widths: 20 12 12 56 + + * - 字段 + - 类型 + - 必填 + - 说明 + * - ``id`` + - String + - 是 + - 要更新的用户标签的 ID。 + * - ``seq_no`` + - Integer + - 是 + - ``GET /setting/{id}`` 返回的用户标签的 ``seq_no`` 。 + * - ``primary_term`` + - Integer + - 是 + - ``GET /setting/{id}`` 返回的用户标签的 ``primary_term`` 。 + +- 如果读取后用户标签已被更改,即 ``seq_no`` 和 ``primary_term`` 不再一致,更新会返回验证错误( ``status: 1`` ,“The tag was changed by someone else. Reload it and try again.”)。请重新获取用户标签后再试。 +- 更改 ``name`` 或 ``owner`` 后,用户标签会获得新的 ID,响应中的 ``id`` 为新 ID。所有者已有新名称的用户标签时,更新会返回“A tag with the same name and owner already exists.”。 +- 更改所有者后, ``permissions`` 中原所有者的用户权限会替换为新所有者的用户权限。 + +响应 +---- + +.. code-block:: json + + { + "response": { + "status": 0, + "id": "c1fd8e024cbadfc79468e66fa52350e46cc31837aabf75b7ee6d929edaa20396", + "created": false + } + } + +更新时, ``created`` 为 ``false`` 。 + +删除用户标签 +============ + +请求 +---- + +:: + + DELETE /api/admin/tagtype/setting/{id} + +响应 +---- + +.. code-block:: json + + { + "response": { + "status": 0 + } + } + +如果在删除过程中用户标签被更改,删除会返回“The tag was changed by someone else. Reload it and try again.”。 + +反映到文档 +========== + +通过本 API 创建、更新和删除用户标签时,会立即保存到用户标签信息中。在 ``user.tag.enabled`` 为 ``true`` 期间,对文档的更改(新增和移除的路径、重命名、删除)会放入队列,由每分钟运行一次的“Log Aggregator”( ``log_aggregator`` )作业反映。为 ``false`` 期间不会放入队列,请在启用用户标签功能后运行“Tag Updater”( ``tag_updater`` )作业。请参阅 :doc:`../../admin/tagtype-guide` 。 + +使用示例 +======== + +与所有已登录的用户共享用户标签 +------------------------------ + +.. code-block:: bash + + # 获取包含 paths、seq_no、primary_term 的用户标签 + curl "http://localhost:8080/api/admin/tagtype/setting/0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c" \ + -H "Authorization: Bearer YOUR_TOKEN" + + # 在权限中加上 {role}guest 后发回 + curl -X PUT "http://localhost:8080/api/admin/tagtype/setting" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "id": "0698e7f9c98a9b64ef11a2bbc71d8d2668c6907b397fa86c23ba19b7fec02d6c", + "seq_no": 12, + "primary_term": 1, + "name": "to-review", + "owner": "alice", + "paths": "https://www.example.com/a.html\nhttps://www.example.com/b.html", + "permissions": "{user}alice\n{role}guest", + "sort_order": 0 + }' + +获取某个用户的用户标签列表 +-------------------------- + +.. code-block:: bash + + curl "http://localhost:8080/api/admin/tagtype/settings?owner=alice&size=50&page=1" \ + -H "Authorization: Bearer YOUR_TOKEN" + +参考信息 +======== + +- :doc:`api-admin-overview` - Admin API概述 +- :doc:`../api-tag` - 用户标签 API +- :doc:`../../admin/tagtype-guide` - 用户标签管理指南 diff --git a/zh-cn/15.9/api/admin/index.rst b/zh-cn/15.9/api/admin/index.rst index 30b46349..cc9697e0 100644 --- a/zh-cn/15.9/api/admin/index.rst +++ b/zh-cn/15.9/api/admin/index.rst @@ -48,6 +48,7 @@ Admin API 参考手册 :caption: 搜索调优 api-admin-labeltype + api-admin-tagtype api-admin-keymatch api-admin-boostdoc api-admin-elevateword diff --git a/zh-cn/15.9/api/api-tag.rst b/zh-cn/15.9/api/api-tag.rst index 4c449bb2..32f2918c 100644 --- a/zh-cn/15.9/api/api-tag.rst +++ b/zh-cn/15.9/api/api-tag.rst @@ -2,30 +2,192 @@ 用户标签 API ============ -本文档介绍为文档添加用户标签的 |Fess| v2 用户标签 API。公共响应信封、错误模型及 CSRF 相关内容,请参阅 :doc:`api-overview`\ 。 +本文档介绍 |Fess| 的 v2 用户标签 API,已登录的用户可以通过它管理自己的用户标签并将其添加到文档。公共响应信封、错误模型及 CSRF 相关内容,请参阅 :doc:`api-overview` 。 -基础 URL 为 ``http:///api/v2/``\ (本地环境示例:\ ``http://localhost:8080/api/v2``\ )。 +基础 URL 为 ``http:///api/v2/`` (本地环境示例: ``http://localhost:8080/api/v2`` )。 .. note:: - 用户标签功能默认禁用。要使用此功能,请在 ``fess_config.properties`` 中设置 ``user.tag.enabled=true``\ 。可以通过 ``/api/v2/ui/config`` 的 ``features.user_tag`` 确认其状态。 + 用户标签功能默认禁用。要使用此功能,请在 ``fess_config.properties`` 中设置 ``user.tag.enabled=true`` 。可以通过 ``/api/v2/ui/config`` 的 ``features.user_tag`` 确认其状态。禁用期间,对于通过 CSRF 和 Origin 验证并使用受支持的 HTTP 方法的请求,用户标签 API 返回 ``invalid_request`` (400)。 -用户标签是类型为“用户标签”的标签(请参阅 :doc:`../admin/labeltype-guide` )。标签名称为用户标签名,值为名称的 SHA-256(十六进制),包含的路径为添加了用户标签的 URL,权限决定谁可以查看。只有当该标签对调用者可见时,用户标签才可见。 +用户标签的机制 +============== -搜索 API( ``/api/v2/search`` )会将每个命中中调用者可见的用户标签作为 ``tags`` 返回。可以通过 ``fields.tag=<值>`` 缩小到带有该用户标签的文档,并通过 ``facet.field=tag`` 获取用户标签的分面。索引中的 ``tag`` 字段本身不会包含在响应中。 +- 用户标签按用户管理。创建用户标签的用户是其所有者,所有者为登录用户 ID。即使名称相同,所有者不同的用户标签也是不同的用户标签。 +- 只有已登录的用户才能使用用户标签。所有用户标签 API 都以会话中的登录用户身份运行,访问令牌不能代替登录。未登录的调用者会收到 ``auth_required`` (401)。 +- 新建的用户标签是私有的,只有所有者可见。所有者将用户标签设为“共享”后,所有已登录的用户都可以看到它并用它进行筛选。未登录的用户看不到任何用户标签,包括共享的用户标签。 +- 只有所有者可以更改、删除用户标签,或将其添加到文档、从文档中移除。其他用户的共享用户标签只能用于显示和筛选。管理员可以在管理界面中管理所有用户标签(请参阅 :doc:`../admin/tagtype-guide` )。 +- 用户标签添加在文档的 URL 上,因此索引中具有该 URL 的所有文档都会带有该用户标签。 -获取用户标签 +每个用户标签有以下两个标识符。 + +``value`` + 用户标签的值,格式为 ``base64url(名称):base64url(所有者)`` (UTF-8,无填充),存储在索引的 ``tag`` 字段中。请将其视为用于筛选搜索结果的不透明值。 + +``id`` + 用户标签 ID,即 ``value`` 的 SHA-256 的小写十六进制表示(64 个字符)。在 ``/api/v2/tags/{tagId}`` 等路径中指定。重命名用户标签后, ``value`` 和 ``id`` 都会改变。 + +用户标签名称会经过 NFKC 规范化,连续的空白合并为一个空格,并去除首尾的空白。规范化后的长度必须为 1 ~ ``user.tag.name.max.length`` (默认: ``50`` )个字符,包含控制字符或格式字符(如零宽字符、双向覆盖字符)的名称会被拒绝。 + +在搜索中使用 +============ + +当 ``user.tag.enabled`` 为 ``true`` 时,搜索 API( ``/api/v2/search`` )按如下方式处理用户标签。 + +- 每个命中以 ``tags`` 返回调用者可见的用户标签。每个元素包含 ``value`` 、 ``name`` 、 ``owner`` 、 ``mine`` (调用者为所有者时为 ``true`` )和 ``shared`` (共享的用户标签为 ``true`` )。没有可见的用户标签时不返回 ``tags`` 。索引中的 ``tag`` 字段本身不会返回。 +- 指定 ``facet.field=tag`` 时, ``facet_field`` 中返回仅包含调用者可见用户标签的分面。除 ``value`` 和 ``count`` 外,每个桶还包含 ``label`` (用户标签名称)、 ``owner`` 、 ``mine`` 和 ``shared`` 。 +- 可以通过 ``fields.tag=`` 缩小到带有该用户标签的文档。值请直接使用命中的 ``tags`` 或分面中的 ``value`` 。 + +指定用户标签的条件( ``fields.tag`` 、 ``tag:`` 、 ``ex_q`` 、 ``facet.query`` )仅在与调用者可见的用户标签值完全一致时有效。不可见用户标签的值,以及通配符、前缀、模糊和范围条件,不会匹配任何文档。对于未登录的调用者,不返回用户标签及其分面,用户标签条件也不会匹配任何文档。 + +一个用户可见的用户标签最多为 ``user.tag.visible.max.size`` (默认: ``1000`` )个,优先包含自己的用户标签。超出部分不会出现在命中的 ``tags`` 和分面中(但仍可用于筛选)。 + +反映到文档 +========== + +用户标签的创建、更改、删除以及在文档上的添加和移除,会立即反映在用户标签 API 中。而索引中文档的 ``tag`` 字段,则是先将更改放入内存中的队列,再由每分钟运行一次的“Log Aggregator”( ``log_aggregator`` )作业批量更新。因此,搜索结果的命中、分面和筛选最多需要约 1 分钟才能反映更改。重命名后的用户标签在下次处理队列之前,由于文档上的旧值不可见,不会显示在搜索结果中。 + +关于队列和作业,请参阅 :doc:`../admin/tagtype-guide` 。 + +获取用户标签列表 +================ + +请求 +---- + +================== ==================================================== +HTTP 方法 GET +端点 ``/api/v2/tags`` +================== ==================================================== + +按排序顺序和名称返回调用者拥有的用户标签。不包含其他用户的共享用户标签。 + +响应 +---- + +成功时(200),在公共信封的 ``response`` 下直接返回以下字段。 + +:: + + { + "response": { + "status": 0, + "tags": [ + { + "id": "ce7ff8c5f49e59fd28b02c1d763c7eca9260b51c44e2b4e0688c668d95738b7e", + "value": "5b6F56Gu6K6k:d2FuZw", + "name": "待确认", + "shared": false, + "sort_order": 0, + "path_count": 3 + } + ] + } + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: 响应字段 + + * - ``tags`` + - 调用者的用户标签数组。每个元素包含 ``id`` 、 ``value`` 、 ``name`` 、 ``shared`` (共享的用户标签为 ``true`` )、 ``sort_order`` (排序顺序)和 ``path_count`` (添加了该用户标签的 URL 数)。 + +表:响应字段 + +创建用户标签 +============ + +请求 +---- + +================== ==================================================== +HTTP 方法 POST +端点 ``/api/v2/tags`` +================== ==================================================== + +创建调用者的用户标签。由于这是更改状态的请求,需要 ``X-Fess-CSRF-Token`` 请求头(请参阅 :doc:`api-overview` )。 + +- 一个用户最多可以拥有 ``user.tag.max.tags`` (默认: ``1000`` )个用户标签。超出时返回 ``invalid_request`` (400)。 +- 调用者已有同名用户标签时返回 ``conflict`` (409)。其他用户拥有同名用户标签时仍可创建。 + +请求体使用 ``Content-Type: application/json`` ,最大为 1 KiB(1024 字节)。 + +:: + + { + "name": "待确认", + "shared": false + } + +.. tabularcolumns:: |p{4cm}|p{11cm}| +.. list-table:: 请求体 + + * - ``name`` + - 用户标签名称(str,必需)。 + * - ``shared`` + - 设为 ``true`` 时,所有已登录的用户都可以看到该用户标签(bool,默认: ``false`` )。 + +表:请求体 + +响应 +---- + +成功时(200), ``response`` 下的 ``tag`` 中返回创建的用户标签(格式与 ``GET /api/v2/tags`` 的元素相同, ``path_count`` 为 ``0`` )。 + +更改用户标签 +============ + +请求 +---- + +================== ==================================================== +HTTP 方法 PUT +端点 ``/api/v2/tags/{tagId}`` +================== ==================================================== + +重命名调用者的用户标签或切换其共享状态。需要 ``X-Fess-CSRF-Token`` 请求头。 + +- 请求体中至少指定 ``name`` 和 ``shared`` 中的一个。 +- 使用 ``name`` 重命名后,用户标签会获得新的 ``id`` 和 ``value`` 。带有旧值的文档会在下次处理队列时替换为新值。如果重命名为调用者已在使用的名称,则返回 ``conflict`` (409),用户标签保持不变。 +- ``shared`` 只改变可以看到该用户标签的用户,不需要更新文档。将 ``shared`` 设为 ``false`` 时,管理员添加到权限中的角色和组会保留。 +- 其他用户的共享用户标签返回 ``forbidden`` (403),调用者不可见的用户标签返回 ``not_found`` (404)。 +- 与其他更新冲突而反复写入失败时,也会返回 ``conflict`` (409)。 + +:: + + { + "name": "已确认", + "shared": true + } + +成功时(200), ``response`` 下返回 ``tag`` (更改后的用户标签)和 ``renamed`` (重命名时为 ``true`` ,此时 ``tag.id`` 和 ``tag.value`` 为新值)。 + +删除用户标签 ============ 请求 ---- +================== ==================================================== +HTTP 方法 DELETE +端点 ``/api/v2/tags/{tagId}`` +================== ==================================================== + +删除调用者的用户标签。文档中的该用户标签值会在下次处理队列时被移除。需要 ``X-Fess-CSRF-Token`` 请求头。其他用户的共享用户标签返回 ``forbidden`` (403),调用者不可见的用户标签返回 ``not_found`` (404)。 + +成功时(200), ``response`` 下返回 ``id`` (已删除的用户标签 ID)和 ``deleted`` (始终为 ``true`` )。 + +获取文档的用户标签 +================== + +请求 +---- + ================== ==================================================== HTTP 方法 GET 端点 ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -返回指定文档的用户标签中调用者可见的部分。调用者无法搜索该文档时,返回 ``not_found`` (404)。 +返回添加在文档 URL 上的用户标签中调用者可见的部分,以及尚未添加到该文档的调用者自己的用户标签。文档按调用者的角色检索,因此调用者无法搜索的文档返回 ``not_found`` (404)。 响应 ---- @@ -38,10 +200,25 @@ HTTP 方法 GET "response": { "status": 0, "doc_id": "a1b2c3d4e5f6", - "addable": true, "tags": [ - { "value": "9f86d081884c7d65...", "name": "待确认", "mine": true } - ] + { + "id": "ce7ff8c5f49e59fd28b02c1d763c7eca9260b51c44e2b4e0688c668d95738b7e", + "value": "5b6F56Gu6K6k:d2FuZw", + "name": "待确认", + "owner": "wang", + "mine": true, + "shared": false + }, + { + "id": "41e429a7d0081e25390c3840268d736dca00250167bab94250389aee9e08e2ed", + "value": "c3BlY3M:Ym9i", + "name": "specs", + "owner": "bob", + "mine": false, + "shared": true + } + ], + "addable": [] } } @@ -50,19 +227,21 @@ HTTP 方法 GET * - ``doc_id`` - 文档 ID(str)。 + * - ``tags`` + - 添加在文档 URL 上的用户标签中调用者可见部分的数组。每个元素包含 ``id`` 、 ``value`` 、 ``name`` 、 ``owner`` (所有者)、 ``mine`` (调用者为所有者时为 ``true`` )和 ``shared`` (共享的用户标签为 ``true`` )。 * - ``addable`` - - 调用者已登录(可以添加用户标签)时为 ``true`` (bool)。 + - 尚未添加到文档 URL 上的调用者的用户标签数组(元素格式与 ``tags`` 相同)。 * - ``added`` - - 仅 POST。调用者已为该文档添加过该用户标签时为 ``false`` (bool)。 + - 仅 POST。用户标签已添加过时为 ``false`` (bool)。 + * - ``tag`` + - 仅 POST。添加到文档的用户标签(元素格式与 ``tags`` 相同)。 * - ``removed`` - - 仅 DELETE(bool)。 - * - ``tags`` - - 调用者可见的用户标签数组。每个元素包含 ``value`` (标签值,用于 ``fields.tag`` )、 ``name`` (用户标签名)和 ``mine`` (调用者包含在该用户标签的权限中时为 ``true`` )。 + - 仅 DELETE。用户标签原本未添加时为 ``false`` (bool)。 -表: 响应字段 +表:响应字段 -添加用户标签 -============ +为文档添加用户标签 +================== 请求 ---- @@ -72,13 +251,9 @@ HTTP 方法 POST 端点 ``/api/v2/documents/{docId}/tags`` ================== ==================================================== -以已登录用户的身份为文档的 URL 添加用户标签。访问令牌不能代替登录。由于是更改状态的请求,需要 ``X-Fess-CSRF-Token`` 头。 +将文档的 URL 添加到调用者的用户标签中。需要 ``X-Fess-CSRF-Token`` 请求头。 -- 如果存在同名的用户标签,则将 URL 添加到其包含的路径,并将用户添加到其权限中。如果不存在,则创建一个只有该用户可见的用户标签。因此,同名的用户标签会合并为一个,添加了同名用户标签的用户之间可以看到彼此的用户标签添加在哪里。 -- 再次为同一文档添加时, ``added`` 为 ``false``\ 。 -- 一个文档最多可以有 ``user.tag.max.document.tags`` (默认值: ``100`` )个用户标签。 - -请求体使用 ``Content-Type: application/json``\ ,在 ``name`` 中指定用户标签名。 +请求体( ``Content-Type: application/json`` ,最大 1 KiB)中,用 ``id`` 指定已有的用户标签,或用 ``name`` 指定用户标签名称。两者都指定时以 ``id`` 为准。 :: @@ -86,44 +261,85 @@ HTTP 方法 POST "name": "待确认" } -用户标签名会进行 NFKC 规范化,连续的空白会合并为一个,并去除首尾空白。长度为 1 至 ``user.tag.name.max.length`` (默认值: ``50`` )个字符,包含控制字符或格式字符(零宽字符、双向覆盖等)的名称会被拒绝。 +- 指定 ``name`` 且调用者没有该名称的用户标签时,会创建一个私有用户标签并添加。新建的用户标签计入 ``user.tag.max.tags`` 。 +- 一个用户标签最多可以添加到 ``user.tag.max.paths`` (默认: ``10000`` )个 URL。超出时返回 ``invalid_request`` (400)。 +- 用 ``id`` 指定其他用户的用户标签时,如果该用户标签可见则返回 ``forbidden`` (403),否则返回 ``not_found`` (404)。 +- 成功时,返回与获取文档的用户标签相同的字段,并附加 ``added`` 和 ``tag`` 。用户标签在 API 中会立即添加,但要等下次处理队列时(约 1 分钟后)才会反映到具有该 URL 的文档的搜索结果中。 -删除用户标签 -============ +从文档移除用户标签 +================== 请求 ---- ================== ==================================================== HTTP 方法 DELETE -端点 ``/api/v2/documents/{docId}/tags?value=<用户标签值>`` +端点 ``/api/v2/documents/{docId}/tags/{tagId}`` ================== ==================================================== -将已登录用户从 ``value`` 指定的用户标签的权限中移除。当不再剩下任何用户、组或角色的权限时,该用户标签会被删除,并从文档中移除。用户不在该用户标签的权限中时,返回 ``forbidden`` (403)。需要 ``X-Fess-CSRF-Token`` 头。 +从 ``tagId`` 指定的调用者的用户标签中移除文档的 URL。需要 ``X-Fess-CSRF-Token`` 请求头。其他用户的用户标签可见时返回 ``forbidden`` (403),不可见时返回 ``not_found`` (404)。成功时,返回与获取文档的用户标签相同的字段,并附加 ``removed`` 。 错误响应 ======== +错误模型的详细信息请参阅 :doc:`api-overview` 。用户标签 API 返回的 HTTP 状态如下。 + .. tabularcolumns:: |p{4cm}|p{11cm}| .. list-table:: 错误响应 * - 状态码 - 说明 * - 400 Bad Request - - 请求不正确时(包括用户标签功能被禁用、用户标签名不正确、超过用户标签上限的情况)。 + - 请求无效时。包括用户标签功能已禁用、用户标签名称无效、缺少必需项,以及超出 ``user.tag.max.tags`` 或 ``user.tag.max.paths`` 上限的情况。 * - 401 Unauthorized - - 在 POST、DELETE 中未登录时。 + - 未登录时(访问令牌不能代替登录)。 * - 403 Forbidden - - CSRF 令牌缺失或失效,或者 DELETE 了自己未添加的用户标签时。 + - CSRF 令牌缺失或失效,或试图更改其他用户的用户标签时。CSRF 验证先于登录检查进行,因此没有会话的更改状态请求返回 403 而不是 401。 * - 404 Not Found - - 找不到文档,或调用者无法搜索该文档时。 + - 用户标签不存在或调用者不可见,或者文档不存在或调用者无法搜索时。 * - 405 Method Not Allowed - - HTTP 方法不被允许时。 + - 不允许该 HTTP 方法时。 + * - 409 Conflict + - 已存在同名用户标签,或与其他更新冲突而无法写入时。 * - 413 Payload Too Large - - 请求体超过大小上限时。 + - 请求体超过大小上限(1 KiB)时。 * - 415 Unsupported Media Type - - 不支持的 ``Content-Type`` 时。 + - ``Content-Type`` 不受支持时。 * - 500 Internal Server Error - 发生服务器内部错误时。 -表: 错误响应 +表:错误响应 + +设置 +==== + +可以通过 ``fess_config.properties`` 中的以下设置调整用户标签功能。 + +.. list-table:: + :header-rows: 1 + :widths: 35 50 15 + + * - 属性 + - 说明 + - 默认值 + * - ``user.tag.enabled`` + - 已登录的用户是否可以使用用户标签。 + - ``false`` + * - ``user.tag.name.max.length`` + - 用户标签名称的最大长度(码点数)。 + - ``50`` + * - ``user.tag.max.tags`` + - 一个用户可以拥有的用户标签的最大数量。 + - ``1000`` + * - ``user.tag.max.paths`` + - 一个用户标签可以添加到的 URL 的最大数量。 + - ``10000`` + * - ``user.tag.queue.max.size`` + - 在反映到文档之前保存在内存中的更改的最大数量。超出的更改会被丢弃,并输出 WARN 日志。 + - ``10000`` + * - ``user.tag.process.batch.size`` + - 将更改反映到文档时,一次批量请求中更新的 URL 数。 + - ``100`` + * - ``user.tag.visible.max.size`` + - 搜索中一个用户可见的用户标签的最大数量。 + - ``1000`` diff --git a/zh-cn/15.9/api/api-uiconfig.rst b/zh-cn/15.9/api/api-uiconfig.rst index 67c39d17..9ebedae5 100644 --- a/zh-cn/15.9/api/api-uiconfig.rst +++ b/zh-cn/15.9/api/api-uiconfig.rst @@ -197,7 +197,7 @@ features - 搜索结果导出( ``GET /api/v2/documents/export`` )是否启用( ``api.search.export`` )。 * - ``user_tag`` - boolean - - 用户标签功能( ``/api/v2/documents/{docId}/tags`` )是否启用( ``user.tag.enabled`` )。 + - 是否启用了按用户管理的用户标签( ``user.tag.enabled`` )。启用时,用户标签端点( ``/api/v2/tags`` 、 ``/api/v2/documents/{docId}/tags`` )可用,搜索命中中包含 ``tags`` 。 * - ``popular_word`` - boolean - 热门词功能是否启用。 diff --git a/zh-cn/15.9/config/properties.po b/zh-cn/15.9/config/properties.po index bf8254de..e27a95bd 100644 --- a/zh-cn/15.9/config/properties.po +++ b/zh-cn/15.9/config/properties.po @@ -573,6 +573,9 @@ msgstr "" msgid "Field name for label in the index." msgstr "" +msgid "Field name for the user tags of the document in the index." +msgstr "" + msgid "Field name for MIME type in the index." msgstr "" @@ -1122,6 +1125,27 @@ msgstr "" msgid "Maximum queue size for click logging." msgstr "" +msgid "Whether logged-in users can tag documents. Each tag belongs to the user who created it." +msgstr "" + +msgid "Maximum length of a tag name, in code points." +msgstr "" + +msgid "Maximum number of tags one user can own." +msgstr "" + +msgid "Maximum number of URLs one tag can be put on." +msgstr "" + +msgid "Maximum number of pending tag changes held in memory until they are applied to the documents." +msgstr "" + +msgid "Number of URLs updated per bulk request when tag changes are applied to the documents." +msgstr "" + +msgid "Maximum number of tags visible to one user in a search." +msgstr "" + msgid "Web" msgstr "" @@ -1239,6 +1263,9 @@ msgstr "" msgid "Maximum number of labeltype records to fetch per page." msgstr "" +msgid "Maximum number of tagtype records to fetch per page." +msgstr "" + msgid "Maximum number of roletype records to fetch per page." msgstr "" @@ -1545,6 +1572,9 @@ msgstr "" msgid "Online help key for label type." msgstr "" +msgid "Online help key for tag type." +msgstr "" + msgid "Online help key for duplicate host." msgstr "" diff --git a/zh-cn/15.9/config/properties.rst b/zh-cn/15.9/config/properties.rst index 1b10940c..05527361 100644 --- a/zh-cn/15.9/config/properties.rst +++ b/zh-cn/15.9/config/properties.rst @@ -753,6 +753,9 @@ Index * - index.field.label - Field name for label in the index. - ``label`` + * - index.field.tag + - Field name for the user tags of the document in the index. + - ``tag`` * - index.field.mimetype - Field name for MIME type in the index. - ``mimetype`` @@ -1458,6 +1461,27 @@ Index * - logging.click.max.queue.size - Maximum queue size for click logging. - ``10000`` + * - user.tag.enabled + - Whether logged-in users can tag documents. Each tag belongs to the user who created it. + - ``false`` + * - user.tag.name.max.length + - Maximum length of a tag name, in code points. + - ``50`` + * - user.tag.max.tags + - Maximum number of tags one user can own. + - ``1000`` + * - user.tag.max.paths + - Maximum number of URLs one tag can be put on. + - ``10000`` + * - user.tag.queue.max.size + - Maximum number of pending tag changes held in memory until they are applied to the documents. + - ``10000`` + * - user.tag.process.batch.size + - Number of URLs updated per bulk request when tag changes are applied to the documents. + - ``100`` + * - user.tag.visible.max.size + - Maximum number of tags visible to one user in a search. + - ``1000`` Web --- @@ -1586,6 +1610,9 @@ Web * - page.labeltype.max.fetch.size - Maximum number of labeltype records to fetch per page. - ``1000`` + * - page.tagtype.max.fetch.size + - Maximum number of tagtype records to fetch per page. + - ``1000`` * - page.roletype.max.fetch.size - Maximum number of roletype records to fetch per page. - ``1000`` @@ -1900,6 +1927,9 @@ Web * - online.help.name.labeltype - Online help key for label type. - ``labeltype`` + * - online.help.name.tagtype + - Online help key for tag type. + - ``tagtype`` * - online.help.name.duplicatehost - Online help key for duplicate host. - ``duplicatehost`` @@ -2265,7 +2295,7 @@ Web - ``/var/lib/fess/export`` * - index.export.exclude.fields - Comma-separated document fields omitted from files written by the index export job. - - ``cache`` + - ``cache,tag`` * - index.export.scroll.size - Number of documents fetched per scroll request by the index export job. - ``100``