外观
全文搜索模式篇
目标:让集成方用
/v1/search/query跑通纯关键词搜索、按容器或文档类型缩窄范围、按字段值筛选与按时间范围过滤,理解响应中高亮片段与文档状态的语义,并明确全文搜索与元数据字段筛选的边界。不在本篇范围:语义片段召回(chunk 粒度的 RAG 检索,见 RAG 检索模式篇);字段值的读写与 schema 定义(见 元数据与 schema 模式篇);按字段值做精确筛选而不走全文检索(见元数据模式篇 §三
metadataFilters);生命周期状态(TRASHED / ARCHIVED 资源的搜索可见性见 §六);错误码完整码表(见错误码参考)。
全文搜索基于全文检索能力,对索引内的文档内容与字段值做全文检索;metadataFilters 是面向结构化字段的精确筛选,实时强一致——两者服务不同场景,不互相替代。
关键事实
- 端点:
POST /v1/search/query,所需 scope:client:search:read。 - ⚠️ 搜索接口必须代表用户调用(强通道或弱通道),不支持 APP_ONLY。APP_ONLY 请求(无 user subjectSet)返回 HTTP 403。ACL 过滤在搜索层按当前用户主体集执行。
- 搜索结果只包含当前调用用户有权读取的文档(ACL 过滤在搜索层执行);集成方不需要在搜索结果上再做权限裁剪。
- 检索范围为已发布版本:文档的可检索内容随其发布版本更新;未发布 / 草稿状态、以及无任何可检索正文与元数据的文档不进入结果。
- 索引为最终一致刷新:文档发布、内容 / 元数据 / 权限变更后,其检索可见性在下一次索引同步周期生效,不保证修改后即时可搜;个别漏同步由平台后台自动补齐。依赖「写后即搜」的流程需改用实时一致的结构化查询端点(如
documents/getPage)或做短暂重试。 - 全文检索能力若未启用,端点返回 HTTP 503(不是业务码)。
- 默认只返回
ACTIVE状态的文档;TRASHED和ARCHIVED文档在默认查询中不可见(见 §六)。 keyword与fields均可选;两者均不传时,按其余过滤条件做范围查(相当于「列出」)。
一、纯关键词搜索
最简形态:只传 keyword,全库在当前用户可见范围内检索。
bash
curl -X POST 'https://api.atkonbase.example.com/v1/search/query' \
-H 'Authorization: Bearer ${accessToken}' \
-H 'X-Atk-User-Token: ${userToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyword": "合同续签",
"page": 1,
"size": 20
}'期望响应(关键字段)
json
{
"code": 0,
"data": {
"total": 3,
"took": 42,
"items": [
{
"docId": "D1000001",
"title": "2026年 Q2 合同续签协议",
"state": "ACTIVE",
"containerId": "C1000001",
"documentTypeCode": "contract",
"createTime": "2026-04-10T09:00:00.000+08:00",
"metadata": {
"status": "signed"
},
"highlights": {
"_fulltext": ["...合同<em>续签</em>条款第三条..."]
},
"hitChunks": []
}
]
}
}| 字段 | 含义 |
|---|---|
total | 总命中数(分页前) |
took | 搜索耗时(毫秒,含检索与详情回查时间) |
docId | 文档业务主键(不含版本,V1 资源端点直接用) |
title | 文档标题(由平台回查文档详情补齐) |
state | 文档当前状态(见 §六) |
containerId | 文档所在容器 ID |
documentTypeCode | 文档类型编码;null 表示文档未绑定具体类型 |
metadata | 命中文档的元数据(attributeKey → 值),与列表 / 详情同口径:按当前用户的字段级权限投影,无权限的受控字段值不出现 |
highlights | 高亮片段;键是字段名,_fulltext 是全文;片段含 <em> 标记 |
hitChunks | 对超长文档按分块命中的文本片段列表(通常为空;对内容特别长的文档会有值) |
⚠️
highlights中的<em>是原生 HTML 标签——渲染前需按需转义;若显示纯文本则 strip 标签。
二、关键词 + 容器范围
按容器缩窄检索范围(容器下直接子文档,不递归到后代):
bash
curl -X POST 'https://api.atkonbase.example.com/v1/search/query' \
-H 'Authorization: Bearer ${accessToken}' \
-H 'X-Atk-User-Token: ${userToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyword": "采购申请",
"containerId": "${containerId}",
"page": 1,
"size": 20
}'containerId缩窄到该容器的直接子文档;若要递归搜索子树,集成方自行遍历子容器后逐层传containerId调用,或不传containerId走全量后在结果侧过滤。
三、关键词 + 字段筛选 + 排序
按字段值过滤并指定排序,适合「在某类文档里搜关键词」场景:
bash
curl -X POST 'https://api.atkonbase.example.com/v1/search/query' \
-H 'Authorization: Bearer ${accessToken}' \
-H 'X-Atk-User-Token: ${userToken}' \
-H 'Content-Type: application/json' \
-d '{
"keyword": "违约",
"documentTypeCode": "contract",
"fields": {
"status": "active",
"region": "cn-east"
},
"createTimeFrom": "2026-01-01T00:00:00",
"createTimeTo": "2026-06-30T23:59:59",
"page": 1,
"size": 10
}'documentTypeCode过滤文档类型编码(ContentType.code);不传则不限类型。fields是分字段搜索条件,键为attributeKey,值为搜索词;与keyword同时传时为**「与」关系**。fields的键必须是已被全文检索索引的字段;未被索引的字段传入不报错,但命中率为 0。字段是否被索引见字段定义(元数据与 schema 模式篇 §五)。createTimeFrom/createTimeTo格式为 ISO 8601 字符串;均可选。
四、全文搜索 vs 元数据字段精确筛选
| 对比维度 | 全文搜索(/v1/search/query) | 字段精确筛选(metadataFilters in getPage) |
|---|---|---|
| 底层 | 全文检索 | 结构化字段精确查询 |
| 延迟 | 有索引延迟(秒-分钟级) | 实时强一致 |
| 匹配语义 | 分词 / 模糊 / 相关度排序 | 精确 / EQ / LIKE / 范围等操作符 |
| 适合场景 | 关键词检索、高亮摘要 | 按字段值精确过滤列表、确保实时性 |
| ACL 过滤 | 在搜索层内执行 | 在结构化查询层执行 |
- 需要「用户输入关键词找文档」→ 用全文搜索。
- 需要「按
region=cn-east过滤列表」→ 用metadataFilters(元数据与 schema 模式篇 §三)。 - 两者可以同时用:先用全文搜索检索,再按
docId回查文档详情补字段值;或先用metadataFilters缩窄,再在结果内做关键词匹配。
五、请求字段速查
| 字段 | 类型 | 说明 |
|---|---|---|
keyword | string | 全文关键词(可选) |
fields | map[string, string] | 分字段搜索:attributeKey → 搜索词(可选) |
documentTypeCode | string | 文档类型编码过滤(可选) |
containerId | string | 容器 ID 过滤(直接子文档,不递归)(可选) |
createTimeFrom | string | 创建时间范围起点(ISO 8601)(可选) |
createTimeTo | string | 创建时间范围终点(ISO 8601)(可选) |
page | int | 页码,从 1 开始(默认 1) |
size | int | 每页大小(默认 20) |
六、TRASHED / ARCHIVED 资源的可见性
- 默认查询只返回
ACTIVE状态的文档——TRASHED和ARCHIVED文档不出现在/v1/search/query结果中。 - 集成方如需检索已归档文档,当前搜索接口不支持状态过滤参数;可改用结构化查询端点
documents/getPage(带state=ARCHIVED过滤)配合关键词title模糊查询作为替代路径。 - 进入
TRASHED的文档从搜索索引中撤除(延迟同索引延迟);恢复(restore)后重新进入索引。 - 生命周期状态的操作端点见 生命周期模式篇。
常见坑
- ⚠️ APP_ONLY 调用收到 403:搜索接口需代表用户调用;添加强通道或弱通道 header(见 认证与身份双通道模式篇)。
- ⚠️ 新上传文档立即搜不到:先确认文档已发布(未发布内容不进入全文检索);已发布的变更也按最终一致刷新、不保证即时可搜。实时性要求高的检索用结构化查询端点(
documents/getPage)。 - ⚠️
total与实际列表页数不符:全文检索与结构化查询是两套独立数据源,总数轻微偏差为正常现象(ACL 过滤、索引延迟等影响)。 - ⚠️
highlights直接渲染导致 XSS:片段含<em>HTML 标签,渲染前需在集成方侧做合适的 HTML 处理(白名单过滤或 textContent 处理)。 - ⚠️ 传未索引的
fields键期望精确匹配:fields命中率取决于字段是否被全文检索索引;未索引字段传入不报错但不会命中,精确匹配应走metadataFilters。 - ⚠️ 全文检索未启用时收到 503:HTTP 503 是服务端降级,不是业务错误;无需按业务码处理,直接提示用户「搜索暂不可用」或做降级逻辑。
下一步
- 字段定义与字段值读写、
metadataFilters精确筛选 → 元数据与 schema 模式篇 - 文档生命周期状态(ACTIVE / ARCHIVED / TRASHED) → 生命周期模式篇
- 按语义召回内容片段(chunk 粒度、构建 RAG 应用) → RAG 检索模式篇
- V1 端点契约 + Try-it → 接口参考