# Node.js 客户端

MyScale 兼容 ClickHouse,因此您可以使用官方的 ClickHouse Node.js 客户端 (opens new window) 来从您的 Node.js 应用程序访问 MyScale。

要安装所需的依赖项,请使用以下命令:

npm i @clickhouse/client

# 创建连接

要了解如何与集群建立连接,请参阅 连接详细信息 部分。

# 创建表

接下来,我们创建一个名为 myscale_categorical_search 的表,它包含 iddatadatelabel 列,并且有一个约束条件,即 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 查询,选择 iddatelabeldata 与样本向量数据之间的距离,使用 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 }
]
Last Updated: Tue May 07 2024 02:28:12 GMT+0000