口径:已并入 / 子段的到访不再计入时间线与统计(导出侧一个字节不动)

真机里两行到访可能「不独立成立」:ZMERGEDTO 指向它被并入的那条、ZPARENT 说明它只是某个
父段的一部分。app 对这两种行既不显示也不计数,本站以前当成普通到访 ⇒ 时间线上出现
「同一时刻同一地点两条」、日停留重复计入(实测数据集 9 有 64 条,26 条到达时间与原件相同)。
这些行**不能删**——导出要靠它们认这次合并发生过,所以判据只立一份 stats.SoloVisitSQL,
在读的一侧收口:visitsWhere / VisitsByPlace / Bookmarked / placeCols 子查询、首次到达城市、
地图极值点、专题(详情 + 列表批量)、三处聚合的 visit_count 与 dwell_minutes,
外加 schema.sql 一段幂等回填把存量库拉正。

天气与位移**不收口**(那几小时、那段路真实发生过);导出侧一个字节不动(rond 只读
places.last_visit_at,保持全量,压根不读 visit_count / dwell_minutes)。编辑页照样列出
这些行,但打上「已并入 #562 / 子段 #374」,免得以为数据丢了。

顺带修两个自测抓出来的问题:
- ingest 的地点聚合回填排在 insertEntityRaw 之前 ⇒ 判据读到空留档 ⇒ 每行都算独立到访
  (整整多算一个「已并入」的量)。
- 收口后 last_visit_at 保持全量,会凑出「0 次却有最近到访」(数据集 9 有 4 个地点),
  展示侧按可见到访数兜住。

验收:304 PASS / 0 FAIL / 0 SKIP(新增 3 个用例:标记后导出仍带该行、存量回填拉正、
判据只出现在读侧)。
This commit is contained in:
tamakyi
2026-09-29 21:15:25 +08:00
parent 152af81f6a
commit 4597047989
12 changed files with 404 additions and 61 deletions
+8 -1
View File
@@ -43,9 +43,16 @@ func TestOverviewMatchesManualSQL(t *testing.T) {
}
var places, cities, days, visits, movements int
var dist float64
// 判据按**访客口径**在手写 SQL 里独立写一遍(不复用 stats.SoloVisitSQL):已并入 / 子段的
// 到访在 app 里既不算次数也不占天数——独立写一份,正好在口径写错时把它抓出来。
// 位移/里程那两行**不**加这个条件:那段路是真的发生过的,收口只管到访本身。
if err := db.QueryRow(`SELECT count(DISTINCT v.place_id), count(DISTINCT p.city),
count(DISTINCT (v.arrival AT TIME ZONE 'Asia/Shanghai')::date), count(*)
FROM visits v LEFT JOIN places p ON p.id = v.place_id WHERE v.dataset_id=$1`, dsID).
FROM visits v LEFT JOIN places p ON p.id = v.place_id
WHERE v.dataset_id=$1
AND NOT EXISTS (SELECT 1 FROM entity_raw er
WHERE er.dataset_id=v.dataset_id AND er.entity='ZVISIT' AND er.src_pk=v.src_pk
AND (er.raw->>'ZMERGEDTO' IS NOT NULL OR er.raw->>'ZPARENT' IS NOT NULL))`, dsID).
Scan(&places, &cities, &days, &visits); err != nil {
t.Fatal(err)
}