这个坑值得记一笔。在 Ubuntu 22.04 上用 qdrant-client 1.12 连本机 Qdrant 容器,集合 faq 里每条知识切了 5 个块,按 doc_id 分组检索,参数写成 group_by='doc_id'、group_size=3、limit=20,返回的 groups 里每组只有 1 条 hit,把 group_size 加到 10 也一样,换成 curl 打 /points/search/groups 结果相同。
刚开始盯着「payload 里字段名写成了 docId,group_by 找不到键就按单点返回」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。group_size 属于分组接口参数,写在 search 的 limit 里不会生效;集合里每个 doc_id 实际只入库了一个 point,分组自然只剩一条;客户端版本低于 1.10,旧方法在序列化时把 group_by 丢掉了。
数一下每个 doc_id 下到底有几个 point
curl -s -X POST 'http://localhost:6333/collections/faq/points/scroll' -H 'Content-Type: application/json' -d '{"limit":200,"with_payload":true}' | jq -r '.result.points[].payload.doc_id' | sort | uniq -c | sort -rn | head
再确认 payload 里真实的字段名
curl -s -X POST 'http://localhost:6333/collections/faq/points/scroll' -H 'Content-Type: application/json' -d '{"limit":1,"with_payload":true}' | jq '.result.points[0].payload | keys'
给分组字段补一个 keyword 索引减少扫描
curl -s -X PUT 'http://localhost:6333/collections/faq/index' -H 'Content-Type: application/json' -d '{"field_name":"doc_id","field_schema":"keyword"}'
末了用 groups 接口显式传 group_size 复验每组条数
curl -s -X POST 'http://localhost:6333/collections/faq/points/search/groups' -H 'Content-Type: application/json' -d '{"vector":[0.12,0.34,0.56],"group_by":"doc_id","group_size":3,"limit":20}' | jq '.result.groups | map(.hits | length)'
别只看报错消失,验证要多做一步。groups 里每组 hits 数量都等于 3,组数与 doc_id 去重后的数量一致,翻页时不再出现重复的 doc_id。
提醒一点。分组检索里的 limit 指组数而不是条数,group_size 才控制每组几条,两个参数在文档里挨着写,只改前一个很容易白折腾。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
