# Node.js 客户端
MyScale 兼容 ClickHouse,因此您可以使用官方的 ClickHouse Node.js 客户端 (opens new window) 来从您的 Node.js 应用程序访问 MyScale。
要安装所需的依赖项,请使用以下命令:
npm i @clickhouse/client
# 创建连接
要了解如何与集群建立连接,请参阅 连接详细信息 部分。
# 创建表
接下来,我们创建一个名为 myscale_categorical_search
的表,它包含 id
、data
、date
和 label
列,并且有一个约束条件,即 vector
数组的长度必须为 128。
await client.exec({
query: `
CREATE TABLE default.myscale_categorical_search
(
id UInt32,
data Array(Float32),
CONSTRAINT check_length CHECK length(data) = 128,
date Date,
label Enum8('person' = 1, 'building' = 2, 'animal' = 3)
)
ORDER BY id
`,
});
resultSet = await client.query({ query: "SHOW TABLES" });
dataset = await resultSet.json();
dataset.data.forEach((item) => console.log(item));
示例代码执行结果:
{ name: 'myscale_categorical_search' }
# 导入数据
假设我们有一个如下所示的值创建的数据字典:
const data = [
{
id: 0,
data: [0, 0, 0, 0.01, 0.08, 0.07, 0.03, 0.02, 0.05, 0, 0, 0.03, 0.05, 0.07, 0.11, 0.31, 0.13, 0, 0, 0, 0, 0.29, 1.06, 1.07, 0.13, 0, 0, 0, 0.01, 0.61, 0.7, 0.42, 0, 0, 0, 0, 0.01, 0.23, 0.28, 0.16, 0.63, 0.04, 0, 0, 0, 0.06, 0.83, 0.81, 1.17, 0.86, 0.25, 0.15, 0.17, 0.5, 0.84, 1.17, 0.31, 0.23, 0.18, 0.35, 0.97, 1.17, 0.49, 0.24, 0.68, 0.27, 0, 0, 0, 0.04, 0.29, 0.71, 0.81, 0.47, 0.13, 0.1, 0.32, 0.87, 1.17, 1.17, 0.45, 0.76, 0.4, 0.22, 0.6, 0.7, 0.41, 0.09, 0.07, 0.21, 0.29, 0.39, 0.53, 0.21, 0.04, 0.01, 0.55, 0.72, 0.03, 0, 0, 0, 0, 0.09, 0.65, 1.17, 0.73, 0.37, 0.28, 0.23, 0.17, 0.34, 0.11, 0.11, 0.27, 0.61, 0.64, 0.25, 0.04, 0, 0.42, 0.13, 0.01, 0.01, 0.01, 0.14, 0.1, 0.06],
date: "2030-09-26",
label: "person",
},
{
id: 1,
data: [0.65, 0.35, 0.08, 0, 0, 0, 0.01, 0.63, 0.48, 0.27, 0.31, 0.19, 0.16, 0.34, 0.96, 1.14, 0.03, 0.01, 0.08, 0.21, 0.27, 0.43, 0.57, 0.21, 0.11, 0.08, 0.37, 0.08, 0, 0, 0.01, 0.23, 1.01, 1.04, 0.11, 0, 0, 0, 0, 0.29, 0.83, 1.14, 1.14, 0.77, 0.23, 0.14, 0.18, 0.52, 0.28, 0.08, 0.46, 0.75, 0.39, 0.24, 0.59, 0.6, 0.02, 0, 0.18, 0.1, 0.2, 0.52, 0.52, 0.16, 0.12, 0.28, 0.04, 0, 0, 0.03, 0.05, 0.08, 1.02, 0.79, 0.58, 0.03, 0, 0, 0, 0.11, 1.14, 1.12, 0.78, 0.5, 0.17, 0.14, 0.45, 1.04, 0.19, 0.31, 0.53, 1.14, 0.73, 0.44, 0.34, 0.26, 0.03, 0.02, 0, 0, 0, 0.01, 0.08, 0.09, 0.34, 0.2, 0, 0, 0, 0, 0.01, 0.23, 0.3, 0.75, 0.87, 0.36, 0, 0, 0, 0.02, 0, 0.17, 0.66, 0.73, 0.03, 0, 0, 0],
date: "1996-06-22",
label: "building",
},
{
id: 2,
data: [0, 0, 0, 0, 0, 0, 0.04, 0.01, 0.15, 0, 0, 0, 0, 0, 0.1, 0.49, 0.27, 0, 0, 0, 0, 0.29, 1.13, 1.14, 0.09, 0, 0, 0, 0.03, 0.69, 0.71, 0.42, 0.14, 0, 0, 0, 0, 0.01, 0.56, 0.79, 0.63, 0.02, 0, 0, 0, 0.38, 1.18, 0.77, 1.18, 0.6, 0.08, 0.08, 0.18, 0.48, 0.59, 1.04, 0.27, 0.16, 0.07, 0.13, 0.8, 1.18, 0.34, 0.21, 1.18, 0.47, 0.04, 0, 0, 0.01, 0.32, 0.99, 0.61, 0.4, 0.31, 0.57, 0.46, 1.18, 1.18, 0.61, 0.8, 0.64, 0.16, 0.21, 0.2, 0.33, 0.23, 0.27, 0.06, 0.22, 0.16, 0.14, 0.51, 0.33, 0, 0, 0.76, 0.4, 0.08, 0, 0.02, 0.14, 0.42, 0.94, 0.19, 0.42, 0.57, 0.67, 0.23, 0.34, 0.22, 0.1, 0.09, 0.52, 0.15, 0.21, 0.05, 0.01, 0.03, 0.03, 0.01, 0.38, 0.12, 0.05, 0.18, 0.01, 0, 0],
date: "1975-10-07",
label: "animal",
},
{
id: 3,
data: [0.03, 0.09, 0.45, 0.22, 0.28, 0.11, 0.04, 0.03, 0.77, 0.1, 0.04, 0.01, 0.01, 0.04, 0.03, 0.11, 0.23, 0, 0, 0, 0.26, 0.49, 0.06, 0.07, 0.05, 0.03, 0.03, 0.01, 0.11, 0.5, 0.08, 0.09, 0.11, 0.07, 0.15, 0.21, 0.12, 0.17, 0.21, 0.25, 1.21, 0.12, 0.04, 0.07, 0.04, 0.07, 0.04, 0.41, 0.28, 0.02, 0, 0.01, 0.1, 0.42, 0.22, 0.2, 0.01, 0.01, 0.04, 0.09, 0.31, 0.79, 0.16, 0.03, 0.23, 0.04, 0.06, 0.26, 0.31, 1.21, 0.87, 0.4, 1.21, 0.82, 0.16, 0.12, 0.15, 0.41, 0.06, 0.1, 0.76, 0.48, 0.05, 0.03, 0.21, 0.42, 0.41, 0.5, 0.05, 0.17, 0.18, 0.64, 0.86, 0.54, 0.17, 0.06, 0.43, 0.62, 0.56, 0.84, 1.16, 1.08, 0.38, 0.26, 0.58, 0.63, 0.2, 0.87, 1.05, 0.37, 0.02, 0.02, 1.21, 1.21, 0.38, 0.25, 0.44, 0.33, 0.24, 0.46, 0.03, 0.16, 0.27, 0.74, 1.21, 0.55, 0.09, 0.04],
date: "2024-08-11",
label: "animal",
},
{
id: 4,
data: [0.06, 0.04, 0.03, 0.07, 0.8, 1.22, 0.62, 0.19, 0.02, 0, 0, 0, 0.32, 0.6, 0.1, 0.19, 0.04, 0, 0, 0, 0, 0.1, 0.69, 0.66, 0, 0, 0, 0, 0.08, 0.58, 0.49, 0.05, 0.05, 0.31, 0.59, 0.67, 1.22, 0.37, 0.01, 0.02, 0.5, 0.01, 0, 0.16, 0.99, 0.48, 0.03, 0.27, 1.22, 0.38, 0.06, 0.07, 0.11, 0.31, 0.87, 1.22, 0.09, 0.08, 0.06, 0.23, 1.22, 1.22, 0.69, 0.21, 0, 0.11, 0.31, 0.55, 0.28, 0, 0, 0, 0.61, 0.04, 0, 0.37, 0.43, 0.02, 0, 0.15, 1.22, 1.22, 0.55, 0.32, 0.06, 0.01, 0, 0.12, 0.05, 0.22, 0.52, 1.22, 1.22, 0.09, 0.02, 0, 0.02, 0, 0, 0.05, 0.28, 0.2, 0.02, 0.02, 0.19, 0.03, 0, 0.02, 0.12, 0.12, 0.03, 0.16, 0.25, 0.18, 0.34, 0.35, 0.05, 0.04, 0.01, 0.13, 0.21, 0.02, 0.22, 0.51, 0.09, 0.2, 0.57, 0.59],
date: "1970-01-31",
label: "animal",
},
{
id: 5,
data: [0.06, 0.02, 0.19, 0.22, 0.22, 0.81, 0.31, 0.12, 0.72, 0.15, 0.12, 0.1, 0.03, 0.06, 0.01, 0.37, 0.3, 0.17, 0.04, 0.02, 0.09, 0.04, 0.02, 0.21, 0.01, 0, 0.01, 0.03, 0.11, 0.09, 0.05, 0.02, 0.07, 0.11, 0.17, 0.61, 1.27, 1.27, 0.28, 0.13, 0.49, 0.36, 0.26, 0.45, 0.28, 0.17, 0.04, 0.16, 1.11, 0.46, 0.11, 0.02, 0.07, 0.25, 0.4, 0.89, 0.02, 0, 0.08, 0.31, 0.63, 0.6, 0.28, 0.12, 0, 0.18, 0.82, 1.27, 0.5, 0.01, 0, 0, 0.94, 0.28, 0.11, 0.88, 0.15, 0, 0, 0.04, 1.27, 1.27, 0.34, 0.23, 0.25, 0.18, 0.18, 0.69, 0.06, 0.16, 0.26, 0.9, 1.27, 0.42, 0.12, 0.08, 0, 0.03, 0.46, 0.29, 0, 0, 0, 0, 0.22, 0.35, 0.15, 0.12, 0, 0, 0, 0, 0.46, 1.27, 0.83, 0.17, 0.01, 0, 0, 0, 0, 0.14, 0.67, 1.15, 0.45, 0, 0, 0],
date: "2025-04-02",
label: "building",
},
{
id: 6,
data: [0.19, 0.35, 0.05, 0.06, 0.4, 0.23, 0.18, 0.04, 0.21, 1.09, 1.2, 0.23, 0.05, 0.12, 0.24, 0.05, 0, 0.05, 0.87, 1.08, 0.47, 0.14, 0.32, 0.08, 0, 0, 0, 0.27, 0.36, 0.3, 0.43, 0, 0.29, 0.12, 0.1, 0.15, 0.06, 0.07, 0.17, 0.12, 0.34, 0.09, 0.14, 0.65, 0.2, 0.23, 0.28, 0.14, 1.2, 0.34, 0.14, 0.14, 0.09, 0.34, 1.2, 1.2, 0.07, 0.06, 0.07, 0.27, 0.56, 1.2, 1.2, 0.23, 0.09, 0.05, 0.04, 0.07, 0.02, 0.06, 0.46, 0.13, 0.29, 0.05, 0.05, 0.32, 0.12, 0.2, 0.99, 0.19, 1.2, 1.2, 1.07, 0.38, 0.13, 0.07, 0.24, 0.36, 0.06, 0.24, 1.2, 1.2, 0.55, 0.26, 0.04, 0.03, 0.05, 0.01, 0, 0, 0.01, 0.05, 0.19, 0.18, 0.02, 0.02, 0, 0.01, 0.18, 0.12, 0.3, 0.07, 0, 0.05, 0.33, 0.29, 0.66, 0.5, 0.26, 0.02, 0, 0, 0.49, 0.45, 0.12, 0.28, 0.1, 0],
date: "2007-06-29",
label: "animal",
},
{
id: 7,
data: [0.28, 0.28, 0.28, 0.27, 0.13, 0.05, 0.04, 0.12, 0.04, 0.08, 0.29, 1.18, 0.69, 0.19, 0.21, 0.07, 0.03, 0, 0, 0.14, 0.14, 0.1, 1.05, 0.6, 0, 0, 0, 0, 0.11, 0.69, 0.76, 0.09, 0.05, 0.02, 0.18, 0.59, 0.17, 0.06, 0.01, 0.05, 0.42, 0.09, 0.16, 0.75, 0.31, 0.21, 0.17, 0.13, 1.18, 0.44, 0.18, 0.16, 0.17, 0.3, 0.78, 1.18, 0.04, 0.04, 0.08, 0.61, 1.18, 1.1, 0.54, 0.25, 0.1, 0.06, 0.21, 0.54, 0.05, 0.05, 0.06, 0.05, 0.38, 0.17, 0.11, 0.31, 0.06, 0.24, 0.64, 0.15, 1.15, 1.18, 1.17, 0.61, 0.13, 0.13, 0.22, 0.25, 0.02, 0.11, 0.66, 1.18, 0.87, 0.25, 0.1, 0.02, 0.1, 0.11, 0.03, 0.02, 0.09, 0.28, 0.04, 0.05, 0.21, 0.18, 0.35, 0.17, 0.06, 0.1, 0.04, 0.3, 0.2, 0.02, 0.13, 0.13, 0.07, 0.3, 0.71, 1.18, 0, 0, 0.03, 0.12, 0.5, 1.03, 0.44, 0.05],
date: "1970-09-10",
label: "building",
},
{
id: 8,
data: [0.41, 0.38, 0.21, 0.17, 0.42, 0.71, 0.6, 0.5, 0.11, 0.01, 0.02, 0.11, 1.09, 1.15, 0.08, 0.04, 0.27, 0.08, 0.05, 0.22, 0.11, 0.09, 0.08, 0.14, 0.2, 0.1, 0.04, 0.33, 0.12, 0.07, 0.04, 0.01, 0.18, 1.15, 0.95, 0.42, 0.17, 0.01, 0, 0, 0.19, 0.06, 0.46, 1.15, 0.91, 0.16, 0, 0.07, 0.66, 0.07, 0.04, 0.15, 0.12, 0.32, 0.91, 1.09, 0.12, 0.03, 0.01, 0.08, 0.21, 1.15, 0.96, 0.17, 0.01, 0.51, 0.78, 0.14, 0, 0, 0, 0, 0.5, 0.4, 0.62, 0.53, 0, 0, 0, 0.03, 1.15, 1.15, 0.4, 0.12, 0.06, 0.13, 0.25, 0.65, 0.07, 0.3, 0.51, 0.65, 1.1, 0.92, 0.25, 0.09, 0, 0.01, 0.13, 0, 0, 0, 0, 0, 0.04, 0.22, 0.11, 0.01, 0, 0, 0, 0, 0.13, 1.15, 0.48, 0.01, 0, 0, 0, 0, 0, 0.36, 1.02, 0.63, 0.11, 0, 0, 0],
date: "2007-10-26",
label: "person",
},
{
id: 9,
data: [0, 0, 0, 0, 0, 0.02, 0.06, 0.04, 0, 0, 0, 0, 0, 0.01, 0.44, 0.57, 0, 0, 0, 0, 0, 0.15, 1.25, 0.52, 0, 0, 0, 0, 0.06, 0.57, 0.44, 0.02, 0.23, 0.01, 0, 0, 0, 0.06, 0.2, 0.23, 1.25, 0.3, 0.05, 0.02, 0.01, 0.03, 0.73, 1.25, 0.16, 0.1, 0.11, 0.46, 0.61, 0.97, 1.25, 0.93, 0, 0, 0, 0.31, 1.11, 0.96, 0.21, 0, 0.2, 0.06, 0, 0, 0.09, 1.14, 0.63, 0.05, 1.25, 1.25, 0.83, 0.08, 0.02, 0.26, 0.05, 0.23, 0.14, 0.56, 1.25, 1.25, 0.37, 0.1, 0.07, 0.1, 0.11, 0.02, 0.17, 0.87, 0.42, 0.05, 0.08, 0.19, 0, 0, 0.07, 0.32, 0.56, 0.91, 0.08, 0, 0.01, 0.17, 0.17, 0.03, 0.14, 0.71, 0.15, 0.05, 0.07, 0.09, 0.35, 0.1, 0.02, 0.05, 0.24, 0.39, 0.14, 0.16, 0.04, 0.09, 0.22, 0.06, 0.13, 0.11],
date: "1971-02-02",
label: "building",
},
];
我们可以使用 client.insert
插入数据:
// 查询 'default.myscale_categorical_search' 表中行数的查询。
const dbCountSql = "SELECT count(*) FROM default.myscale_categorical_search";
// 获取并打印在插入之前 'default.myscale_categorical_search' 表中的行数。
resultSet = await client.query({ query: dbCountSql });
dataset = await resultSet.json();
console.log("before insert:", dataset.data[0]);
// 向 'myscale_categorical_search' 表中插入数据。
await client.insert({
table: "myscale_categorical_search",
values: data,
format: "JSONEachRow",
});
// 获取并打印插入之后 'default.myscale_categorical_search' 表中的行数。
resultSet = await client.query({ query: dbCountSql });
dataset = await resultSet.json();
console.log("after insert:", dataset.data[0]);
示例代码执行结果:
before insert: { 'count()': '0' }
after insert: { 'count()': '10' }
# 创建向量索引
MyScale 异步执行创建索引命令,这意味着在索引创建过程中不会阻塞数据库。但是,如果表非常大,创建索引仍然可能需要相当长的时间。因此,在代码中检查索引是否成功创建非常重要。
下面是一个示例代码,用于说明如何检查索引是否已创建:
await client.exec({
query: `
ALTER TABLE default.myscale_categorical_search
ADD VECTOR INDEX categorical_vector_idx data
TYPE MSTG
`,
});
// 查询 'vector_indices' 系统表以检查索引创建的状态。
resultSet = await client.query({
query: `
SELECT status FROM system.vector_indices
WHERE table='myscale_categorical_search'
`,
});
dataset = await resultSet.json();
// 打印索引创建的状态。
// 如果索引创建成功,状态将为 'Built'。
console.log("index build status:", dataset.data[0]);
# 向量搜索
在此示例中,我们执行一个 SQL 查询,选择 id
、date
、label
和 data
与样本向量数据之间的距离,使用 distance
函数。LIMIT 10
子句指定函数应返回前 10 个最近的向量。
// 从数据中随机选择一行作为目标
const targetRowData = data[0].data;
// 获取查询结果
resultSet = await client.query({
query: `
SELECT id, date, label, distance(data, [${targetRowData}]) as dist
FROM default.myscale_categorical_search
ORDER BY dist
LIMIT 10
`,
});
dataset = await resultSet.json();
// 打印结果
console.log("currently selected item:");
console.log(data[0]);
console.log("top 10 candidates:");
console.log(dataset.data);
示例代码执行结果:
currently selected item:
{
id: 0,
data: [
0, 0, 0, 0.01, 0.08, 0.07, 0.03, 0.02, 0.05, 0, 0,
0.03, 0.05, 0.07, 0.11, 0.31, 0.13, 0, 0, 0, 0, 0.29,
1.06, 1.07, 0.13, 0, 0, 0, 0.01, 0.61, 0.7, 0.42, 0,
0, 0, 0, 0.01, 0.23, 0.28, 0.16, 0.63, 0.04, 0, 0,
0, 0.06, 0.83, 0.81, 1.17, 0.86, 0.25, 0.15, 0.17, 0.5, 0.84,
1.17, 0.31, 0.23, 0.18, 0.35, 0.97, 1.17, 0.49, 0.24, 0.68, 0.27,
0, 0, 0, 0.04, 0.29, 0.71, 0.81, 0.47, 0.13, 0.1, 0.32,
0.87, 1.17, 1.17, 0.45, 0.76, 0.4, 0.22, 0.6, 0.7, 0.41, 0.09,
0.07, 0.21, 0.29, 0.39, 0.53, 0.21, 0.04, 0.01, 0.55, 0.72, 0.03,
0,
... 28 more items
],
date: '2030-09-26',
label: 'person'
}
top 10 candidates:
[
{ id: 0, date: '2030-09-26', label: 'person', dist: 0 },
{ id: 2, date: '1975-10-07', label: 'animal', dist: 6.0087996 },
{ id: 7, date: '1970-09-10', label: 'building', dist: 17.4312 },
{ id: 9, date: '1971-02-02', label: 'building', dist: 18.327602 },
{ id: 6, date: '2007-06-29', label: 'animal', dist: 20.485401 },
{ id: 4, date: '1970-01-31', label: 'animal', dist: 20.8502 },
{ id: 3, date: '2024-08-11', label: 'animal', dist: 25.294102 },
{ id: 1, date: '1996-06-22', label: 'building', dist: 27.214201 },
{ id: 5, date: '2025-04-02', label: 'building', dist: 27.3434 },
{ id: 8, date: '2007-10-26', label: 'person', dist: 30.0682 }
]