全文搜索 (Full-text Search)
分类代号:C.9 本章共 3 个接口
可关闭特性:config.yaml里fullsearch.disable: true会让这组路由完全不注册;当full_search返回VjmapError(404)时即判定为"关闭"。
vjmap 内置 bleve 作为 CAD 图纸全文索引,主要用于搜"图上某段文字在哪儿"。典型使用场景:
- 用户在前端搜索框里输入"消防栓",后端返回所有匹配到的文字 + bbox,前端画框高亮
- 按图元类型(单行/多行/属性注记/图层名/块名…)过滤
- 按工作区 / map_ver 隔离
快速索引
| 序号 | SDK 方法 | URL |
|---|---|---|
| 58 | full_search / fullSearch |
POST /api/v1/service/fullsearch/search(也支持 GET) |
| 59 | full_search_add / fullSearchAdd |
POST /api/v1/service/fullsearch/add |
| 60 | full_search_delete / fullSearchDelete |
DELETE /api/v1/service/fullsearch/delete |
Document 数据结构
{
"id": "unique-id", // 必填,全库唯一
"map_ver": "sys_zp_v1", // 建议填,便于按图过滤
"content": "消防栓", // 被索引的文本
"type": 1, // 见下方 type 表
"min_x": 0.0, // bbox
"min_y": 0.0,
"max_x": 1.0,
"max_y": 1.0,
"props": {...}, // 任意附加属性
"workspace":"_", // ⚠ 见下方坑位:默认工作区要显式写 "_",不能留空
"data": "..." // 原始业务载荷(由你自己定义)
}
type 常用值
| type | 说明 |
|---|---|
| 1 | 单行文字 |
| 2 | 多行文本 MText |
| 3 | 属性注记 Attribute |
| 4 | 块属性注记 |
| 5 | 图层名 |
| 6 | 块名 |
| 7 | 线型名 |
| 8 | 填充符号名 |
| 9 | 用户自定义 |
58 · 搜索 fullsearch/search
两种调用方式:
- GET:所有参数走 query,适合简单关键词。
- POST:所有参数走 JSON body,支持复杂结构(尤其
bounding_box)。
请求字段
| 字段 | 类型 | 说明 |
|---|---|---|
query |
string | 搜索关键词 |
map_ver |
string | 多个用 , 分隔;纯 mapid 自动取最新版本 |
type |
string | 类型过滤:"1" / "1,2,5" / "1-3" / "1-3,6" |
workspace |
string | 工作区,多个逗号分隔;缺省 "_","*" 查全部 |
limit |
int | 每页条数,默认 10 |
offset |
int | 分页偏移 |
fields |
string | 返回字段过滤,逗号分隔 |
facet |
bool | 是否按 map_ver 聚合 facet |
bounding_box |
string | "minx,miny,maxx,maxy" 或 "[..]" |
time_range |
string | "2023-01-01~2023-12-31" 或 "7"(最近 N 天) |
响应(实采)
{
"total": 0,
"hits": [],
"took": 2
}
total 是命中数量,hits 是文档数组(含 id / content / score / fragments 等 bleve 字段),took 是耗时毫秒。
Python
res = svc.full_search(
query="消防栓",
map_ver="proj_v1",
type_="1,2",
bounding_box="[0,0,1000,1000]",
limit=20,
)
for hit in res.get("hits", []):
print(hit["id"], hit.get("content"))
用 GET 走查询串:
svc.full_search(query="消防栓", limit=5, use_get=True)
Node.js
const res = await svc.fullSearch('消防栓', {
mapVer: 'proj_v1',
type: '1,2',
boundingBox: '[0,0,1000,1000]',
limit: 20,
});
59 · 新增文档 fullsearch/add
Body
{
"document": { "id":"...","map_ver":"...","content":"..." }
}
响应(实采)
{
"id": "nb_fs_1776832372",
"message": "Document added successfully"
}
坑位:
workspace留空 ≠ 默认工作区。自动同步会把空工作区名归一化为"_"再入库,但fullsearch/add不做归一化——留空会以""入库;而搜索缺省固定追加workspace:"_"的 term 过滤,结果默认搜索永远搜不到。要么 add 时显式传"workspace":"_",要么搜索时传workspace:"*"。
Python
svc.full_search_add({
"id": "firehydrant_01",
"map_ver": "proj_v1",
"content": "消防栓",
"type": 1,
"workspace": "_", # 显式写默认工作区,否则搜不到
"min_x": 100, "min_y": 200, "max_x": 110, "max_y": 210,
})
批量导入:本 SDK 只封装了单条
full_search_add。接口/fullsearch/batchAdd用同样的 POST JSON({"documents":[...]});本次不做默认封装,可按需自行svc._request("POST", svc.service_url("fullsearch/batchAdd"), json_body={"documents":[...]})。
60 · 删除文档 fullsearch/delete
注意是 DELETE 带 JSON body,而不是 ?id=(gin 用 ShouldBindJSON)。
Body
{ "id": "firehydrant_01" }
响应(实采)
{
"id": "nb_fs_1776832372",
"message": "Document deleted successfully"
}
Python
svc.full_search_delete("firehydrant_01")
常见错误
| HTTP 状态 | body 片段 | 含义 |
|---|---|---|
| 400 | "error":"Invalid request parameters" |
JSON 反序列化失败 |
| 400 | "error":"Document ID cannot be empty" |
未填 id |
| 400 | "error":"Invalid bounding box format" |
bounding_box 解析失败 |
| 404 | 整条路由不存在 | fullsearch.disable:true,功能关闭 |
| 500 | "error":"Failed to initialize service" |
后端索引损坏,看服务器日志 |
使用建议
- 用
map_ver隔离:别把所有图纸的文字都塞一个索引里查全局,会拖慢。 - 先 bbox 后全文:多数场景只需搜当前视口,给
bounding_box可大幅缩小候选集。 - 批量构建走后台 job:把"从 DWG 抽文字 → 批量 add"放到离线任务里;前端只做搜索。
- 关闭索引也没关系:SDK 的
full_search会在 404 时抛VjmapError(404),应用层 catch 一下退化到普通查询即可。 - CJK 单字分词:
query走 bleve match query + standard analyzer,中文按单字切分——搜"不存在的词"这类常见汉字组合会命中任何含其中某个字的文档。断言"无结果"请用纯拉丁乱码词;做精确匹配建议配合map_ver/type/bounding_box收敛候选集。