Java操作向量数据库Milvus

Source

数据库

Milvus 在集合之上引入了数据库层,为管理和组织数据提供了更有效的方式,同时支持多租户。

什么是数据库

在 Milvus 中,数据库是组织和管理数据的逻辑单元。为了提高数据安全性并实现多租户,你可以创建多个数据库,为不同的应用程序或租户从逻辑上隔离数据。例如,创建一个数据库用于存储用户 A 的数据,另一个数据库用于存储用户 B 的数据。

创建数据库

Milvus提供了java sdk

<dependency>
	<groupId>io.milvus</groupId>
	<artifactId>milvus-sdk-java</artifactId>
</dependency>

 在实际项目中一般不会直接通过SDK操作数据库。项目中有多数据源的情况下可以用anyline自带的service按关系型数据库的习惯去操作milvus。

import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.service.database.request.*;

ConnectConfig config = ConnectConfig.builder()
        .uri("http://localhost:19530")
        .token("root:Milvus")
        .build();
MilvusClientV2 client = new MilvusClientV2(config);

CreateDatabaseReq createDatabaseReq = CreateDatabaseReq.builder()
        .databaseName("my_database_1")
        .build();
client.createDatabase(createDatabaseReq);

您还可以在创建数据库时为其设置属性。下面的示例设置了数据库的副本数量。

Map<String, String> properties = new HashMap<>();
properties.put("database.replica.number", "3");
CreateDatabaseReq createDatabaseReq = CreateDatabaseReq.builder()
        .databaseName("my_database_2")
        .properties(properties)
        .build();
client.createDatabase(createDatabaseReq);

查看数据库

您可以使用 Milvus RESTful API 或 SDK 列出所有现有数据库并查看其详细信息。

import io.milvus.v2.service.database.response.*;

ListDatabasesResp listDatabasesResp = client.listDatabases();

DescribeDatabaseResp descDBResp = client.describeDatabase(DescribeDatabaseReq.builder()
        .databaseName("default")
        .build());

管理数据库属性

每个数据库都有自己的属性,您可以在创建数据库时设置数据库属性(如创建数据库中所述),也可以更改和删除任何现有数据库的属性。

下表列出了可能的数据库属性。

属性名称

类型

属性描述

database.replica.number

整数

指定数据库的副本数量。

database.resource_groups

字符串

与指定数据库关联的资源组名称,以通用分隔列表形式显示。

database.diskQuota.mb

整数

指定数据库的最大磁盘空间大小(MB)。

database.max.collections

整数

指定数据库中允许的最大 Collections 数量。

database.force.deny.writing

布尔

是否强制指定的数据库拒绝写操作。

database.force.deny.reading

布尔

是否强制指定的数据库拒绝读取操作。

更改数据库属性

您可以通过以下方式更改现有数据库的属性。下面的示例限制了可以在数据库中创建的 Collections 数量。

client.alterDatabaseProperties(AlterDatabasePropertiesReq.builder()
        .databaseName("my_database_1")
        .property("database.max.collections", "10")
        .build());

删除数据库属性

您还可以通过如下方式删除数据库属性来重置该属性。下面的示例删除了可以在数据库中创建的 Collection 数量限制。

client.dropDatabaseProperties(DropDatabasePropertiesReq.builder()
        .databaseName("my_database_1")
        .propertyKeys(Collections.singletonList("database.max.collections"))
        .build());

使用数据库

你可以在不断开与 Milvus 连接的情况下从一个数据库切换到另一个数据库。

RESTful API 不支持此操作符。

client.useDatabase("my_database_2");
删除数据库
一旦不再需要数据库,就可以删除数据库。请注意

不能丢弃默认数据库。

在丢弃数据库之前,需要先丢弃数据库中的所有 Collections。

你可以使用 Milvus RESTful API 或 SDK 以编程方式创建数据。

client.dropDatabase(DropDatabaseReq.builder()
        .databaseName("my_database_2")
        .build());

创建 Collections

您可以通过定义 Schema、索引参数、度量类型以及创建时是否加载来创建一个 Collection。本页将介绍如何从头开始创建 Collections。

集合概述

Collection 是一个二维表,具有固定的列和变化的行。每列代表一个字段,每行代表一个实体。要实现这样的结构化数据管理,需要一个 Schema。要插入的每个实体都必须符合 Schema 中定义的约束条件。

你可以确定 Collections 的方方面面,包括其 Schema、索引参数、度量类型,以及是否在创建时加载,以确保集合完全满足你的要求。

要创建一个 Collection,您需要

创建 Schema

Schema 定义了 Collections 的数据结构。创建 Collections 时,需要根据自己的要求设计模式。有关详细信息,请参阅Schema Explained

以下代码片段创建了一个模式,其中包含启用的 Dynamic Field 和三个必填字段,分别命名为my_id 、my_vector 和my_varchar 。

import io.milvus.v2.common.DataType;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
        .uri(CLUSTER_ENDPOINT)
        .token(TOKEN)
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 3. Create a collection in customized setup mode

// 3.1 Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();

// 3.2 Add fields to schema
schema.addField(AddFieldReq.builder()
        .fieldName("my_id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .autoID(false)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("my_vector")
        .dataType(DataType.FloatVector)
        .dimension(5)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("my_varchar")
        .dataType(DataType.VarChar)
        .maxLength(512)
        .build());

即时创建 Collections

通过设置名称和向量场维度,可以立即创建一个 Collection。创建时,Milvus 会自动索引向量场并加载 Collections。本页演示如何使用默认设置即时创建 Collections。

集合概述

Collection 是一个二维表,有固定的列和变化的行。每列代表一个字段,每行代表一个实体。实现这种结构化数据管理需要一个 Schema。每个要插入的实体都必须符合 Schema 中定义的约束条件。

AIGC 应用程序通常使用向量数据库作为知识库,管理用户与大型语言模型(LLMs)交互过程中产生的数据。这些知识库几乎是相似的。为了加快 Milvus Collections 在此类场景中的使用,我们提供了一种即时方法,只需两个参数,即 Collections 名称和向量场维度,即可创建一个 Collection。

使用默认设置即时创建 Collections 时,以下设置适用:

  • 主字段和向量字段被添加到 Schema 中(id向量)。

  • 主字段接受整数并禁用AutoId

  • 向量字段接受浮动向量 Embeddings。

  • AUTOINDEX用于在向量字段上创建索引。

  • COSINE用于测量向量嵌入之间的相似性。

  • 启用名为$meta的储备动态字段,可将非 Schema 定义的字段及其值保存为键值对。

  • 该 Collections 会在创建时自动加载。

有关上述术语的详细信息,请参阅《Collection Explained》

值得注意的是,使用默认设置即时创建 Collections 并不适合所有情况。建议您熟悉常用的 Collections 创建程序,以便更好地了解 Milvus 的功能。

快速设置

通过这种方式,您只需输入集合名称和向量场维数,即可即时创建集合。

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.GetLoadStateReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
        .uri(CLUSTER_ENDPOINT)
        .token(TOKEN)
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 2. Create a collection in quick setup mode
CreateCollectionReq quickSetupReq = CreateCollectionReq.builder()
        .collectionName("quick_setup")
        .dimension(5)
        .build();

client.createCollection(quickSetupReq);

GetLoadStateReq quickSetupLoadStateReq = GetLoadStateReq.builder()
        .collectionName("quick_setup")
        .build();

Boolean res = client.getLoadState(quickSetupLoadStateReq);
System.out.println(res);

// Output:
// true

使用自定义字段快速设置

如果默认的度量类型、字段名称和数据类型不能满足您的需求,您可以按以下方式调整这些设置。

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.GetLoadStateReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
        .uri(CLUSTER_ENDPOINT)
        .token(TOKEN)
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 2. Create a collection in quick setup mode
CreateCollectionReq customQuickSetupReq = CreateCollectionReq.builder()
        .collectionName("custom_quick_setup")
        .dimension(5)
        .primaryFieldName("my_id")
        .idType(DataType.VarChar)
        .maxLength(512)
        .vectorFieldName("my_vector")
        .metricType("L2")
        .autoID(true)
        .build();

client.createCollection(customQuickSetupReq);

GetLoadStateReq customQuickSetupLoadStateReq = GetLoadStateReq.builder()
        .collectionName("custom_quick_setup")
        .build();

Boolean res = client.getLoadState(customQuickSetupLoadStateReq);
System.out.println(res);

// Output:
// true

查看收藏集

您可以获取当前连接的数据库中所有 Collections 的名称列表,并查看特定 Collections 的详细信息。

列出收藏集

下面的示例演示了如何获取当前连接的数据库中所有集合的名称列表。

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.response.ListCollectionsResp;

ConnectConfig connectConfig = ConnectConfig.builder()
        .uri("http://localhost:19530")
        .token("root:Milvus")
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

ListCollectionsResp resp = client.listCollections();
System.out.println(resp.getCollectionNames());

如果您已经创建了一个名为quick_setup 的 Collection,则上述示例的结果应类似于下面的内容。

["quick_setup"]

描述 Collection

还可以获取特定 Collection 的详细信息。下面的示例假定您已经创建了名为 quick_setup 的 Collection。

import io.milvus.v2.service.collection.request.DescribeCollectionReq;
import io.milvus.v2.service.collection.response.DescribeCollectionResp;

DescribeCollectionReq request = DescribeCollectionReq.builder()
        .collectionName("quick_setup")
        .build();
DescribeCollectionResp resp = client.describeCollection(request);
System.out.println(resp);
{
    'collection_name': 'quick_setup', 
    'auto_id': False, 
    'num_shards': 1, 
    'description': '', 
    'fields': [
        {
            'field_id': 100, 
            'name': 'id', 
            'description': '', 
            'type': <DataType.INT64: 5>, 
            'params': {}, 
            'is_primary': True
        }, 
        {
            'field_id': 101, 
            'name': 'vector', 
            'description': '', 
            'type': <DataType.FLOAT_VECTOR: 101>, 
            'params': {'dim': 768}
        }
    ], 
    'functions': [], 
    'aliases': [], 
    'collection_id': 456909630285026300, 
    'consistency_level': 2, 
    'properties': {}, 
    'num_partitions': 1, 
    'enable_dynamic_field': True
}

修改 Collections

您可以重命名一个 Collection 或更改其设置。本页主要介绍如何修改 Collection。

重新命名 Collections

您可以按以下方式重命名一个 Collection。

import io.milvus.v2.service.collection.request.RenameCollectionReq;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;

String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
    .uri(CLUSTER_ENDPOINT)
    .token(TOKEN)
    .build();
    
MilvusClientV2 client = new MilvusClientV2(connectConfig);

RenameCollectionReq renameCollectionReq = RenameCollectionReq.builder()
        .collectionName("my_collection")
        .newCollectionName("my_new_collection")
        .build();

client.renameCollection(renameCollectionReq);

设置集合属性

以下代码片段演示了如何设置 Collection TTL。

import io.milvus.v2.service.collection.request.AlterCollectionReq;
import java.util.HashMap;
import java.util.Map;

Map<String, String> properties = new HashMap<>();
properties.put("collection.ttl.seconds", "60");

AlterCollectionReq alterCollectionReq = AlterCollectionReq.builder()
        .collectionName("my_collection")
        .properties(properties)
        .build();

client.alterCollection(alterCollectionReq);

适用的 Collections 属性如下:

属性

何时使用

collection.ttl.seconds

如果需要在特定时间后删除某个 Collection 的数据,可考虑设置其有效时间(TTL),单位为秒。一旦 TTL 超时,Milvus 就会删除 Collection 中的所有实体。 删除是异步的,这表明在删除完成之前,搜索和查询仍然可以进行。详情请参阅设置 Collections TTL

mmap.enabled

内存映射(Mmap)可实现对磁盘上大型文件的直接内存访问,允许 Milvus 在内存和硬盘中同时存储索引和数据。这种方法有助于根据访问频率优化数据放置策略,在不影响搜索性能的情况下扩大 Collections 的存储容量。

有关详情,请参阅使用 mmap

partitionkey.isolation

启用分区密钥隔离后,Milvus 会根据分区密钥值对实体进行分组,并为每个分组创建单独的索引。收到搜索请求后,Milvus 会根据过滤条件中指定的 Partition Key 值定位索引,并将搜索范围限制在索引包含的实体内,从而避免在搜索过程中扫描不相关的实体,大大提高搜索性能。有关详情,请参阅使用 Partition Key Isolation

删除 Collection 属性

您还可以通过删除 Collection 属性来重置该属性,具体方法如下。

client.dropCollectionProperties(DropCollectionPropertiesReq.builder()
        .collectionName("my_collection")
        .propertyKeys(Collections.singletonList("collection.ttl.seconds"))
        .build());

删除 Collections

如果不再需要某个 Collection,您可以删除该 Collection。

示例

以下代码片段假定您有一个名为my_collection 的 Collection。

import io.milvus.v2.service.collection.request.DropCollectionReq;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;

String CLUSTER_ENDPOINT = "http://localhost:19530";
String TOKEN = "root:Milvus";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
        .uri(CLUSTER_ENDPOINT)
        .token(TOKEN)
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

DropCollectionReq dropQuickSetupParam = DropCollectionReq.builder()
        .collectionName("my_collection")
        .build();

client.dropCollection(dropQuickSetupParam);