Olha o código abaixo em node.js dá uma ajustada pro teu cenário já que usa js
import { createClient } from '@clickhouse/client';
const ch = createClient({
host: process.env.CHK_HOST,
username: process.env.CHK_USER,
password: process.env.CHK_PASS,
database: process.env.CHK_DB,
});
const BUCKETS = 256;
const CUTOFF = '2025-09-08 00:00:00';
async function backfill() {
for (let i = 0; i < BUCKETS; i++) {
const q = `
INSERT INTO agg_tabela
SELECT
k1, k2,
sumState(m1) AS m1_state,
uniqCombinedState(user_id) AS u_state,
countState() AS cnt_state
FROM fatos
WHERE sipHash64(k1, k2) % ${BUCKETS} = ${i}
AND event_time <= parseDateTimeBestEffort('${CUTOFF}') -- remova se não usar cutoff
GROUP BY k1, k2
SETTINGS max_execution_time=0
`;
await ch.exec({ query: q });
console.log(`bucket ${i} OK`);
}
}
backfill().then(()=>process.exit(0)).catch(e=>{console.error(e);process.exit(1);});
O que isso ai não faz:
Não cria a MV nova depois do backfill — você precisa criar com:
CREATE MATERIALIZED VIEW mv_agg TO agg_tabela AS SELECT ... GROUP BY ...;
Não valida as contagens automaticamente. Se quiser isso, adicione lógica de validação com:
const res = await ch.query({
query: `SELECT count() FROM agg_tabela WHERE sipHash64(k1,k2) % 256 = ${i}`,
format: 'JSONEachRow',
});
Espero que ajude, acho muito interessante fazer artigo de como resolveu, acho que isso é o maior déficit na web, as pessoas pedem ajuda, resolvem e não voltam para dar um feedback de como resolveram e quem lê em busca de ajuda se lasca.