用户标签 API

本文档介绍 Fess 的 v2 用户标签 API,已登录的用户可以通过它管理自己的用户标签并将其添加到文档。公共响应信封、错误模型及 CSRF 相关内容,请参阅 API 概述 。

基础 URL 为 http://<Server Name>/api/v2/ (本地环境示例: http://localhost:8080/api/v2 )。

Note

用户标签功能默认禁用。要使用此功能,请在 fess_config.properties 中设置 user.tag.enabled=true 。可以通过 /api/v2/ui/config 的 features.user_tag 确认其状态。禁用期间,对于通过 CSRF 和 Origin 验证并使用受支持的 HTTP 方法的请求,用户标签 API 返回 invalid_request (400)。

用户标签的机制

  • 用户标签按用户管理。创建用户标签的用户是其所有者,所有者为登录用户 ID。即使名称相同,所有者不同的用户标签也是不同的用户标签。

  • 只有已登录的用户才能使用用户标签。所有用户标签 API 都以会话中的登录用户身份运行,访问令牌不能代替登录。未登录的调用者会收到 auth_required (401)。

  • 新建的用户标签是私有的,只有所有者可见。所有者将用户标签设为“共享”后,所有已登录的用户都可以看到它并用它进行筛选。未登录的用户看不到任何用户标签,包括共享的用户标签。

  • 只有所有者可以更改、删除用户标签,或将其添加到文档、从文档中移除。其他用户的共享用户标签只能用于显示和筛选。管理员可以在管理界面中管理所有用户标签(请参阅 用户标签 )。

  • 用户标签添加在文档的 URL 上,因此索引中具有该 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 )个字符,包含控制字符或格式字符(如零宽字符、双向覆盖字符)的名称会被拒绝。

虚拟主机

配置了虚拟主机时,标签与标签分面一样,遵循请求的虚拟主机。

  • 标签会记录创建它的请求的虚拟主机。

  • 在与某个虚拟主机匹配的请求中,GET /api/v2/tags 和文档标签 API 的 addable 只返回调用者在该虚拟主机下的标签。其他虚拟主机的标签,以及没有虚拟主机的标签,不会返回。对这类标签重命名、删除,或按 id 添加到文档,会返回 not_found (404);按 name 添加到文档,会返回 conflict (409),因为一个用户在所有虚拟主机中每个名称只能有一个标签。与任何虚拟主机都不匹配的请求可以看到所有标签。

  • 带虚拟主机的标签,只有在文档的爬取设置包含该虚拟主机时,才会设置到文档上。重新索引文档、运行 tag_updater 作业以及给文档添加标签时都适用这一规则。没有虚拟主机的标签和没有虚拟主机的文档不受限制。

  • 管理员可以在标签类型管理页面更改标签的虚拟主机或删除标签(参见 用户标签)。

在搜索中使用

当 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=<value> 缩小到带有该用户标签的文档。值请直接使用命中的 tags 或分面中的 value 。

指定用户标签的条件( fields.tag 、 tag: 、 ex_q 、 facet.query )仅在与调用者可见的用户标签值完全一致时有效。不可见用户标签的值,以及通配符、前缀、模糊和范围条件,不会匹配任何文档。对于未登录的调用者,不返回用户标签及其分面,用户标签条件也不会匹配任何文档。

标签的值包含 :,因此在查询中请用引号括起来:q=tag:"<value>" 可用。不加引号时,q=tag:<value> 不匹配任何内容,ex_q=tag:<value> 会被以 HTTP 400 拒绝。

一个用户可见的用户标签最多为 user.tag.visible.max.size (默认: 1000 )个,优先包含自己的用户标签。超出部分不会出现在命中的 tags 和分面中(但仍可用于筛选)。

反映到文档

用户标签的创建、更改、删除以及在文档上的添加和移除,会立即反映在用户标签 API 中。而索引中文档的 tag 字段,则是先将更改放入内存中的队列,再由每分钟运行一次的“Log Aggregator”( log_aggregator )作业批量更新。因此,搜索结果的命中、分面和筛选最多需要约 1 分钟才能反映更改。重命名后的用户标签在下次处理队列之前,由于文档上的旧值不可见,不会显示在搜索结果中。

关于队列和作业,请参阅 用户标签 。

获取用户标签列表

请求

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
      }
    ]
  }
}
响应字段
tags 调用者的用户标签数组。每个元素包含 id 、 value 、 name 、 shared (共享的用户标签为 true )、 sort_order (排序顺序)和 path_count (添加了该用户标签的 URL 数)。

表:响应字段

创建用户标签

请求

HTTP 方法 POST
端点 /api/v2/tags

创建调用者的用户标签。由于这是更改状态的请求,需要 X-Fess-CSRF-Token 请求头(请参阅 API 概述 )。

  • 一个用户最多可以拥有 user.tag.max.tags (默认: 1000 )个用户标签。超出时返回 invalid_request (400)。

  • 调用者已有同名用户标签时返回 conflict (409)。其他用户拥有同名用户标签时仍可创建。

请求体使用 Content-Type: application/json ,最大为 1 KiB(1024 字节)。

{
  "name": "待确认",
  "shared": false
}
请求体
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

返回添加在文档 URL 上的用户标签中调用者可见的部分,以及尚未添加到该文档的调用者自己的用户标签。文档按调用者的角色检索,因此调用者无法搜索的文档返回 not_found (404)。

响应

成功时(200),在公共信封的 response 下直接返回以下字段。

{
  "response": {
    "status": 0,
    "doc_id": "a1b2c3d4e5f6",
    "tags": [
      {
        "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": []
  }
}
响应字段
doc_id 文档 ID(str)。
tags 添加在文档 URL 上的用户标签中调用者可见部分的数组。每个元素包含 id 、 value 、 name 、 owner (所有者)、 mine (调用者为所有者时为 true )和 shared (共享的用户标签为 true )。
addable 尚未添加到文档 URL 上的调用者的用户标签数组(元素格式与 tags 相同)。
added 仅 POST。用户标签已添加过时为 false (bool)。
tag 仅 POST。添加到文档的用户标签(元素格式与 tags 相同)。
removed 仅 DELETE。用户标签原本未添加时为 false (bool)。

表:响应字段

为文档添加用户标签

请求

HTTP 方法 POST
端点 /api/v2/documents/{docId}/tags

将文档的 URL 添加到调用者的用户标签中。需要 X-Fess-CSRF-Token 请求头。

请求体( Content-Type: application/json ,最大 1 KiB)中,用 id 指定已有的用户标签,或用 name 指定用户标签名称。两者都指定时以 id 为准。

{
  "name": "待确认"
}
  • 指定 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/{tagId}

从 tagId 指定的调用者的用户标签中移除文档的 URL。需要 X-Fess-CSRF-Token 请求头。其他用户的用户标签可见时返回 forbidden (403),不可见时返回 not_found (404)。成功时,返回与获取文档的用户标签相同的字段,并附加 removed 。

错误响应

错误模型的详细信息请参阅 API 概述 。用户标签 API 返回的 HTTP 状态如下。

错误响应
状态码 说明
400 Bad Request 请求无效时。包括用户标签功能已禁用、用户标签名称无效、缺少必需项,以及超出 user.tag.max.tags 或 user.tag.max.paths 上限的情况。
401 Unauthorized 未登录时(访问令牌不能代替登录)。
403 Forbidden CSRF 令牌缺失或失效,或试图更改其他用户的用户标签时。CSRF 验证先于登录检查进行,因此没有会话的更改状态请求返回 403 而不是 401。
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 中的以下设置调整用户标签功能。

属性 说明 默认值
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