LobeHub 全文检索后端 pg_search 和 Elasticsearch 怎么选? 📅 发布时间:2026/9/9 22:41:12 👁 浏览次数: LobeHub 全文检索后端 pg_search 和 Elasticsearch 怎么选【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehubLobeHub 自托管部署需要对 agent、topic、message、文件、知识库、聊天组和记忆等产品数据做全文检索。官方文档把这类产品搜索与 agent 可调用的联网搜索工具区分开并为前者提供两个可选后端pg_searchPostgreSQL 上的 ParadeDB BM25 索引和elasticsearch独立搜索引擎。整个部署只由一个环境变量决定用哪个后端——FTS_SEARCH_PROVIDER合法取值是pg_search和elasticsearch默认值为pg_search并且 LobeHub 不会在后端不可用时静默回退到另一个。这篇文档的目标是给你一条可执行的选型判断路径先按条件选出后端再按对应路径完成部署、回填、切换和验证。操作依据来自 Full-Text Search 和 Migrate from pg_search to Elasticsearch 两篇官方文档。按条件选择后端官方给出的选型判断条件是后端适用条件额外运维成本pg_search部署已经在跑 PostgreSQL且该数据库支持 ParadeDBpg_search扩展希望拓扑最简单PostgreSQL 自己维护 BM25 索引不需要额外的搜索同步 workerelasticsearch需要搜索服务独立扩容或想把搜索存储与事务型 PostgreSQL 分离或 PostgreSQL 服务方将停止支持pg_search需要一个 Elasticsearch 服务、一次初始回填backfill、PostgreSQL 变更捕获以及一个持续运行的增量消费 worker满足以下三个条件就保留默认的pg_search不需要读后面的 Elasticsearch 章节你的 PostgreSQL 服务支持pg_searchBM25 索引能够舒适地和其他数据库负载共存你不想额外运维一个独立的搜索服务。自建数据库时LobeHub 的 Docker 示例使用paradedb/paradedb:latest-pg17镜像并预加载pg_search。应用常规的 LobeHub 数据库迁移安装扩展和 LobeHub 管理的 BM25 索引之后保持FTS_SEARCH_PROVIDERpg_search什么时候必须选 Elasticsearch文档给出的直接触发条件是搜索需要独立容量、要分离搜索存储与 PostgreSQL或者你的 PostgreSQL 提供方正在终止pg_search支持。一个有明确时间点的案例Neon 已于 2026 年 3 月 19 日起不再向新项目提供pg_search并通知受影响的老用户该扩展将在 2026 年 9 月 21 日被移除——之后仍依赖它的查询、索引和应用都会失效。如果你的 LobeHub 跑在 Neon 上需要在那之前完成迁移。文档同时提醒在动手前先确认 Neon 官方的pg_search公告和扩展目录中的当前状态服务状态可能已变化。一个容易被忽略的硬限制选择 Elasticsearch不会让历史数据库迁移跳过pg_search当前迁移流程面向的是已经应用过pg_search迁移的存量数据库。即使选FTS_SEARCH_PROVIDERelasticsearchbun run db:migrate仍然会执行创建pg_search扩展和 BM25 索引的迁移如果数据库服务装不了这个扩展迁移会直接失败。因此包括全新 Docker Compose 安装在内的所有 LobeHub 数据库目前都必须跑在能安装pg_search的 PostgreSQL 镜像上例如官方 Compose 文件自带的paradedb/paradedb:latest-pg17。用 Docker Compose 部署单节点 Elasticsearch主路径官方docker-compose/deploy/docker-compose.yml内置了一个可选的elasticsearch服务以及配套的回填、同步服务面向单机部署且没有外部 Elasticsearch 账号的场景。三个服务都由 Compose profile 控制默认的docker compose up既不会下载也不会启动它们服务Profile作用elasticsearchelasticsearch单节点由固定官方镜像加analysis-icu插件本地构建带命名数据卷和健康检查不发布端口fts-search-reindexelasticsearch-reindex一次性回填/状态检查命令检查点存放在fts-search-reindex-state卷fts-search-syncelasticsearch-sync长驻增量消费 worker遇到失败或死信工作会退出非零并打日志由 Compose 重启资源前提Linux 主机上启动前确认节点默认 1 GB JVM 堆ES_JAVA_OPTS堆要保持在容器可用内存的一半以内仅 Elasticsearch 规划至少 2 GB 内存主机内核参数必须设置vm.max_map_count262144。首次启用该 profile 时镜像会本地构建一次需要能访问docker.elastic.co和artifacts.elastic.co之后的容器重建可离线进行。安全边界要理解清楚这个节点关闭了安全认证、不发布端口只允许在 Compose 网络内部访问所以明文无 API key 的连接必须用ES_ALLOW_INSECURE_HTTPtrue显式打开ES_ALLOW_INSECURE_HTTP永远不会允许在明文 HTTP 上发送 API key因此不要把它和ES_API_KEY加http://地址组合使用。该节点不要发布端口。按下面四步操作全程保持pg_search在服务最后一步才切换1. 启用节点。在.env中取消 Elasticsearch 配置块的注释COMPOSE_PROFILESelasticsearch ES_URLhttp://elasticsearch:9200 ES_ALLOW_INSECURE_HTTPtrue ES_INDEX_NAMESPACElobehub # FTS_SEARCH_PROVIDER 保持默认 pg_search直到最后一步然后启动并等待所有服务包括新节点健康同一版本的数据库迁移会创建 Outbox 结构docker compose up -d --wait2. 回填。先查状态再跑一次性回填。--apply会安装 PostgreSQL 变更捕获、按 ICU 映射创建 14 个索引、拷贝数据并创建别名docker compose run --rm fts-search-reindex --status docker compose run --rm fts-search-reindex --apply --fresh-run --yes只有第一次运行用--fresh-run。如果中途被中断用不带--fresh-run的同一条命令从检查点卷恢复。反复执行--status直到运行状态为ready_for_incremental_sync、每个实体都是completed、每个failedCount都是0才能进入下一步。3. 启动持续同步。在.env中加上同步 profile 并重建栈COMPOSE_PROFILESelasticsearch,elasticsearch-syncdocker compose up -d docker compose logs -f fts-search-syncworker 循环执行fts-search-elasticsearch-sync.cjs --max-steps8 --interval-seconds15 --yesFTS_SEARCH_SYNC_INTERVAL_SECONDS改变空队列时的停顿秒数遇到失败或死信工作会退出非零、由 Compose 重启所以容器反复重启说明队列需要你处理。只要 Elasticsearch 还在服务搜索这个 worker 就要一直跑。4. 显式切换。当docker compose run --rm fts-search-reindex --status显示pending、ready、retrying、inFlight、dead和revisionLag全部为0时在.env里设置FTS_SEARCH_PROVIDERelasticsearch并重建应用容器docker compose up -d lobe没有任何东西会自动切换 provider。回滚就是把FTS_SEARCH_PROVIDER改回pg_search再重建lobe同步 worker 可以继续运行。可选分支指向外部 Elasticsearch如果你的目标是 Elastic Cloud 或自管集群fts-search-reindex和fts-search-sync两个服务只依赖 PostgreSQL、不依赖内置节点把elasticsearchprofile 留在COMPOSE_PROFILES之外在.env里设置ES_URL和ES_API_KEY不设置ES_ALLOW_INSECURE_HTTP第 24 步完全相同。外部目标的额外要求目标可通过 HTTPS 从 LobeHub 服务器访问明文 HTTP 只允许本地开发的回环地址LobeHub 拒绝向其他主机明文发送 API key集群必须带官方 ICU 分析插件analysis-icu。Elastic Cloud Serverless 已内置自管集群要在每个节点安装并重启后再做首次--applyES_API_KEY需要索引创建、批量写入、refresh、count、别名和搜索权限不要用只读 keyES_INDEX_NAMESPACE保持稳定作为部署专属前缀例如lobehub派生出lobehub-messages这类别名不同部署不要共用一个命名空间也不要在迁移或增量消费进行中修改它。切换后如何验证与回滚切换完成后文档要求的观察项是成功的后端操作被记到elasticsearch不再出现新的pg_search操作Outbox 反复回到零 lag且没有死信工作你实际使用的产品搜索入口通过冒烟测试。LobeHub 通过 OpenTelemetry 导出有界指标和 trace不记录原始查询、用户 ID、文档 ID 或索引文本。定位搜索成本时主要看fts_search_backend_operations_total按 provider、实体、操作、结果统计的请求量与失败、fts_search_backend_operation_duration、fts_search_elasticsearch_requests_total、fts_search_elasticsearch_server_took等文档强调要同时看请求量、字节数、命中数、服务端耗时和索引存储单一信号不足以判断问题。在观察窗口内保留旧的 BM25 索引和pg_search扩展。只要这些旧对象还在回滚就是把FTS_SEARCH_PROVIDER改回pg_search并重新部署同步消费者可以继续跑。注意如果在捕获触发器安装后停掉消费者源变更会持续积压在 Outbox 里直到消费者恢复。清理已退役的 pg_search 对象等 Elasticsearch 稳定服务搜索、且有一个可用的 PostgreSQL 恢复点后检查残留的 LobeHub 管理对象bun run scripts/pgSearchCleanup/index.ts --status确认后再执行清理不要从文档里手抄 SQLbun run scripts/pgSearchCleanup/index.ts --apply --yes该命令使用直连DATABASE_URL不是事务池端点在FTS_SEARCH_PROVIDERelasticsearch生效前会拒绝执行并发移除已知 BM25 索引、移除扩展时不带CASCADE中断后重跑安全。它不会删除 Elasticsearch Outbox、捕获触发器或增量消费者——这三者是活跃的 Elasticsearch 后端的组成部分必须保留。Neon 上的部署必须在 2026-09-21 之前完成清理其他 PostgreSQL 提供方可以保留pg_search但清掉退役对象可以避免继续维护无用的 BM25 索引。边界与下一步完整回填只是初始快照不能替代周期性消费者只要 Elasticsearch 在服务搜索fts-search:sync就要一直在计划任务里。迁移前建议先备份 PostgreSQL并在隔离的数据库副本和空的 Elasticsearch 目标上演练至少覆盖每个非空实体的一个批次、同一检查点目录的恢复、增量追平和切换时的应用冒烟测试。不要并发地对同一检查点目录和物理索引跑两个 worker换机器恢复时必须把整个状态目录拷过去。更完整的演练、回填、切换与回滚细节包括按实体限流、--entity筛选、--skip-failure等参数见 Migrate from pg_search to Elasticsearchpg_search路径的完整说明见 Full-Text Search。【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考