@clickhouse/client 1.20.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/client.d.ts +6 -6
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +6 -6
- package/dist/config.js +6 -5
- package/dist/config.js.map +1 -1
- package/dist/connection/compression.d.ts +4 -4
- package/dist/connection/compression.js +3 -3
- package/dist/connection/compression.js.map +1 -1
- package/dist/connection/create_connection.d.ts +6 -6
- package/dist/connection/create_connection.js +3 -3
- package/dist/connection/create_connection.js.map +1 -1
- package/dist/connection/index.d.ts +4 -4
- package/dist/connection/index.js.map +1 -1
- package/dist/connection/node_base_connection.d.ts +11 -11
- package/dist/connection/node_base_connection.js +75 -42
- package/dist/connection/node_base_connection.js.map +1 -1
- package/dist/connection/node_custom_agent_connection.d.ts +4 -4
- package/dist/connection/node_custom_agent_connection.js +2 -2
- package/dist/connection/node_custom_agent_connection.js.map +1 -1
- package/dist/connection/node_http_connection.d.ts +4 -4
- package/dist/connection/node_http_connection.js.map +1 -1
- package/dist/connection/node_https_connection.d.ts +5 -5
- package/dist/connection/node_https_connection.js +11 -11
- package/dist/connection/node_https_connection.js.map +1 -1
- package/dist/connection/socket_pool.d.ts +9 -9
- package/dist/connection/socket_pool.js +33 -32
- package/dist/connection/socket_pool.js.map +1 -1
- package/dist/connection/stream.d.ts +2 -2
- package/dist/connection/stream.js +18 -18
- package/dist/connection/stream.js.map +1 -1
- package/dist/index.d.ts +41 -8
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/result_set.d.ts +31 -20
- package/dist/result_set.js +83 -13
- package/dist/result_set.js.map +1 -1
- package/dist/utils/encoder.d.ts +2 -2
- package/dist/utils/encoder.js +3 -3
- package/dist/utils/encoder.js.map +1 -1
- package/dist/utils/index.d.ts +4 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/runtime.js.map +1 -1
- package/dist/utils/stream.d.ts +1 -1
- package/dist/utils/stream.js +8 -8
- package/dist/utils/stream.js.map +1 -1
- package/dist/utils/user_agent.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/skills/clickhouse-js-node-coding/reference/async-insert.md +12 -12
- package/skills/clickhouse-js-node-coding/reference/client-configuration.md +16 -16
- package/skills/clickhouse-js-node-coding/reference/custom-json.md +31 -31
- package/skills/clickhouse-js-node-coding/reference/data-types.md +65 -65
- package/skills/clickhouse-js-node-coding/reference/insert-columns.md +23 -23
- package/skills/clickhouse-js-node-coding/reference/insert-formats.md +30 -30
- package/skills/clickhouse-js-node-coding/reference/insert-values.md +35 -35
- package/skills/clickhouse-js-node-coding/reference/ping.md +24 -24
- package/skills/clickhouse-js-node-coding/reference/query-parameters.md +27 -27
- package/skills/clickhouse-js-node-coding/reference/select-formats.md +21 -21
- package/skills/clickhouse-js-node-coding/reference/sessions.md +27 -27
- package/skills/clickhouse-js-node-troubleshooting/reference/compression.md +2 -2
- package/skills/clickhouse-js-node-troubleshooting/reference/data-types.md +24 -24
- package/skills/clickhouse-js-node-troubleshooting/reference/logging.md +5 -5
- package/skills/clickhouse-js-node-troubleshooting/reference/proxy-pathname.md +7 -7
- package/skills/clickhouse-js-node-troubleshooting/reference/query-format-clause.md +6 -6
- package/skills/clickhouse-js-node-troubleshooting/reference/query-params.md +30 -30
- package/skills/clickhouse-js-node-troubleshooting/reference/readonly-users.md +4 -4
- package/skills/clickhouse-js-node-troubleshooting/reference/socket-hangup.md +20 -20
- package/skills/clickhouse-js-node-troubleshooting/reference/tls.md +24 -24
|
@@ -30,16 +30,16 @@ When answering configuration questions, include the relevant points:
|
|
|
30
30
|
## Minimal client
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
|
-
import { createClient } from
|
|
33
|
+
import { createClient } from "@clickhouse/client";
|
|
34
34
|
|
|
35
35
|
const client = createClient({
|
|
36
36
|
url: process.env.CLICKHOUSE_URL, // defaults to 'http://localhost:8123'
|
|
37
37
|
username: process.env.CLICKHOUSE_USER, // defaults to 'default'
|
|
38
38
|
password: process.env.CLICKHOUSE_PASSWORD, // defaults to ''
|
|
39
|
-
database:
|
|
40
|
-
})
|
|
39
|
+
database: "analytics", // defaults to 'default'
|
|
40
|
+
});
|
|
41
41
|
// ... your queries ...
|
|
42
|
-
await client.close()
|
|
42
|
+
await client.close();
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
`url` accepts a string or a `URL` object. The accepted string format is:
|
|
@@ -62,7 +62,7 @@ export CLICKHOUSE_URL='https://bob:secret@my.host:8124/analytics'
|
|
|
62
62
|
|
|
63
63
|
```ts
|
|
64
64
|
// In your Node.js code — no URL construction needed:
|
|
65
|
-
const client = createClient({ url: process.env.CLICKHOUSE_URL })
|
|
65
|
+
const client = createClient({ url: process.env.CLICKHOUSE_URL });
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
## Per-client vs per-request `clickhouse_settings` ⭐
|
|
@@ -79,14 +79,14 @@ const client = createClient({
|
|
|
79
79
|
clickhouse_settings: {
|
|
80
80
|
output_format_json_quote_64bit_integers: 0, // applied to every request
|
|
81
81
|
},
|
|
82
|
-
})
|
|
82
|
+
});
|
|
83
83
|
|
|
84
84
|
const rows = await client.query({
|
|
85
|
-
query:
|
|
85
|
+
query: "SELECT number FROM system.numbers LIMIT 2 FORMAT JSONEachRow",
|
|
86
86
|
clickhouse_settings: {
|
|
87
87
|
output_format_json_quote_64bit_integers: 1, // overrides client default for this call
|
|
88
88
|
},
|
|
89
|
-
})
|
|
89
|
+
});
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
## `default_format` for `exec()`
|
|
@@ -96,17 +96,17 @@ query has no trailing `FORMAT …` clause, set `default_format` so the server
|
|
|
96
96
|
knows what to send back, then wrap the response in a `ResultSet`:
|
|
97
97
|
|
|
98
98
|
```ts
|
|
99
|
-
import { createClient, ResultSet } from
|
|
99
|
+
import { createClient, ResultSet } from "@clickhouse/client";
|
|
100
100
|
|
|
101
|
-
const client = createClient()
|
|
102
|
-
const format =
|
|
101
|
+
const client = createClient();
|
|
102
|
+
const format = "JSONCompactEachRowWithNamesAndTypes";
|
|
103
103
|
const { stream, query_id } = await client.exec({
|
|
104
|
-
query:
|
|
104
|
+
query: "SELECT database, name, engine FROM system.tables LIMIT 5",
|
|
105
105
|
clickhouse_settings: { default_format: format },
|
|
106
|
-
})
|
|
107
|
-
const rs = new ResultSet(stream, format, query_id)
|
|
108
|
-
console.log(await rs.json())
|
|
109
|
-
await client.close()
|
|
106
|
+
});
|
|
107
|
+
const rs = new ResultSet(stream, format, query_id);
|
|
108
|
+
console.log(await rs.json());
|
|
109
|
+
await client.close();
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
For ordinary `SELECT`s prefer `client.query({ format })` — `default_format` is
|
|
@@ -35,38 +35,38 @@ A custom `{ parse, stringify }` lets you plug in `JSONBig`,
|
|
|
35
35
|
## Recipe: BigInt-safe stringify, custom Date handling
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
|
-
import { createClient } from
|
|
38
|
+
import { createClient } from "@clickhouse/client";
|
|
39
39
|
|
|
40
40
|
const valueSerializer = (value: unknown): unknown => {
|
|
41
41
|
// Serialize Date as a UNIX millis number (instead of toJSON's ISO string)
|
|
42
42
|
if (value instanceof Date) {
|
|
43
|
-
return value.getTime()
|
|
43
|
+
return value.getTime();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// Serialize BigInt as a string so JSON.stringify won't throw
|
|
47
|
-
if (typeof value ===
|
|
48
|
-
return value.toString()
|
|
47
|
+
if (typeof value === "bigint") {
|
|
48
|
+
return value.toString();
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (Array.isArray(value)) {
|
|
52
|
-
return value.map(valueSerializer)
|
|
52
|
+
return value.map(valueSerializer);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
if (typeof value ===
|
|
55
|
+
if (typeof value === "object" && value !== null) {
|
|
56
56
|
return Object.fromEntries(
|
|
57
57
|
Object.entries(value).map(([k, v]) => [k, valueSerializer(v)]),
|
|
58
|
-
)
|
|
58
|
+
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
return value
|
|
62
|
-
}
|
|
61
|
+
return value;
|
|
62
|
+
};
|
|
63
63
|
|
|
64
64
|
const client = createClient({
|
|
65
65
|
json: {
|
|
66
66
|
parse: JSON.parse, // use default parsing
|
|
67
67
|
stringify: (obj: unknown) => JSON.stringify(valueSerializer(obj)),
|
|
68
68
|
},
|
|
69
|
-
})
|
|
69
|
+
});
|
|
70
70
|
|
|
71
71
|
await client.command({
|
|
72
72
|
query: `
|
|
@@ -75,20 +75,20 @@ await client.command({
|
|
|
75
75
|
ENGINE MergeTree
|
|
76
76
|
ORDER BY id
|
|
77
77
|
`,
|
|
78
|
-
})
|
|
78
|
+
});
|
|
79
79
|
|
|
80
80
|
await client.insert({
|
|
81
|
-
table:
|
|
82
|
-
format:
|
|
81
|
+
table: "inserts_custom_json_handling",
|
|
82
|
+
format: "JSONEachRow",
|
|
83
83
|
values: [
|
|
84
84
|
{
|
|
85
|
-
id: BigInt(
|
|
85
|
+
id: BigInt("250000000000000200"), // serialized as a string
|
|
86
86
|
dt: new Date(), // serialized as ms since epoch
|
|
87
87
|
},
|
|
88
88
|
],
|
|
89
|
-
})
|
|
89
|
+
});
|
|
90
90
|
|
|
91
|
-
await client.close()
|
|
91
|
+
await client.close();
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
> The custom `valueSerializer` runs **before** `JSON.stringify`, so values
|
|
@@ -102,10 +102,10 @@ or precision-lossy numbers), plug in a `BigInt`-aware parser such as
|
|
|
102
102
|
[`json-bigint`](https://www.npmjs.com/package/json-bigint):
|
|
103
103
|
|
|
104
104
|
```ts
|
|
105
|
-
import { createClient } from
|
|
106
|
-
import JSONBig from
|
|
105
|
+
import { createClient } from "@clickhouse/client";
|
|
106
|
+
import JSONBig from "json-bigint";
|
|
107
107
|
|
|
108
|
-
const bigJson = JSONBig({ useNativeBigInt: true })
|
|
108
|
+
const bigJson = JSONBig({ useNativeBigInt: true });
|
|
109
109
|
|
|
110
110
|
const client = createClient({
|
|
111
111
|
json: {
|
|
@@ -115,7 +115,7 @@ const client = createClient({
|
|
|
115
115
|
clickhouse_settings: {
|
|
116
116
|
output_format_json_quote_64bit_integers: 0,
|
|
117
117
|
},
|
|
118
|
-
})
|
|
118
|
+
});
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
`output_format_json_quote_64bit_integers: 0` is the default since
|
|
@@ -134,15 +134,15 @@ hand-rolled reviver. This uses the `context.source` argument that
|
|
|
134
134
|
numeric literal is available before it's coerced to a JS `number`:
|
|
135
135
|
|
|
136
136
|
```ts
|
|
137
|
-
import { createClient } from
|
|
137
|
+
import { createClient } from "@clickhouse/client";
|
|
138
138
|
|
|
139
139
|
const parseBigInt = (text: string) =>
|
|
140
140
|
JSON.parse(text, function (key, value, context) {
|
|
141
|
-
if (key.endsWith(
|
|
142
|
-
return BigInt(context.source)
|
|
141
|
+
if (key.endsWith("__bigint")) {
|
|
142
|
+
return BigInt(context.source);
|
|
143
143
|
}
|
|
144
|
-
return value
|
|
145
|
-
})
|
|
144
|
+
return value;
|
|
145
|
+
});
|
|
146
146
|
|
|
147
147
|
const client = createClient({
|
|
148
148
|
json: {
|
|
@@ -150,15 +150,15 @@ const client = createClient({
|
|
|
150
150
|
stringify: JSON.stringify, // use default stringify
|
|
151
151
|
},
|
|
152
152
|
clickhouse_settings: { output_format_json_quote_64bit_integers: 0 },
|
|
153
|
-
})
|
|
153
|
+
});
|
|
154
154
|
|
|
155
155
|
const rs = await client.query({
|
|
156
|
-
query:
|
|
157
|
-
})
|
|
158
|
-
const { data } = await rs.json()
|
|
159
|
-
console.log(data[0].id__bigint) // 250000000000000200
|
|
156
|
+
query: "SELECT toUInt64(250000000000000200) AS id__bigint",
|
|
157
|
+
});
|
|
158
|
+
const { data } = await rs.json();
|
|
159
|
+
console.log(data[0].id__bigint); // 250000000000000200
|
|
160
160
|
|
|
161
|
-
await client.close()
|
|
161
|
+
await client.close();
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
Trade-offs versus `json-bigint`:
|
|
@@ -50,7 +50,7 @@ When answering about storing and reading JSON objects:
|
|
|
50
50
|
## `Dynamic`, `Variant(...)`, `JSON`
|
|
51
51
|
|
|
52
52
|
```ts
|
|
53
|
-
import { createClient } from
|
|
53
|
+
import { createClient } from "@clickhouse/client";
|
|
54
54
|
|
|
55
55
|
const client = createClient({
|
|
56
56
|
clickhouse_settings: {
|
|
@@ -61,7 +61,7 @@ const client = createClient({
|
|
|
61
61
|
allow_experimental_dynamic_type: 1,
|
|
62
62
|
allow_experimental_json_type: 1,
|
|
63
63
|
},
|
|
64
|
-
})
|
|
64
|
+
});
|
|
65
65
|
|
|
66
66
|
await client.command({
|
|
67
67
|
query: `
|
|
@@ -75,16 +75,16 @@ await client.command({
|
|
|
75
75
|
ENGINE MergeTree
|
|
76
76
|
ORDER BY id
|
|
77
77
|
`,
|
|
78
|
-
})
|
|
78
|
+
});
|
|
79
79
|
|
|
80
80
|
await client.insert({
|
|
81
|
-
table:
|
|
82
|
-
format:
|
|
81
|
+
table: "chjs_dynamic_variant_json",
|
|
82
|
+
format: "JSONEachRow",
|
|
83
83
|
values: [
|
|
84
|
-
{ id: 1, var: 42, dynamic:
|
|
85
|
-
{ id: 2, var:
|
|
84
|
+
{ id: 1, var: 42, dynamic: "foo", json: { foo: "x" } },
|
|
85
|
+
{ id: 2, var: "str", dynamic: 144, json: { bar: 10 } },
|
|
86
86
|
],
|
|
87
|
-
})
|
|
87
|
+
});
|
|
88
88
|
|
|
89
89
|
const rs = await client.query({
|
|
90
90
|
query: `
|
|
@@ -95,36 +95,36 @@ const rs = await client.query({
|
|
|
95
95
|
dynamicType(json.bar)
|
|
96
96
|
FROM chjs_dynamic_variant_json
|
|
97
97
|
`,
|
|
98
|
-
format:
|
|
99
|
-
})
|
|
100
|
-
console.log(await rs.json())
|
|
98
|
+
format: "JSONEachRow",
|
|
99
|
+
});
|
|
100
|
+
console.log(await rs.json());
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
Outputs:
|
|
104
104
|
|
|
105
105
|
```js
|
|
106
|
-
|
|
106
|
+
[
|
|
107
107
|
{
|
|
108
|
-
id:
|
|
109
|
-
var:
|
|
110
|
-
dynamic:
|
|
111
|
-
json: { foo:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
id: "1",
|
|
109
|
+
var: "42",
|
|
110
|
+
dynamic: "foo",
|
|
111
|
+
json: { foo: "x" },
|
|
112
|
+
"variantType(var)": "Int64",
|
|
113
|
+
"dynamicType(dynamic)": "String",
|
|
114
|
+
"dynamicType(json.foo)": "String",
|
|
115
|
+
"dynamicType(json.bar)": "None",
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
|
-
id:
|
|
119
|
-
var:
|
|
120
|
-
dynamic:
|
|
121
|
-
json: { bar:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
id: "2",
|
|
119
|
+
var: "str",
|
|
120
|
+
dynamic: "144",
|
|
121
|
+
json: { bar: "10" },
|
|
122
|
+
"variantType(var)": "String",
|
|
123
|
+
"dynamicType(dynamic)": "Int64",
|
|
124
|
+
"dynamicType(json.foo)": "None",
|
|
125
|
+
"dynamicType(json.bar)": "Int64",
|
|
126
126
|
},
|
|
127
|
-
]
|
|
127
|
+
];
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### Notes
|
|
@@ -149,7 +149,7 @@ sub-second precision (`p` digits, up to `9` for nanoseconds). Both require
|
|
|
149
149
|
```ts
|
|
150
150
|
const client = createClient({
|
|
151
151
|
clickhouse_settings: { enable_time_time64_type: 1 },
|
|
152
|
-
})
|
|
152
|
+
});
|
|
153
153
|
|
|
154
154
|
await client.command({
|
|
155
155
|
query: `
|
|
@@ -165,38 +165,38 @@ await client.command({
|
|
|
165
165
|
ENGINE MergeTree
|
|
166
166
|
ORDER BY id
|
|
167
167
|
`,
|
|
168
|
-
})
|
|
168
|
+
});
|
|
169
169
|
|
|
170
170
|
await client.insert({
|
|
171
|
-
table:
|
|
172
|
-
format:
|
|
171
|
+
table: "chjs_time_time64",
|
|
172
|
+
format: "JSONEachRow",
|
|
173
173
|
values: [
|
|
174
174
|
{
|
|
175
175
|
id: 1,
|
|
176
|
-
t:
|
|
177
|
-
t64_0:
|
|
178
|
-
t64_3:
|
|
179
|
-
t64_6:
|
|
180
|
-
t64_9:
|
|
176
|
+
t: "12:34:56",
|
|
177
|
+
t64_0: "12:34:56",
|
|
178
|
+
t64_3: "12:34:56.123",
|
|
179
|
+
t64_6: "12:34:56.123456",
|
|
180
|
+
t64_9: "12:34:56.123456789",
|
|
181
181
|
},
|
|
182
182
|
{
|
|
183
183
|
id: 2,
|
|
184
|
-
t:
|
|
185
|
-
t64_0:
|
|
186
|
-
t64_3:
|
|
187
|
-
t64_6:
|
|
188
|
-
t64_9:
|
|
184
|
+
t: "999:59:59",
|
|
185
|
+
t64_0: "999:59:59",
|
|
186
|
+
t64_3: "999:59:59.999",
|
|
187
|
+
t64_6: "999:59:59.999999",
|
|
188
|
+
t64_9: "999:59:59.999999999",
|
|
189
189
|
},
|
|
190
190
|
{
|
|
191
191
|
id: 3,
|
|
192
|
-
t:
|
|
193
|
-
t64_0:
|
|
194
|
-
t64_3:
|
|
195
|
-
t64_6:
|
|
196
|
-
t64_9:
|
|
192
|
+
t: "-999:59:59",
|
|
193
|
+
t64_0: "-999:59:59",
|
|
194
|
+
t64_3: "-999:59:59.999",
|
|
195
|
+
t64_6: "-999:59:59.999999",
|
|
196
|
+
t64_9: "-999:59:59.999999999",
|
|
197
197
|
},
|
|
198
198
|
],
|
|
199
|
-
})
|
|
199
|
+
});
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
### Notes
|
|
@@ -228,16 +228,16 @@ ClickHouse handle the bit-plane layout — don't feed raw `FixedString` bytes
|
|
|
228
228
|
through JSON yourself.
|
|
229
229
|
|
|
230
230
|
```ts
|
|
231
|
-
import { createClient } from
|
|
231
|
+
import { createClient } from "@clickhouse/client";
|
|
232
232
|
|
|
233
|
-
const tableName = `chjs_qbit
|
|
233
|
+
const tableName = `chjs_qbit`;
|
|
234
234
|
const client = createClient({
|
|
235
235
|
clickhouse_settings: {
|
|
236
236
|
// QBit introduced in ClickHouse 25.10 (experimental), GA since 26.x.
|
|
237
237
|
// This setting is required only on 25.10; harmless/no-op on >= 26.x.
|
|
238
238
|
allow_experimental_qbit_type: 1,
|
|
239
239
|
},
|
|
240
|
-
})
|
|
240
|
+
});
|
|
241
241
|
|
|
242
242
|
await client.command({
|
|
243
243
|
query: `
|
|
@@ -249,7 +249,7 @@ await client.command({
|
|
|
249
249
|
ENGINE MergeTree
|
|
250
250
|
ORDER BY id
|
|
251
251
|
`,
|
|
252
|
-
})
|
|
252
|
+
});
|
|
253
253
|
|
|
254
254
|
// Even though QBit is stored internally as a Tuple of FixedString bit planes,
|
|
255
255
|
// JSON* formats accept (and return) the original Array(Float32) shape.
|
|
@@ -257,21 +257,21 @@ const values = [
|
|
|
257
257
|
{ id: 1, vec: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0] },
|
|
258
258
|
{ id: 2, vec: [8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0] },
|
|
259
259
|
{ id: 3, vec: [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5] },
|
|
260
|
-
]
|
|
260
|
+
];
|
|
261
261
|
await client.insert({
|
|
262
262
|
table: tableName,
|
|
263
|
-
format:
|
|
263
|
+
format: "JSONEachRow",
|
|
264
264
|
values,
|
|
265
|
-
})
|
|
265
|
+
});
|
|
266
266
|
|
|
267
267
|
// Round-trip via JSONEachRow: the vec column comes back as an array of numbers.
|
|
268
268
|
const rs = await client.query({
|
|
269
269
|
query: `SELECT id, vec FROM ${tableName} ORDER BY id`,
|
|
270
|
-
format:
|
|
271
|
-
})
|
|
272
|
-
const rows = await rs.json<{ id: number; vec: number[] }>()
|
|
270
|
+
format: "JSONEachRow",
|
|
271
|
+
});
|
|
272
|
+
const rows = await rs.json<{ id: number; vec: number[] }>();
|
|
273
273
|
// vec comes back unchanged as the original Float32 array.
|
|
274
|
-
console.log(rows)
|
|
274
|
+
console.log(rows);
|
|
275
275
|
|
|
276
276
|
// Approximate vector search via L2DistanceTransposed.
|
|
277
277
|
// The third argument is the precision in bits: lower = less I/O, less accurate.
|
|
@@ -286,13 +286,13 @@ const search = await client.query({
|
|
|
286
286
|
ref: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
|
|
287
287
|
bits: 16,
|
|
288
288
|
},
|
|
289
|
-
format:
|
|
290
|
-
})
|
|
291
|
-
const nearest = await search.json<{ id: number; dist: number }>()
|
|
289
|
+
format: "JSONEachRow",
|
|
290
|
+
});
|
|
291
|
+
const nearest = await search.json<{ id: number; dist: number }>();
|
|
292
292
|
// The reference vector is exactly row #1, so it's the closest match (dist 0).
|
|
293
|
-
console.log(nearest)
|
|
293
|
+
console.log(nearest);
|
|
294
294
|
|
|
295
|
-
await client.close()
|
|
295
|
+
await client.close();
|
|
296
296
|
```
|
|
297
297
|
|
|
298
298
|
### Notes
|
|
@@ -22,11 +22,11 @@ get their declared default.
|
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
24
|
await client.insert({
|
|
25
|
-
table:
|
|
26
|
-
columns: [
|
|
27
|
-
format:
|
|
28
|
-
values: [{ message:
|
|
29
|
-
})
|
|
25
|
+
table: "events",
|
|
26
|
+
columns: ["message"], // the rest of the events table columns get their DEFAULTs
|
|
27
|
+
format: "JSONEachRow",
|
|
28
|
+
values: [{ message: "foo" }],
|
|
29
|
+
});
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Insert excluding columns
|
|
@@ -36,11 +36,11 @@ should default but you want to name only the few to skip.
|
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
38
|
await client.insert({
|
|
39
|
-
table:
|
|
40
|
-
format:
|
|
41
|
-
values: [{ message:
|
|
42
|
-
columns: { except: [
|
|
43
|
-
})
|
|
39
|
+
table: "events",
|
|
40
|
+
format: "JSONEachRow",
|
|
41
|
+
values: [{ message: "bar" }],
|
|
42
|
+
columns: { except: ["id"] },
|
|
43
|
+
});
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
## Tables with EPHEMERAL columns
|
|
@@ -62,18 +62,18 @@ await client.command({
|
|
|
62
62
|
ENGINE MergeTree
|
|
63
63
|
ORDER BY id
|
|
64
64
|
`,
|
|
65
|
-
})
|
|
65
|
+
});
|
|
66
66
|
|
|
67
67
|
await client.insert({
|
|
68
|
-
table:
|
|
69
|
-
format:
|
|
68
|
+
table: "events",
|
|
69
|
+
format: "JSONEachRow",
|
|
70
70
|
values: [
|
|
71
|
-
{ id:
|
|
72
|
-
{ id:
|
|
71
|
+
{ id: "42", message_default: "foo" },
|
|
72
|
+
{ id: "144", message_default: "bar" },
|
|
73
73
|
],
|
|
74
74
|
// Including the ephemeral column name triggers the DEFAULT expression
|
|
75
|
-
columns: [
|
|
76
|
-
})
|
|
75
|
+
columns: ["id", "message_default"],
|
|
76
|
+
});
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
## Insert into a different database
|
|
@@ -82,15 +82,15 @@ If the client's default `database` is not the target, qualify the table name
|
|
|
82
82
|
with `db.table`:
|
|
83
83
|
|
|
84
84
|
```ts
|
|
85
|
-
const client = createClient({ database:
|
|
85
|
+
const client = createClient({ database: "system" });
|
|
86
86
|
|
|
87
|
-
await client.command({ query:
|
|
87
|
+
await client.command({ query: "CREATE DATABASE IF NOT EXISTS analytics" });
|
|
88
88
|
|
|
89
89
|
await client.insert({
|
|
90
|
-
table:
|
|
91
|
-
format:
|
|
92
|
-
values: [{ id: 42, message:
|
|
93
|
-
})
|
|
90
|
+
table: "analytics.events", // fully qualified
|
|
91
|
+
format: "JSONEachRow",
|
|
92
|
+
values: [{ id: 42, message: "foo" }],
|
|
93
|
+
});
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
There is no per-call `database` override on `insert()` / `query()` — qualify
|
|
@@ -27,20 +27,20 @@ When answering "what format/call should I use for an array of JS objects?":
|
|
|
27
27
|
This is the right answer for ~90% of inserts.
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
|
-
import { createClient } from
|
|
30
|
+
import { createClient } from "@clickhouse/client";
|
|
31
31
|
|
|
32
|
-
const client = createClient()
|
|
32
|
+
const client = createClient();
|
|
33
33
|
|
|
34
34
|
await client.insert({
|
|
35
|
-
table:
|
|
36
|
-
format:
|
|
35
|
+
table: "events",
|
|
36
|
+
format: "JSONEachRow",
|
|
37
37
|
values: [
|
|
38
|
-
{ id: 42, name:
|
|
39
|
-
{ id: 43, name:
|
|
38
|
+
{ id: 42, name: "foo" },
|
|
39
|
+
{ id: 43, name: "bar" },
|
|
40
40
|
],
|
|
41
|
-
})
|
|
41
|
+
});
|
|
42
42
|
|
|
43
|
-
await client.close()
|
|
43
|
+
await client.close();
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
The shape of `values` must match the chosen format.
|
|
@@ -60,15 +60,15 @@ The shape of `values` must match the chosen format.
|
|
|
60
60
|
|
|
61
61
|
```ts
|
|
62
62
|
await client.insert({
|
|
63
|
-
table:
|
|
64
|
-
format:
|
|
63
|
+
table: "events",
|
|
64
|
+
format: "JSONCompactEachRowWithNamesAndTypes",
|
|
65
65
|
values: [
|
|
66
|
-
[
|
|
67
|
-
[
|
|
68
|
-
[11,
|
|
69
|
-
[12,
|
|
66
|
+
["id", "name", "sku"],
|
|
67
|
+
["UInt32", "String", "Array(UInt32)"],
|
|
68
|
+
[11, "foo", [1, 2, 3]],
|
|
69
|
+
[12, "bar", [4, 5, 6]],
|
|
70
70
|
],
|
|
71
|
-
})
|
|
71
|
+
});
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
These formats can be **streamed** — pass a Node stream of rows instead of an
|
|
@@ -88,33 +88,33 @@ These cannot be streamed — the entire body is sent in one shot.
|
|
|
88
88
|
| `JSONObjectEachRow` | `Record<string, { col: value, ... }>` (the record key labels each row but is not stored) |
|
|
89
89
|
|
|
90
90
|
```ts
|
|
91
|
-
import type { InputJSON, InputJSONObjectEachRow } from
|
|
91
|
+
import type { InputJSON, InputJSONObjectEachRow } from "@clickhouse/client";
|
|
92
92
|
|
|
93
|
-
const meta: InputJSON[
|
|
94
|
-
{ name:
|
|
95
|
-
{ name:
|
|
96
|
-
]
|
|
93
|
+
const meta: InputJSON["meta"] = [
|
|
94
|
+
{ name: "id", type: "UInt32" },
|
|
95
|
+
{ name: "name", type: "String" },
|
|
96
|
+
];
|
|
97
97
|
|
|
98
98
|
await client.insert({
|
|
99
|
-
table:
|
|
100
|
-
format:
|
|
99
|
+
table: "events",
|
|
100
|
+
format: "JSONCompact",
|
|
101
101
|
values: {
|
|
102
102
|
meta,
|
|
103
103
|
data: [
|
|
104
|
-
[19,
|
|
105
|
-
[20,
|
|
104
|
+
[19, "foo"],
|
|
105
|
+
[20, "bar"],
|
|
106
106
|
],
|
|
107
107
|
},
|
|
108
|
-
})
|
|
108
|
+
});
|
|
109
109
|
|
|
110
110
|
await client.insert({
|
|
111
|
-
table:
|
|
112
|
-
format:
|
|
111
|
+
table: "events",
|
|
112
|
+
format: "JSONObjectEachRow",
|
|
113
113
|
values: {
|
|
114
|
-
row_1: { id: 23, name:
|
|
115
|
-
row_2: { id: 24, name:
|
|
114
|
+
row_1: { id: 23, name: "foo" },
|
|
115
|
+
row_2: { id: 24, name: "bar" },
|
|
116
116
|
} satisfies InputJSONObjectEachRow<{ id: number; name: string }>,
|
|
117
|
-
})
|
|
117
|
+
});
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
## Quick chooser
|