96444d67fa
GET /api/v1/compare/records 新增 ordered / keyword 两个查询参数,过滤全部下推到 SQL。 不能分页之后再由客户端 filter —— 一页里可能一条都不命中,列表看着就是空的, 得翻很多页才蹦出一条。 顺带修掉这条链路上几处随数据量线性变慢的地方: - 列表查询 defer raw_payload / llm_calls / llm_price_snapshot 三个重型 JSON 列。 出参 ComparisonRecordOut 根本不读,却是每页几百 KB~几 MB 的白读 + 白反序列化, 是「比价记录/全部记录」页慢的主要来源;详情接口不 defer,raw_payload 照常返回。 - 「已下单」标记改为只按本页店名(≤ limit 条)反查 savings,不再把该用户全部下单 店名捞进内存跟 50 条记录取交集。 - 新增 (user_id, created_at, id) 复合索引:反向扫恰好等于列表的 ORDER BY created_at DESC, id DESC,PG 免排序直接取前 n 条。 迁移走 CREATE INDEX CONCURRENTLY,不阻塞线上 harvest 写入。 - keyword 转义 LIKE 通配符后再匹配,避免搜一个「%」把整表拉回来。 - nginx 对 application/json 开 gzip:此前 gzip off + gzip_types 只含 text/html + gzip_proxied off 三个默认值凑一起,等于所有接口都在裸奔;记录列表这种 字段名和中文店名高度重复的 JSON 压缩比稳定 8~10 倍。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.2 KiB
3.2 KiB
GET /api/v1/compare/records — 比价记录列表(游标分页)
所属:比价记录组(前缀
/api/v1/compare) | 鉴权:Bearer | ← 返回 API 索引
「我的比价记录」列表页数据源。按 id 倒序(最新在前)。
入参(query)
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
limit |
int | ❌ | 20 | 1–100 |
cursor |
int | ❌ | null | 上一页末条 id,首页不传 |
ordered |
bool | ❌ | null | true=只出「已下单」(店名命中本人真实下单)的记录;不传=不筛 |
keyword |
string | ❌ | null | 按店名 / 菜名模糊搜索,忽略大小写,≤64 字符;纯空白等同不传 |
include_trace |
bool | ❌ | false | 客户端开了本机 agent 调试模式时带 true,放行本人记录的 trace_url |
ordered / keyword 都在服务端过滤后再分页,客户端不要拿一页结果自己 filter ——
分页之后一页里可能一条都不命中,列表会看着像空的。
出参
响应 200:{ items: ComparisonRecordOut[], next_cursor: int|null }(分页见 索引#游标分页约定)
ComparisonRecordOut(列表项,不含 raw_payload,减小 payload)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
int | 记录 id(也是游标) |
business_type |
string | food / ecom / coupon |
trace_id |
string | pricebot trace_id |
source_platform_id |
string | null | 源平台代号 |
source_platform_name |
string | null | 源平台中文名 |
source_package |
string | null | 源平台包名 |
source_price_cents |
int | null | 源平台到手价(分) |
best_platform_id |
string | null | 最优平台代号 |
best_platform_name |
string | null | 最优平台中文名 |
best_price_cents |
int | null | 最优价(分) |
saved_amount_cents |
int | null | 省下(分,可 0/负) |
is_source_best |
bool | null | 源平台是否最便宜(= 没省到) |
store_name |
string | null | 店铺名 |
total_dish_count |
int | null | 菜品总数 |
skipped_dish_count |
int | null | 跳过菜品数 |
status |
string | success / failed |
information |
string | null | done 帧文案。成功:"在美团找到同店,到手价 ¥X…";失败:具体原因(如"美团、京东外卖均未找到该商品"),前端在 status=failed 时当原因展示 |
items |
object[] | 下单菜品 {name, qty, specs?} |
comparison_results |
object[] | 逐平台对比(price 单位元,已按 rank 升序) |
skipped_dish_names |
string[] | 被跳过的菜名 |
ordered |
bool | 「已下单」店级标记:店名命中本人 source='compare' 的下单记录即 true。瞬态字段,不在表里,每次查询现算 |
ad_coins_earned |
int | 本次比价看信息流广告实发的金币(按 trace_id 聚合)。同为瞬态字段 |
trace_url |
string | null | pricebot 调试链接。未开 debug_trace_enabled 且未带 include_trace=true 时为 null |
created_at |
datetime | 时间 |
错误
401未鉴权
说明
只返回当前登录用户自己的记录。需要单条全量(含 raw_payload)走 详情接口。