fix(search): stop dropping the name filter for short queries
CI / Frontend — svelte-check, ESLint, Stylelint, Prettier (push) Blocked by required conditions
CI / changes (push) Waiting to run
CI / Plugins — fixtures + runtime tests (push) Blocked by required conditions
CI / Message-bus spec — AsyncAPI + TypeScript DTO drift (push) Blocked by required conditions
CI / Migration ordering (new migrations postdate target branch) (push) Blocked by required conditions
CI / Rustfmt (push) Blocked by required conditions
CI / Clippy (push) Blocked by required conditions
CI / Wasm — fmt + clippy (push) Blocked by required conditions
CI / Wasm — release tests (push) Blocked by required conditions
CI / Server Unit and Functionnal Tests (push) Blocked by required conditions
CI / Security Audit (push) Blocked by required conditions
CI / Build (push) Waiting to run
CI / API, WebDAV & OIDC tests (push) Blocked by required conditions
CI / Bundled-assets binary — embed + SPA-serve integration (push) Blocked by required conditions
CI / WebDAV RFC 4918 — litmus (59/59) (push) Blocked by required conditions
CI / CalDAV + CardDAV — python-caldav (push) Blocked by required conditions
CI / Frontend end-to-end tests (via Playwright) (push) Blocked by required conditions
Docker Build and Test / Build and Test Docker Image (push) Waiting to run
Docker Publish (release, main, dry-run) / Pre-publish Tests (push) Waiting to run
Docker Publish (release, main, dry-run) / Build & Push Multi-Arch (push) Blocked by required conditions
CI / Frontend — svelte-check, ESLint, Stylelint, Prettier (push) Blocked by required conditions
CI / changes (push) Waiting to run
CI / Plugins — fixtures + runtime tests (push) Blocked by required conditions
CI / Message-bus spec — AsyncAPI + TypeScript DTO drift (push) Blocked by required conditions
CI / Migration ordering (new migrations postdate target branch) (push) Blocked by required conditions
CI / Rustfmt (push) Blocked by required conditions
CI / Clippy (push) Blocked by required conditions
CI / Wasm — fmt + clippy (push) Blocked by required conditions
CI / Wasm — release tests (push) Blocked by required conditions
CI / Server Unit and Functionnal Tests (push) Blocked by required conditions
CI / Security Audit (push) Blocked by required conditions
CI / Build (push) Waiting to run
CI / API, WebDAV & OIDC tests (push) Blocked by required conditions
CI / Bundled-assets binary — embed + SPA-serve integration (push) Blocked by required conditions
CI / WebDAV RFC 4918 — litmus (59/59) (push) Blocked by required conditions
CI / CalDAV + CardDAV — python-caldav (push) Blocked by required conditions
CI / Frontend end-to-end tests (via Playwright) (push) Blocked by required conditions
Docker Build and Test / Build and Test Docker Image (push) Waiting to run
Docker Publish (release, main, dry-run) / Pre-publish Tests (push) Waiting to run
Docker Publish (release, main, dry-run) / Build & Push Multi-Arch (push) Blocked by required conditions
The SQL repositories gated the name ILIKE condition on name.len() >= 3 *bytes*, so a 1-2 character search (e.g. "ab") silently returned an arbitrary page of the caller's files instead of matches — while the suggest dropdown (which never had the gate) still found them, making the top-bar search feel broken. The gate existed because the pg_trgm GIN index cannot accelerate sub-trigram patterns, but wrong-but-indexed is never acceptable: caller/folder scoping still bounds the scanned set and result pages are LIMIT-bound. Add a shared name_filter_active() predicate next to like_escape() (any non-blank query filters) and use it at all 7 gate sites — 4 in file_blob_read_repository (condition/bind pairs kept in lockstep so bind indices stay aligned), 3 match guards in folder_db_repository. The Tantivy >= 2 gate on the content index is deliberately left alone: it means "too-short tokens don't enter the full-text index", not a correctness gate. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,34 @@
|
||||
|
||||
## 已完成
|
||||
|
||||
### [2026-10-01] 修复搜索框短关键词失效(<3 字节查询静默丢名字过滤)
|
||||
- **状态**: 已完成(cargo fmt ✓;clippy --all-features --all-targets -D warnings 0 警告 ✓;
|
||||
`cargo test --lib` 930 通过 0 失败,含新增 3 个回归守卫测试 ✓)
|
||||
- **计划**: 修复"原先的搜索框模糊搜索能力有问题"。根因:7 处 SQL 仓库把名字 `ILIKE`
|
||||
条件门在 `name.len() >= 3`(**字节**)上——查询短于 3 字节时名字条件被**整体丢弃**,
|
||||
`/api/search?q=ab` 返回任意一页文件而非匹配项;而 suggest 下拉(`suggest_files_by_name`)
|
||||
没有此门槛,所以表现为"下拉能找到、结果页找不到"。门槛初衷是 pg_trgm GIN 索引
|
||||
无法加速 <3 字符的 pattern,但"错误但有索引"不可接受(韧性优先):调用方的
|
||||
caller/folder 作用域仍约束扫描集,结果页有 LIMIT。
|
||||
- **修法**: `pg/mod.rs` 新增共享判定 `name_filter_active`(非空白即过滤,trim 后判空)
|
||||
+ 3 个单测(1/2 字符、CJK 单字 3 字节、空白不过滤);7 处门槛全部换用该判定:
|
||||
- `src/infrastructure/repositories/pg/file_blob_read_repository.rs` — 4 处
|
||||
(search_files_paginated 条件+bind、search_files_in_subtree 条件+bind;
|
||||
条件与 bind 成对替换,参数序号不错位)
|
||||
- `src/infrastructure/repositories/pg/folder_db_repository.rs` — 3 处
|
||||
(search_folders、根目录臂、list_descendant_folders 的 match guard)
|
||||
- 刻意不动:`search_service.rs` L404 Tantivy 内容索引的 `>= 2` 门槛(语义是
|
||||
"太短的词不进全文索引",非正确性门槛);`search_dto.rs` 无校验,保持原样
|
||||
- **改动文件**(均为上游文件,局部替换):
|
||||
- `src/infrastructure/repositories/pg/mod.rs` — `name_filter_active` + `mod name_filter_tests`
|
||||
- `src/infrastructure/repositories/pg/file_blob_read_repository.rs` — 4 处判定替换
|
||||
- `src/infrastructure/repositories/pg/folder_db_repository.rs` — 3 处判定替换
|
||||
- **仅本地文件**: 无新增(`status.md` 本身)
|
||||
- **上游冲突风险**: 低 — 纯判定函数替换,无 SQL/结构改动;若上游也修此 bug 会天然收敛
|
||||
- **已知边界(未处理,记为后续)**: 词序模糊("report 2026" 匹配 "2026 report.docx")
|
||||
与分词匹配不在本次范围——`ILIKE %…%` 是子串语义,需要 tsvector/pg_trgm 相似度
|
||||
或分词方案,属功能增强而非缺陷修复
|
||||
|
||||
### [2026-10-01] 移除文件页搜索过滤栏(顶栏统一入口)
|
||||
- **状态**: 已完成(`npm run check` 全绿:svelte-check 0 错 0 警 + eslint + stylelint + prettier;`vitest run` 492 通过 0 失败)
|
||||
- **计划**: 顶栏搜索框与筛选面板(`29d0c335`)已提供同一套筛选能力后,文件页自己的
|
||||
|
||||
Reference in New Issue
Block a user