技术干货

速看!Milvus JavaScript 客户端入门级使用指南

2023-08-11

By Eric Goebelbecker

速看!Milvus JavaScript 客户端入门级使用指南

Milvus 是一款云原生的开源向量数据库,专为向量相似性搜索和 AI 应用赋能。Milvus 支持水平扩展,可以处理海量数据,同时,Milvus 还提供多语言的 SDK (包括 JavaScript)。

使用 Milvus node.js SDK,可以轻松搭建灵活且强大的数据处理系统。Milvus 支持使用 Node.js 连接至服务器,完成各种数据库操作。我们还可以使用 Milvus Nods.js SDK 进行一些列操作,如:创建 Collection(集合)、插入数据、构建索引、查询和搜索数据等。

本文为入门级使用教程,将从如何设置环境、连接至 Milvus 数据库、创建 Collection、进行数据操作(如插入和查询数据)。其中,连接数据库是最为重要的基础性步骤,只有连接 Milvus 数据库后,才能自由探索 Milvus 提供的丰富资源。准备好,3、2、1,开始!

01.前提条件

开始前,请先在开发系统安装所需软件和依赖。由于本教程使用 Milvus Lite,所以请安装:

  • Python 3.8 及以上版本

  • Node.js 12 及以上版本

  • npm 12 及以上版本

  • yarn

02.安装并运行 Milvus Lite

运用 Milvus Lite 这样的 Python 应用的最佳方式就是使用虚拟环境

请先创建、部署环境并升级 pip。

[egoebelbecker@ares examples]$ python3 -m venv ./venv
[egoebelbecker@ares examples]$ source venv/bin/activate
(venv) [egoebelbecker@ares examples]$ pip install --upgrade pip
Requirement already satisfied: pip in ./venv/lib64/python3.11/site-packages (22.3.1)
Collecting pip
Using cached pip-23.2-py3-none-any.whl (2.1 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 22.3.1
Uninstalling pip-22.3.1:
Successfully uninstalled pip-22.3.1
Successfully installed pip-23.2

接着,通过 PyPi 安装 Milvus 向量数据库。

(venv) [egoebelbecker@ares examples]$ pip install milvus
Collecting milvus
  Obtaining dependency information for milvus from <https://files.pythonhosted.org/packages/c1/a6/599ba1f8615e6ec73208ab614f5daf7ab27097070fbbd1715a1b5cc5e578/milvus-2.2.11-py3-none-manylinux2014_x86_64.whl.metadata>
  Downloading milvus-2.2.11-py3-none-manylinux2014_x86_64.whl.metadata (6.7 kB)
Using cached milvus-2.2.11-py3-none-manylinux2014_x86_64.whl (51.7 MB)
Installing collected packages: milvus
Successfully installed milvus-2.2.11
(venv) [egoebelbecker@ares examples]$

最后,运行服务器。

(venv) [egoebelbecker@ares examples]$ milvus-server

    __  _________ _   ____  ______
   /  |/  /  _/ /| | / / / / / __/
  / /|_/ // // /_| |/ / /_/ /\\ \\
 /_/  /_/___/____/___/\\____/___/ {Lite}

 Welcome to use Milvus!

 Version:   v2.2.11-lite
 Process:   505236
 Started:   2023-07-20 14:18:37
 Config:    /home/egoebelbecker/.milvus.io/milvus-server/2.2.11/configs/milvus.yaml
 Logs:      /home/egoebelbecker/.milvus.io/milvus-server/2.2.11/logs

 Ctrl+C to exit ...

03.安装 Milvus node.js SDK

首先,初始化 npm。

[egoebelbecker@ares examples]$ npm init
[egoebelbecker@ares examples]$ npm install @zilliz/milvus2-sdk-node

完成后就可以开始编写代码啦!

04.使用 Javascript 玩转 Milvus

安装完 Milvus 和 JavaScript 之后,就可以开始运用它们了。

##3 连接 Milvus

通过 MilvusClient 连接 Milvus。Milvus 提供多种连接方式,例如:使用用户名密码、服务器地址等。由于本教程使用的是 Milvus Lite 版本,所以连接时只需提供服务器地址即可。

可以通过以下步骤,创建 MilvusClient。通过检查 connectStatus 字段,我们可以查看连接是否成功。

import { MilvusClient } from '@zilliz/milvus2-sdk-node';

const milvusClient = new MilvusClient({
    address: 'localhost:19530',
});

console.log("Connection status: " + milvusClient.connectStatus)

输出结果如下所示:

Connection status: 1

创建向量数据库

大部分 Milvus Javascript API 使用网络请求并返回 promise。这些 Javascript API 不一定会按照在您的代码中的顺序执行,所以,请务必注意 API 执行时间点。您可以借助 promise 链式调用、代码块、await 等手段确保函数按照您指定的顺序执行。

为确保代码易读性,本教程将使用独立的代码块,并在执行完成后打印 promise。在必要时,代码中还会使用 await 作为一种强制指定执行顺序的手段。本教程代码不适用于生产环境,请务必注意。

以下代码通过 createDatabase 创建数据库,使用 await 保证在上一个命令执行完后再执行下一个命令。最后本代码还通过 listDatabases 验证新数据库是否创建成功。

CreateDatabase 只需要提供新数据库名称这 1 个参数值。

import { MilvusClient } from '@zilliz/milvus2-sdk-node';

(async () => {
  const milvusClient = new MilvusClient({
    address: 'localhost:19530',
  });
  console.log("Connection status: " + milvusClient.connectStatus)

  const createDb = await milvusClient.createDatabase({ db_name: 'my_db' });
  console.log('Database is created', createDb);

  const listDatabases = await milvusClient.listDatabases();
  console.log('list databases', listDatabases);
})();

结果如下:

Connection status: 1
Database is created { error_code: 'Success', reason: '' }
list databases {
  db_names: [ 'my_db', 'default' ],
  status: { error_code: 'Success', reason: '' }
}

创建集合(Collection)

数据库创建完成后,我们就可以继续在数据库中创建集合并插入数据。

以下代码在连接 Milvus 后,在 my_db 数据库中通过 createCollection创建新 Collection。创建后,通过 describeCollection检查是否创建成功。创建新 Collection 时需要设置 Schema,定义数据类型。因此,代码中需要导入 DataType。

import { MilvusClient, DataType } from '@zilliz/milvus2-sdk-node';

(async () => {
  const milvusClient = new MilvusClient({
    address: 'localhost:19530',
  });
  console.log('Connection status: ' + milvusClient.connectStatus);

  await milvusClient.use({ db_name: 'my_db' });

  const create = await milvusClient.createCollection({
    collection_name: 'sample_collection',
    fields: [
      {
        name: 'age',
        description: 'ID field',
        data_type: DataType.Int64,
        is_primary_key: true,
        autoID: true,
      },
      {
        name: 'vector',
        description: 'Vector field',
        data_type: DataType.FloatVector,
        dim: 8,
      },
      { name: 'height', description: 'int64 field', data_type: DataType.Int64 },
      {
        name: 'name',
        description: 'VarChar field',
        data_type: DataType.VarChar,
        max_length: 128,
      },
    ],
  });
  console.log('Create collection is finished.', create);

  await milvusClient.describeCollection({ collection_name: 'sample_collection'});

  console.log('describe collection', describeCollection);
 })();

脚本运行成功后会返回新 Collection 信息。

Connection status: 1new Database is using { error_code: 'Success', reason: '' }
Create collection is finished. { error_code: 'Success', reason: '' }
describe collection {
  virtual_channel_names: [ 'by-dev-rootcoord-dml_1_443014985196255045v0' ],
  physical_channel_names: [ 'by-dev-rootcoord-dml_1' ],
  aliases: [],
  start_positions: [],
  properties: [],
  status: { error_code: 'Success', reason: '' },
  schema: {
    fields: [ [Object], [Object], [Object], [Object] ],
    name: 'sample_collection',
    description: '',
    autoID: false,
    enable_dynamic_field: false
  },
  collectionID: '443014985196255045',
  created_timestamp: '443015720996700166',
  created_utc_timestamp: '1689970859515',
  shards_num: 1,
  consistency_level: 'Bounded',
  collection_name: 'sample_collection',
  db_name: 'my_db',
  num_partitions: '1'
}

插入数据、查询数据

插入前先准备数据。以下脚本使用 InsertReq 向新 Collection 中插入数据。

import { MilvusClient, InsertReq } from '@zilliz/milvus2-sdk-node';

(async () => {
  const milvusClient = new MilvusClient({
    address: 'localhost:19530',
  });
  console.log('Connection status: ' + milvusClient.connectStatus);

  const useDb = await milvusClient.use({ db_name: 'my_db' });
  console.log('new Database is using', useDb);

  const vectorsData = [
    {
      vector: [
        0.11878310581111173, 0.9694947902934701, 0.16443679307243175,
        0.5484226189097237, 0.9839246709011924, 0.5178387104937776,
        0.8716926129208069, 0.5616972243831446,
      ],
      height: 20405,
      name: 'zlnmh',
    },
    {
      vector: [
        0.9992090731236536, 0.8248790611809487, 0.8660083940881405,
        0.09946359318481224, 0.6790698063908669, 0.5013786801063624,
        0.795311915725105, 0.9183033261617566,
      ],
      height: 93773,
      name: '5lr9y',
    },
    {
      vector: [
        0.8761291569818763, 0.07127366044153227, 0.775648976160332,
        0.5619757601304878, 0.6076543120476996, 0.8373907516027586,
        0.8556140171597648, 0.4043893119391049,
      ],
      height: 85122,
      name: 'nes0j',
    },
    {
      vector: [
        0.5849602436079879, 0.5108258101682586, 0.8250884731578105,
        0.7996354835509332, 0.8207766774911736, 0.38133662902290566,
        0.7576720055508186, 0.4393152967662368,
      ],
      height: 92037,
      name: 'ct2li',
    },
    {
      vector: [
        0.3768133716738886, 0.3823259261020866, 0.7906232829855262,
        0.31693696726284193, 0.3731715403499176, 0.3300751870649885,
        0.22353556137796238, 0.38062799545615444,
      ],
      height: 31400,
      name: '6ghrg',
    },
    {
      vector: [
        0.0007531778212483964, 0.12941566118774994, 0.9340164428788116,
        0.3795768837758642, 0.4532443258064389, 0.596455163143,
        0.9529469158782906, 0.7692465408044873,
      ],
      height: 1778,
      name: 'sb7mt',
    },
  ];

  const params: InsertReq = {
    collection_name: 'sample_collection',
    fields_data: vectorsData,
  };
  // insert data into collection
  const insert = await milvusClient.insert(params);
  console.log('Inserted data:', insert);
})();

API 返回插入的数据信息。

Connection status: 1
new Database is using { error_code: 'Success', reason: '' }
Inserted data: {
  succ_index: [ 0, 1, 2, 3, 4, 5 ],
  err_index: [],
  status: { error_code: 'Success', reason: '' },
  IDs: { int_id: { data: [Array] }, id_field: 'int_id' },
  acknowledged: false,
  insert_cnt: '6',
  delete_cnt: '0',
  upsert_cnt: '0',
  timestamp: '443015922585698312'
}

数据插入完成后就可以开始查询数据了。在正式开始查询前,可以先为 Collection 构建索引,加速查询。以下代码针对向量字段构建索引。

const createIndex = await milvusClient.createIndex({
   collection_name: 'sample_collection',
   field_name: 'vector',
   metric_type: 'L2',
});

同样,在运行数据查询命令前,仍需要连接 Milvus 数据库。

以下示例在查询数据时设置了年龄的过滤条件。

import { MilvusClient } from '@zilliz/milvus2-sdk-node';

(async () => {
  const milvusClient = new MilvusClient({
    address: 'localhost:19530',
  });

  const useDb = await milvusClient.use({ db_name: 'my_db' });
  console.log('new Database is using', useDb);

  const load = await milvusClient.loadCollectionSync({ collection_name: 'sample_collection' });

  const query = await milvusClient.query({
    collection_name: 'sample_collection',
    filter: 'age > 0',
    output_fields: ['age', 'vector'],
    limit: 100,
  });
  console.log('query result', query);
})();

以下为查询结果:

new Database is using { error_code: 'Success', reason: '' }
Query time: 235.806ms
query result {
  status: { error_code: 'Success', reason: '' },
  data: [
    { vector: [Array], age: '443014985196258910' },
    { vector: [Array], age: '443014985196258911' },
    { vector: [Array], age: '443014985196258912' },
    { vector: [Array], age: '443014985196258913' },
    { vector: [Array], age: '443014985196258914' },
    { vector: [Array], age: '443014985196258915' }
  ]
}

向量搜索

将 Collection 加载到内存后,可以进行向量相似性搜索

import { MilvusClient } from '@zilliz/milvus2-sdk-node';

(async () => {
  const milvusClient = new MilvusClient({
    address: 'localhost:19530',
  });

  const useDb = await milvusClient.use({ db_name: 'my_db' });
  console.log('new Database is using', useDb);

  const load = await milvusClient.loadCollectionSync({ collection_name: 'sample_collection' });

  const query = await milvusClient.search({
    collection_name: 'sample_collection',
    vector: [1,2,3,4,5,6,7,8],
    filter: 'age > 0',
    output_fields: ['id', 'age'],
    limit: 5,
  });
  console.log('query result', query);
})();

以下为搜索结果:

  Search result {
  status: { error_code: 'Success', reason: '' },
  results: [
    { score: 0, id: '442936641561652921', age: '442936641561652921' },
    {
      score: 1.0004949569702148,
      id: '442936641561652924',
      age: '442936641561652924'
    },
    {
      score: 1.6779069900512695,
      id: '442936641561652926',
      age: '442936641561652926'
    },
    {
      score: 1.7160398960113525,
      id: '442936641561652922',
      age: '442936641561652922'
    },
    {
      score: 1.718210220336914,
      id: '442936641561652925',
      age: '442936641561652925'
    }
  ]
}

05.总结

本教程展示了如何部署环境,并使用 JavaScript 玩转 Milvus。文本具体展示了如何连接 Milvus 服务器、创建数据库和 Collection、插入数据、查询数据、进行向量相似性搜索。

如果大家想要更轻松地使用 Milvus,还可以试试 Zilliz Cloud——全托管的向量数据库服务,提供开箱即用的 Milvus 体验。

🌟「寻找 AIGC 时代的 CVP 实践之星」 专题活动即将启动!

Zilliz 将联合国内头部大模型厂商一同甄选应用场景, 由双方提供向量数据库与大模型顶级技术专家为用户赋能,一同打磨应用,提升落地效果,赋能业务本身。

如果你的应用也适合 CVP 框架,且正为应用落地和实际效果发愁,可直接申请参与活动,获得最专业的帮助和指导!联系邮箱为 business@zilliz.com。

Eric Goebelbecker 现居纽约,有着 25 年的金融市场从业经验。他负责为金融资讯交换(FIX)协定网络和市场数据分析系统搭建基础设施。Eric 热衷于探索各种提升团队工作效率的工具和软件。

  • Eric Goebelbecker