FastGPT icon indicating copy to clipboard operation
FastGPT copied to clipboard

知识库的搜索测试无法查到数据(实际上是有相关数据的)

Open yuzhaopeng opened this issue 11 months ago • 13 comments

例行检查

  • [ ] 我已确认目前没有类似 issue
  • [ ] 我已完整查看过项目 README,以及项目文档
  • [ ] 我使用了自己的 key,并确认我的 key 是可正常使用的
  • [ ] 我理解并愿意跟进此 issue,协助测试和提供反馈
  • [x] 我理解并认可上述内容,并理解项目维护者精力有限,不遵循规则的 issue 可能会被无视或直接关闭

你的版本

  • [ ] 公有云版本
  • [x] 私有部署版本, 具体版本号: 4.8.22-alpha 使用的pg版本

问题描述, 日志截图,配置文件等 知识库中搜索测试,无法查询到数据,实际上是有数据的 Image

查看了fastGPT容器的日志如下: 打印了一个sql Image

我将sql拷贝出来,发现是一个带分页的sql查询语句,我用navicat连上postgres之后执行了一下,如果不带limit分页条件,是可以查出数据的,如下

Image

但是如果带上limit分页,就查不出结果了

Image

复现步骤

  1. 上传自己的pdf文档
  2. 在知识库测试搜索
  3. 搜索结果为空

预期结果 预期应该搜出来数据

相关截图 Image

yuzhaopeng avatar Feb 18 '25 15:02 yuzhaopeng

重新构建索引或者增大 ef search 试试

c121914yu avatar Feb 18 '25 15:02 c121914yu

好像是pgvector的锅,在pgvector的issue里找到了这个 https://github.com/pgvector/pgvector/issues/719 ,这个issue目前还没关闭,似乎这个bug还没修复

yuzhaopeng avatar Feb 18 '25 16:02 yuzhaopeng

那我把这个issue关闭了,等待pgvector那边修复吧

yuzhaopeng avatar Feb 18 '25 16:02 yuzhaopeng

留着好了,准备升级 0.8.0,到时候再试试。可以先把索引参数调整一下。估计还是 hnsw 索引的问题。

c121914yu avatar Feb 18 '25 16:02 c121914yu

重建索引后,把索引参数调到1000了,还是不行

yuzhaopeng avatar Feb 18 '25 16:02 yuzhaopeng

https://github.com/pgvector/pgvector/issues/719 这个issue被关闭了。另外我将插件的版本已经升级到了0.8.0了,问题依旧存在

shikaiwei1 avatar Feb 24 '25 14:02 shikaiwei1

https://github.com/pgvector/pgvector/issues/719 这个issue被关闭了。另外我将插件的版本已经升级到了0.8.0了,问题依旧存在

你增加迭代次数了吗

c121914yu avatar Feb 24 '25 14:02 c121914yu

没有,我仅仅是升级了插件版本,并在V4.8.22版本上测试

shikaiwei1 avatar Feb 24 '25 14:02 shikaiwei1

没有,我仅仅是升级了插件版本,并在V4.8.22版本上测试

这并不会有任何变化,它并不是一个错误,而是 hnsw 索引与 where 条件的问题,根据它的 issue 描述,需要通过增加迭代查询来解决。

c121914yu avatar Feb 24 '25 14:02 c121914yu

咱们的查询语句是不是应该增加SET hnsw.iterative_scan = on; 开启迭代器

shikaiwei1 avatar Feb 24 '25 15:02 shikaiwei1

我修改了源码中的如下语句,增加了打开迭代器的配置,但是问题依旧

      const results: any = await PgClient.query(
        `
        BEGIN;
          SET hnsw.iterative_scan = on;
          SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
          select id, collection_id, vector <#> '[${vector}]' AS score 
            from ${DatasetVectorTableName} 
            where team_id='${teamId}'
              AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
              ${filterCollectionIdSql}
              ${forbidCollectionSql}
            order by score limit ${limit};
        COMMIT;`
      );

shikaiwei1 avatar Feb 24 '25 15:02 shikaiwei1

我修改了源码中的如下语句,增加了打开迭代器的配置,但是问题依旧

      const results: any = await PgClient.query(
        `
        BEGIN;
          SET hnsw.iterative_scan = on;
          SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
          select id, collection_id, vector <#> '[${vector}]' AS score 
            from ${DatasetVectorTableName} 
            where team_id='${teamId}'
              AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
              ${filterCollectionIdSql}
              ${forbidCollectionSql}
            order by score limit ${limit};
        COMMIT;`
      );

按它issue里推荐配置加上试试

c121914yu avatar Feb 24 '25 15:02 c121914yu

测试方法: 分别配置和调整如下3个参数,在console中进行测试 SET hnsw.scan_mem_multiplier = 2; (调整范围1-8) SET hnsw.max_scan_tuples = 20000; (调整范围1000000-20000) SET hnsw.iterative_scan = relaxed_order;(调整范围strict_order/relaxed_order)

测试结论:

  1. 增加SET hnsw.iterative_scan = relaxed_order;后,能够部分解决(我这边数据集场景下,limit100 能出来4条,耗时229ms)
  2. 调整hnsw.scan_mem_multiplier和hnsw.max_scan_tuples 这两个值,能够提高limit 100情况下,返回的数据。但同时也增加了耗时,特别是scan_mem_multiplier值的增加会成倍增加耗时(当scan_mem_multiplier=2时,耗时提高到了3228ms)。

但是: 如果在代码中调整为如下内容,则所有的向量搜索都返回空结果。:

      const results: any = await PgClient.query(
        `
        BEGIN;
          SET LOCAL hnsw.iterative_scan = relaxed_order;
          SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
          select id, collection_id, vector <#> '[${vector}]' AS score 
            from ${DatasetVectorTableName} 
            where team_id='${teamId}'
              AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
              ${filterCollectionIdSql}
              ${forbidCollectionSql}
            order by score limit ${limit};
        COMMIT;`
      );

我通过console中记录的慢查询日志,将语句复制到console中,是可以查询到的。所以很奇怪,是什么原因导致最终的查询结果仍然为空。

shikaiwei1 avatar Feb 25 '25 09:02 shikaiwei1

我们这边遇到一个非常奇怪的问题,已导入的知识库,都无法搜索了,报错:搜索结果为空,但新导入的又没问题,旧知识重新构建也没问题(能想到的变更就是中间做了一次数据库升配操作),问题非常诡异

seven-yu avatar Mar 24 '25 08:03 seven-yu

测试方法: 分别配置和调整如下3个参数,在console中进行测试 SET hnsw.scan_mem_multiplier = 2; (调整范围1-8) SET hnsw.max_scan_tuples = 20000; (调整范围1000000-20000) SET hnsw.iterative_scan = relaxed_order;(调整范围strict_order/relaxed_order)

测试结论:

  1. 增加SET hnsw.iterative_scan = relaxed_order;后,能够部分解决(我这边数据集场景下,limit100 能出来4条,耗时229ms)
  2. 调整hnsw.scan_mem_multiplier和hnsw.max_scan_tuples 这两个值,能够提高limit 100情况下,返回的数据。但同时也增加了耗时,特别是scan_mem_multiplier值的增加会成倍增加耗时(当scan_mem_multiplier=2时,耗时提高到了3228ms)。

但是: 如果在代码中调整为如下内容,则所有的向量搜索都返回空结果。:

      const results: any = await PgClient.query(
        `
        BEGIN;
          SET LOCAL hnsw.iterative_scan = relaxed_order;
          SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
          select id, collection_id, vector <#> '[${vector}]' AS score 
            from ${DatasetVectorTableName} 
            where team_id='${teamId}'
              AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
              ${filterCollectionIdSql}
              ${forbidCollectionSql}
            order by score limit ${limit};
        COMMIT;`
      );

我通过console中记录的慢查询日志,将语句复制到console中,是可以查询到的。所以很奇怪,是什么原因导致最终的查询结果仍然为空。

通过手动执行一次pg主动回收解决了所有问题,然后看了下自动回收,默认阈值在20%,不太适合向量表,调整了些参数后好很多。 回收策论示例

// 积极策略 100万推荐配置
ALTER TABLE modeldata SET (
  autovacuum_vacuum_scale_factor = 0.01,  -- 死组清理的比例
  autovacuum_analyze_scale_factor = 0.02, -- 重新统计的比例
  autovacuum_vacuum_threshold = 1000,     -- 更高的基础阈值
  autovacuum_analyze_threshold = 1000,
  autovacuum_vacuum_cost_delay = 10,      -- 降低清理过程的休眠时间(ms),默认20ms
  autovacuum_vacuum_cost_limit = 2000     -- 增加每轮清理的工作量,默认200
);

c121914yu avatar Mar 25 '25 01:03 c121914yu

This issue has not been updated for more than 6 months and is marked as stale. If there is no further activity within 7 days, it will be automatically closed. Please reply to this issue if you need to continue following up on it.

github-actions[bot] avatar Jan 12 '26 04:01 github-actions[bot]