Introdução ao cliente JavaScript do Milvus
Milvus é um banco de dados robusto de código aberto para busca vetorial. Sua capacidade de escalar horizontalmente para praticamente qualquer carga o torna a melhor escolha para implantações de machine learning. Ele também conta com ferramentas da melhor categoria, inclusive para clientes JavaScript. Neste post, mostraremos como começar a usar Milvus e JavaScript.
O Milvus node.js SDK(Client) permite que você crie recursos flexíveis e poderosos de manipulação de dados diretamente no seu ambiente JavaScript. Ele usa Node.js para se conectar a um servidor Milvus, oferecendo acesso completo a todas as operações do banco de dados. Você pode usar o cliente para criar coleções, inserir dados, criar índices, executar consultas e buscas, e muito mais.
Começaremos configurando o ambiente necessário para executar o código, incluindo uma instância de servidor local. Assim que estivermos funcionando, você passará para a conexão com o banco de dados Milvus. Esta etapa fundamental garante que você esteja conectado aos vastos recursos que o Milvus oferece.
Em seguida, você criará uma coleção no Milvus. Com sua coleção configurada, finalmente entraremos no cerne das operações de dados: inserir e consultar dados.
Vamos começar.
Pré-requisitos
Antes de começar, você precisará ter algumas coisas instaladas no seu sistema de desenvolvimento.
Usaremos o Milvus Lite neste tutorial, portanto você precisará do Python 3.8 ou superior. Você também precisará do Node.js versão 12 ou superior, npm versão 12 ou superior, ou yarn, para instalar pacotes.
Depois de preparar tudo, vamos instalar e executar o Milvus Lite e o JavaScript Client.
Instalar e executar o Milvus Lite
Uma prática recomendada para executar aplicações Python como o Milvus Lite é usar um ambiente virtual. Crie um ambiente, carregue-o e atualize o 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
Em seguida, instale a biblioteca milvus a partir do PyPi.
(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]$
Por fim, execute seu servidor.
(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 ...
Instalar o Milvus node.js SDK(Client)
Primeiro, inicialize o npm no seu diretório de trabalho.
[egoebelbecker@ares examples]$ npm init
[egoebelbecker@ares examples]$ npm install @zilliz/milvus2-sdk-node
Agora, você está pronto para escrever algum código!
Começando com Milvus e JavaScript
Depois de instalar o Milvus e o JavaScript, você está pronto para executar o Milvus e o JavaScript.
Conectar ao Milvus
Você pode se conectar e se comunicar com o Milvus por meio da classe MilvusClient.
O Milvus oferece várias opções de conexão, como nome de usuário, senha e endereço do servidor. Como você está usando o Milvus Lite, só precisa informar onde se conectar.
Crie um MilvusClient e verifique o campo connectStatus para garantir que ele esteja conectado:
import { MilvusClient } from '@zilliz/milvus2-sdk-node';
const milvusClient = new MilvusClient({
address: 'localhost:19530',
});
console.log("Connection status: " + milvusClient.connectStatus)
Aqui está a saída:
Connection status: 1
Criar um banco de dados
Seu servidor está vazio, então vamos começar criando um banco de dados.
A maioria das chamadas da API JavaScript do Milvus envolve uma solicitação de rede, portanto, elas retornam uma promise. Também não há garantia de que sejam executadas na ordem em que você as lista no seu código, então você deve estar atento ao tempo de execução e ao uso de ferramentas como encadeamento de promises, blocos de código e await para garantir que as funções sejam executadas na ordem esperada.
Para tornar o código mais fácil de ler, usarei blocos de código individuais e imprimirei a promise quando ela for concluída. Também usarei await quando necessário como uma abordagem de "força bruta" para garantir que o código seja executado na ordem correta.
Para código de produção, você provavelmente usaria uma abordagem diferente.
Este código cria um banco de dados com createDatabase, usando await para impedir que o código prossiga até que a operação seja concluída. Em seguida, ele verifica se o novo banco de dados existe chamando listDatabases.
CreateDatabase precisa apenas de um nome de banco de dados.
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);
})();
Os resultados são os seguintes:
Connection status: 1
Database is created { error_code: 'Success', reason: '' }
list databases {
db_names: [ 'my_db', 'default' ],
status: { error_code: 'Success', reason: '' }
}
Criar uma coleção
Em seguida, é hora de criar uma coleção para que você possa adicionar alguns dados a ela.
Antes de criar ou usar uma coleção, você precisa usar o banco de dados que a contém. Portanto, após conectar, este script usa my_db.
Então, ele cria a nova coleção com createCollection e a verifica com describeCollection. Uma nova coleção precisa de um esquema com tipos de dados, então você deve importar DataType para o script.
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);
})();
O script é executado com sucesso com informações sobre a nova coleção:
Connection status: 1
new 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'
}
Adicionar e recuperar dados
Agora é hora de adicionar alguns dados à coleção.
Primeiro, precisamos dos dados. Normalmente, seu código lê ou monta dados de algum lugar, mas você usará alguns valores codificados diretamente.
Depois de declarar um array de valores, este script usa um InsertReq para insert por nome na nova coleção:
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);
})();
A API retorna informações sobre o que você inseriu:
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'
}
Agora, você tem alguns dados para consultar. Mas antes de começar a executar consultas em produção, provavelmente adicionaria um índice à sua coleção. Isso adiciona um índice no campo vector:
const createIndex = await milvusClient.createIndex({
collection_name: 'sample_collection',
field_name: 'vector',
metric_type: 'L2',
});
Para executar este código, seu script ainda precisa se conectar e usar o banco de dados associado.
Por fim, você pode executar uma consulta escrita em qualquer expressão ou consulta compatível com o Milvus. Para esta, ela simplesmente filtra itens com base na idade.
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);
})();
Aqui está o resultado:
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' }
]
}
Pesquisar vetores
Depois que sua coleção for carregada na memória, você poderá realizar uma pesquisa de similaridade vetorial nela.
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);
})();
Aqui está o resultado:
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'
}
]
}
Resumo
Configuramos um ambiente de desenvolvimento para trabalhar com Milvus e o Milvus JavaScript. Conectamos a um servidor, criamos um banco de dados e uma coleção, inserimos dados e os recuperamos, além de realizar pesquisas de similaridade vetorial. Como você viu, trabalhar com dados vetoriais em JavaScript com o Milvus não poderia ser mais simples!
Adicione o poder da pesquisa vetorial aos seus aplicativos web hoje mesmo! Enquanto faz isso, dê uma olhada em uma avaliação gratuita do Zilliz Cloud e veja como você pode ter um cluster Milvus pronto para a nuvem, confiável e de alto desempenho em execução em minutos.
Sobre o autor
Este post foi escrito por Eric Goebelbecker. Eric trabalhou nos mercados financeiros na cidade de Nova York por 25 anos, desenvolvendo infraestrutura para redes de dados de mercado e do protocolo de troca de informações financeiras (FIX). Ele adora falar sobre o que torna as equipes eficazes (ou não tão eficazes!).
Continue lendo

The AWS Outage Was a Wake-Up Call for Vector Database Cross-Region Disaster Recovery
Zilliz Cloud Had the Answer Before the Crisis. Zilliz Cloud is the world's first vector database with native cross-region disaster recovery.

Cosmos World Foundation Model Platform for Physical AI
NVIDIA's Cosmos platform enables safe, digital twin training of GenAI models for physical applications, overcoming data scarcity and safety challenges.

Similarity Metrics for Vector Search
Exploring five similarity metrics for vector search: L2 or Euclidean distance, cosine distance, inner product, and hamming distance.



