Skip to content
bitzorcas
中EN

Concept

Search 搜索、利冲与索引平台

源码校验的 Search 模块说明书,覆盖 Lucene 组合、统一搜索、利冲、权限漂移、事件断链、索引目录、分词配置、重建和生产门禁。

Last updated

Search 把 Bitzsoft.Integrations.Search 的检索端口、Lucene provider、平台权限和两张 owner-local 配置表组合为应用模块。它提供统一搜索、利冲检查、索引统计/目录、分词弱词管理以及基于已注册数据源的全量重建,但当前不是一条完整的数据索引平台:没有业务模块发布 SearchIndexChangedIntegrationEvent,Created/Updated consumer 只是日志 no-op。

1. 当前真实能力

已实现:

  • Lucene provider,配置入口 Search:Provider 与 Search:LuceneBasePath;
  • POST /api/search/unified,在调用者 TenantId 下查询任意 IndexKey;
  • POST /api/search/conflict/check,固定使用 conflict 索引执行当事人匹配;
  • 目录、统计、重建、利冲记录四条 generated endpoint;
  • 分词弱词增/删/查三条手写 endpoint;
  • 全局 SearchIndexCatalog 与 SysSegmentConfig 表;
  • Lucene/ElasticSearch/OpenSearch provider manifest,其中只有 Lucene 标记已实现;
  • search.index.changed consumer 的 Deleted 分支;
  • API Shell 无数据库/搜索能力时的 unavailable 默认端口与生产显式覆盖。

尚未实现:业务文档生产者、Created/Updated Upsert、事件 inbox/版本门、利冲记录持久化、源资源授权复核、StoredFields allowlist/脱敏、Feature 运行时映射、完整权限一致性、索引 seed、健康/新鲜度指标、多副本一致性、灾备恢复和 Search 端到端测试。

2. 运行结构

未接线Created/Updated: no-opDeleted全量重建

API caller

IAuthorizedRequest
部分 action 与目录漂移

UnifiedSearch / CheckConflict

ISearchEngine

Lucene provider
本地 BasePath

业务模块 publisher
当前不存在

search.index.changed

SearchIndexEventHandler

RebuildIndex
全量重建已实现

SearchIndexCatalog

Search 当前运行在 API 组合中。JobHost 只有 Infrastructure 项目引用,没有调用 AddBitzOrcasSearchPlatform,也没有重建 executor。默认 search-index 是相对进程目录;多 API 副本会拥有各自文件系统视图,CAP 负载均衡也不会自动复制 Lucene 文档。

3. 九条 HTTP 端点

方法与路由当前作用运行时权限后缀
POST /api/search/unified统一查询search.search.view
POST /api/search/conflict/check利冲匹配search.conflict.search
GET /api/search/conflict/records/{recordId}固定未就绪search.conflict.view
GET /api/search/index/catalog全局目录search.index.view
GET /api/search/index/{indexKey}/statistics租户索引统计search.index.view
POST /api/search/index/{indexKey}/rebuild全量重建search.index.manage
POST /api/search/segment/words新增全局弱词search.index.create
DELETE /api/search/segment/words删除全局弱词search.index.delete
GET /api/search/segment/words/{segmentType}列出全局弱词search.index.view

治理目录只声明 search.search.view、search.conflict.search/view、search.index.manage/view。因此利冲 check 调用利冲用 search.conflict.search,弱词写用 search.index.create/delete,与目录 manage/view 存在 action suffix 漂移。详见 HTTP 契约、权限与 Feature。

4. 第一次统一搜索

下面的应用内调用在当前租户的 conflict 索引查询“海岚科技”。Handler 把 Keyword 同时放入 Name、Subject、Content 三个默认字段;它不验证 IndexKey、Skip/Take,也不检查调用者是否有权查看每个命中所属的案件/文档。完整 HTTP body 见端点契约。

应用内调用并保留搜索失败
var result = await mediator.Send(
new UnifiedSearch.Query(
IndexKey: "conflict",
Keyword: "海岚科技",
Skip: 0,
Take: 20),
cancellationToken);
// Provider、目录或查询错误必须进入统一错误映射,不能伪装成“没有命中”。
if (result.IsFailure)
return result.Error;
// 命中是索引投影,不是案件访问授权,也不是业务事实来源。
return result.Value!;

响应包含 BusinessId、BusinessType、MatchKeywords、HitLevel 和原样映射的 StoredFields。当前没有字段 allowlist;如果 producer 把敏感值存进 StoredFields,Search 会全部返回。

5. 利冲不是普通关键字搜索

利冲入口忽略客户端 ConflictCheckRequest.TenantId,正确地使用当前用户 TenantId。它把 Name、ForeignName、FormerName、CreditCode 组成 category/keyword map,并支持用 SourceBusinessId 排除当前案件。

但当前结果只是“索引有匹配”。模块没有:检查记录、审查人/时间、规则版本、人工确认、override、源案件授权复核、不可否认审计或索引 watermark。GetConflictRecord 永远返回 ConflictRecord.PendingCasesModule。商业交付不能把布尔 HasConflict 当成完整利冲工作流。

详见统一搜索、利冲与结果安全。

6. 增量索引并未闭环

SearchIndexChangedIntegrationEvent 定义 EventId、IndexKey、DocumentId、TenantId、EntityType、Action、SourceVersion 和 OccurredAt,但没有 [IntegrationTopic],仓库中没有构造/发布它的代码。

consumer 对 Created/Updated 只记录“缺少 IIndexDocumentProvider”,随后仍调用 NotifyIndexChangedAsync;异常也会被吞掉。Deleted 调 ISearchEngine.DeleteAsync,失败时重抛触发 CAP retry。SourceVersion 只传给 notifier,没有用于索引幂等或乱序判断。

详见事件索引、版本顺序与重建。

7. Provider、目录与分词配置

Lucene 是唯一已实现 provider;ElasticSearch/OpenSearch 配置会启动失败,不会回退。外部包 1.0.0-alpha.8 提供 Search 抽象和 Lucene 引擎;平台模块负责组合、目录/词库持久化与 API。

目录表是全局 catalog,没有 seed 生产者,GetAll 无稳定排序,未知 Status 会被恢复为 Active。分词词库同样全局;增删以精确字符串工作,唯一键是 (SegmentType,Content),而内存桶使用 OrdinalIgnoreCase,数据库 collation 与运行时集合可能不一致。Store 注册 Scoped,缓存也是实例级,并非跨请求/节点缓存。

详见Lucene Provider、目录与分词词库。

8. 安全边界

已做对的部分:搜索和统计使用当前 TenantId,利冲不信任请求 TenantId,整个 /api/search group 要求认证和 user rate limit。

尚缺:

  • IndexKey allowlist 与每场景授权;
  • 命中级源资源授权/DataScope;
  • StoredFields 列级 allowlist、脱敏和大小限制;
  • 利冲人员数据的专用审计/保留;
  • 全局目录与弱词变更的更高平台权限;
  • Feature search.index 的运行时 entitlement;
  • 防止错误/恶意索引文档跨租户写入的 producer contract。

租户过滤只是第一层;索引中的 TenantId 若在写入时就错误,查询层无法自行修复。

9. 可观测性与恢复

目录有 DocumentCount、LastRebuiltAt、Version,但当前重建/统计链不更新目录。查询响应没有 index version、as-of、lag 或 producer watermark。也没有索引健康检查、损坏检测、磁盘阈值、commit lag、CAP backlog、reconciliation 或 shadow rebuild runbook。

Lucene 目录不应被普通数据库备份流程假定覆盖。生产必须明确索引是可重建缓存,还是需要独立备份;前者首先要求真正可工作的数据源和演练。

10. 现有测试证据

现有测试主要证明:一个 ListSegmentWords Handler 委托、两个内存 IEntitySet store 场景、owner-local 元数据、ORM 中立、host composition、provider manifest 与 unavailable 默认端口。

缺少:真实 Lucene 查询/Upsert/Delete、事件 byte contract、Created/Updated/Deleted 行为、权限 suffix、九条 endpoint、请求规则、StoredFields 安全、利冲业务规则、数据库 provider parity、索引损坏/多副本/重建/恢复和规模性能。

11. GA 红线

  1. 建立业务 owner→版本化事件/快照→Search 的文档生产契约;
  2. Created/Updated 真正 Upsert,Deleted、重复、乱序与 gap 有确定语义;
  3. 实现数据源、shadow rebuild、checkpoint、对账、切换与回滚;
  4. 统一 .check/.search、.manage/.create/.update/.delete;
  5. 将 search.index 接入运行时 Feature evaluator;
  6. 加 IndexKey allowlist、命中级源授权和 StoredFields schema;
  7. 把利冲提升为有证据、审阅、override 和记录的工作流;
  8. 验证全局词库作用域、规范化、并发和跨节点失效;
  9. 明确多副本 Lucene 拓扑、持久卷、所有权和灾备;
  10. 补齐契约、端点、provider、恢复、安全与性能测试。

12. 源码导航

主题入口
手写端点src/Hosts/BitzOrcas.Api/Endpoints/SearchEndpoints.cs
查询与利冲src/Platform/Search/...Search.Application/Queries、Commands/CheckConflict
权限/Feature...Search.Contracts/SearchPermissions.cs、SearchFeatures.cs
Lucene 组合...Search.Infrastructure/SearchDependencyInjection.cs
provider manifest...Search.Infrastructure/Providers/SearchProviderManifest.cs
增量 consumer...Search.Infrastructure/Events/SearchIndexEventHandler.cs
目录/词库...Search.Infrastructure/Persistence 与 Stores
外部能力版本Directory.Packages.props 中 Bitzsoft.Integrations.Search* 1.0.0-alpha.8

返回平台模块目录 · Documents · Tickets · Authorization

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%