以下最佳实践基于旧版API实现,后续我们会基于新版API V2更新,若使用新版API V2想参考最佳实践请联系我们。
以下最佳实践基于新版本的控制台前端及新版本的API V1 实现,请您关注自己的版本对应使用:
如何判断自己是否是旧版本:
若您是2025.08.14前开通的用户,页面如下图所示,则为旧版本。
若您是2025.08.14后开通的用户则无法使用此版本,请使用新版本,具体可参考向量库新版本(V2)快速入门
若您已升级为新版本,也可通过下图左上角按钮切换为旧版本,使用旧版本下的数据集。但不推荐您新的场景使用旧版本。
向量数据库 VikingDB 是构建于火山引擎的云基础设施之上的向量数据库系统,其核心功能涵盖了对机器学习模型产生的海量向量数据进行生产、存储、索引以及分析等操作。
在本指南里,我们会引导您在短短几分钟内迅速完成首个向量库的开通、配置工作,让您能够在我们的配置页面走完数据集创建、索引创建以及检索查询的全部流程。
分为以下三个步骤:
登录 火山引擎控制台,找到 VikingDB,根据对应的提示按需开通 向量数据库服务。
创建数据集有两种方式:
text、image 类型字段仅作为存储数据用途,不会用于向量化,字段名称也不能与向量化字段重复。编号 | 参数名称 | 参数说明 |
|---|---|---|
1 | 基础信息(必填) |
|
2 | 向量信息(必填) |
|
3 | 字段配置(选填) |
|
4 | 主键(必填) |
|
5 | 费用细则与创建数据集 |
|
数据写入现在支持在线同步写入、在线异步写入、本地数据导入和单条数据插入四种形式。
适用于在线服务数据实时写入生效场景,提供流式写入接口。
# 使用 pip 安装 SDK for Python,支持 Python 3.7 及其以上版本 pip3 install --user volcengine
//推荐通过 Maven 依赖使用火山引擎 SDK for Java <dependency> <groupId>com.volcengine</groupId> <artifactId>volc-sdk-java</artifactId> <version>最新版本</version> </dependency>
//安装 SDK for Go,支持Go 1.14及其以上版本 go get -u github.com/volcengine/volc-sdk-golang
//推荐使用 pnpm 管理依赖,请使用 Node version >= 12,SDK 版本 >= 1.19.0 pnpm add @volcengine/openapi
from volcengine.viking_db import * vikingdb_service = VikingDBService("host", "region") vikingdb_service.set_ak("Your ak") vikingdb_service.set_sk("Your sk")
VikingDBService vikingDBService = new VikingDBService("host", "region", "Your ak", "Your sk", "scheme"); //获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 //Java SDK 接入指南
service := vikingDB.NewVikingDBService("host", "region", "Your ak", "Your sk", "scheme"); //获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 //Go SDK 接入指南
import { vikingdb } from '@volcengine/openapi' const vikingdbService = new vikingdb.VikingdbService({ ak: 'Your ak', sk: 'Your sk', region: 'Your region', }) // 获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 // NodeJS 接入指南
在写入数据时请根据选择"从向量化开始"或"已有向量数据"来决定上传时需要写入的参数。
请注意:根据所选数据集创建方式,vector字段和text字段只能选择一个进行上传。
# 获取指定数据集,程序初始化时调用即可,无需重复调用 collection = vikingdb_service.get_collection("example") def gen_random_vector(dim): # 构建指定维度的随机向量 return [random.random() - 0.5 for _ in range(dim)] # 生成随机向量 # field中的字段名称根据所建立数据集的字段名称而定 field = { "doc_id": "11", # 如果选择“从向量化开始”,请根据需求上传需要向量化的字段“text”,“image” "text": "这是一段需要自动embedding的文本示例", # 若需要上传多模态数据,请先将图片上传至TOS,并将图片存储路径传入"image"字段 "image": "tos://your-bucket-name/path/to/image.jpg", # 图片存储路径 # 如果选择“已有向量数据”,请将已有向量上传至"text_vector"字段。 #"text_vector": gen_random_vector(12), # 生成12维随机向量 "price": 1.11, "author": ["zh"], "aim": True, } data = Data(field) collection.upsert_data([data]) # 插入或更新单条数据 async def upsert_data(): collection = await vikingdb_service.async_get_collection("async") # 异步上传示例数据 field = { "doc_id": "111", "text_vector": gen_random_vector(10), # 生成10维随机向量 "like": 1, "price": 1.11, "author": ["gy"], "aim": True, } data = Data(field) await collection.async_upsert_data([data]) # 异步插入或更新单条数据 asyncio.run(upsert_data())
//getCollection获取指定数据集,程序初始化时调用即可,无需重复调用 Collection collection = vikingDBService.getCollection("javaSDKTest"); // 构建向量方法 HashMap<String, Object> field = new HashMap<>(); List<String> authors = new ArrayList<>(); authors.add("name1"); authors.add("name2"); // 填充示例数据 field.put("doc_id", "11"); field.put("text_sparse_vector", Map.of("hello", 0.34, "world", 0.03, "!", 0.11)); // 稀疏向量 // 如果选择“从向量化开始”,请根据需求上传需要向量化的字段"text"和"image" field.put("text", "这是一段需要自动embedding的文本示例"); // 若需要上传多模态数据,请先将图片上传至TOS,并将图片存储路径传入"image"字段 // 如果选择“已有向量数据”,请将已有向量上传至"text_vector"字段。 //field.put("text_vector", genRandomVector(12)); // 生成12维随机向量 field.put("image", "tos://your-bucket-name/path/to/image.jpg"); field.put("like", 1); field.put("price", 1.11); field.put("aim", true); field.put("author", authors); // 创建 DataObject DataObject dataObject = new DataObject() .setFields(field) .build(); // 写入数据到集合 collection.upsertData(Collections.singletonList(dataObject)); // 插入单条数据 //获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 //Java SDK 接入指南
//GetCollection获取指定数据集,程序初始化时调用即可,无需重复调用 collection, _ := service.GetCollection("go") //构建向量 field1 := map[string]interface{}{ "doc_id": "111", "text_sparse_vector":map[string]float64{"hello": 0.34, "world": 0.03, "!": 0.11} "text": "这是一段需要自动embedding的文本示例", // 新增字段 "image": "tos://your-bucket-name/path/to/image.jpg", // 新增字段 //"text_vector": genRandomVector(12), "like": 1, "price": 1.11, "author": []string{"gy"}, "aim": true, } data1 := vikingdb.Data{ Fields: field1, } datas := []vikingdb.Data{ data1, } err := collection.UpsertData(datas) if err != nil { print(err.Error()) } //获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 //Go SDK 接入指南
import { vikingdb } from '@volcengine/openapi' declare const service: vikingdb.VikingdbService // 替换为你初始化好的实例 await service.data.UpsertData({ CollectionName: 'test_collection_1', Fields: [ { Id: 1, Name: 'Tom' }, { Id: 2, Name: 'Jerry' }, ], }) // 获取更多数据写入信息,请参阅我们的文档获取详细信息和示例。 // NodeJS 接入指南
完成SDK安装与初始化的基础上,您可以使用在线异步写入的方式写入数据。
异步写入可以提供比同步写入大10倍的写入带宽,适用于更大规模数据量级的实时更新场景。
import multiprocessing import struct, base64, uuid, tqdm, time from volcengine.viking_db import * queue = multiprocessing.Queue(maxsize=10) event = multiprocessing.Event() def consumer(): """消费者函数:从队列中取出数据并处理""" vikingdb_service = VikingDBService() vikingdb_service.set_ak("ak") vikingdb_service.set_sk("sk") collection = vikingdb_service.get_collection("") items = [] while not event.is_set() or not queue.empty(): item = queue.get() items.append(item) if len(items) == 50: collection.upsert_data(items, async_upsert=True) items = [] print("Consumer received event. Exiting...") if __name__ == "__main__": # 创建消费者进程 processors = [] for i in range(10): p = multiprocessing.Process(target=consumer) p.start() processors.append(p) datas = [] # 准备数据 for i in range(100000): # 压缩向量 float_array = [0.124135132531424]*1024 packed_data = struct.pack('f'*len(float_array), *float_array) s = base64.b64encode(packed_data).decode() uuid4 = uuid.uuid4() # 此处用户可修改为自己希望的id datas.append(Data({"id": str(uuid4), "text_vertor": s})) for data in tqdm.tqdm(datas): queue.put(data) event.set() # 通知消费者停止工作 for p in processors: p.join() print("Main process exiting...")
class Consumer implements Runnable { private final LinkedBlockingQueue<DataObject> queue; private final AtomicBoolean event; public Consumer(LinkedBlockingQueue<DataObject> queue, AtomicBoolean event) { this.queue = queue; this.event = event; } @Override public void run() { VikingDBService vikingdbService = null; try { vikingdbService = new VikingDBService(); } catch (Exception e) { e.printStackTrace(); } Collection collection = null; try { collection = vikingdbService.getCollection(""); } catch (Exception e) { e.printStackTrace(); } List<DataObject> items = new ArrayList<>(); while (!event.get() || !queue.isEmpty()) { try { DataObject item = queue.poll(1, TimeUnit.SECONDS); if (item != null) { items.add(item); if (items.size() == 50) { try { collection.upsertData(items, true); } catch (Exception e) { e.printStackTrace(); } items.clear(); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } System.out.println("Consumer received event. Exiting..."); } } public class test { public static List<Double> genRandomVector(int dim){ List<Double> res = new ArrayList<>(); for(int i=0;i<dim;i++){ res.add(new Random().nextDouble()); } return res; } public static void main(String[] args) throws Exception { VikingDBService vikingDBService = new VikingDBService(); LinkedBlockingQueue<DataObject> queue = new LinkedBlockingQueue<>(10); AtomicBoolean event = new AtomicBoolean(false); List<Thread> processors = new ArrayList<>(); for (int i = 0; i < 10; i++) { Thread p = new Thread(new Consumer(queue, event)); p.start(); processors.add(p); } int num = 10000; List<DataObject> datas = new ArrayList<>(); for (int i = 0; i < num; i++) { float[] floatArray = new float[1024]; Arrays.fill(floatArray, 0.124135132531424f); ByteBuffer byteBuffer = ByteBuffer.allocate(floatArray.length * Float.BYTES); byteBuffer.asFloatBuffer().put(floatArray); String s = Base64.getEncoder().encodeToString(byteBuffer.array()); UUID uuid4 = UUID.randomUUID(); HashMap<String,Object> field = new HashMap<String,Object>(); field.put("id", uuid4); field.put("text_vector", s); DataObject dataObject = new DataObject() .setFields(field) .build(); datas.add(dataObject); } ProgressBar pb = new ProgressBar("Processing", num); for (DataObject data : datas) { queue.put(data); pb.step(); } pb.close(); event.set(true); for (Thread p : processors) { p.join(); } System.out.println("Main process exiting..."); } }
var wg sync.WaitGroup func consumer(queue <-chan vikingdb.Data, vikingDBService *vikingdb.VikingDBService, stopChan <-chan struct{}) { defer wg.Done() collection, err := vikingDBService.GetCollection("") if err != nil { fmt.Println(err) } items := make([]vikingdb.Data, 0, 50) for { select { case item := <-queue: items = append(items, item) if len(items) == 50 { collection.UpsertData(items, vikingdb.WithAsyncUpsert(true)) items = items[:0] } case <-stopChan: if len(items) > 0 { collection.UpsertData(items, vikingdb.WithAsyncUpsert(true)) } return } } } func main() { queue := make(chan vikingdb.Data, 10) stopChan := make(chan struct{}) vikingDBService := vikingdb.NewVikingDBService() // 创建消费者 for i := 0; i < 10; i++ { wg.Add(1) go consumer(queue, vikingDBService, stopChan) } // 准备数据 num := 10000 floatArray := make([]float32, 1024) for j := range floatArray { floatArray[j] = 0.124135132531424 } var datas []vikingdb.Data for i := 0; i < num; i++ { packedData := make([]byte, 1024*4) for j, v := range floatArray { binary.LittleEndian.PutUint32(packedData[j*4:], math.Float32bits(v)) } s := base64.StdEncoding.EncodeToString(packedData) id := uuid.New().String() field := map[string]interface{}{ "id": id, "text_vector": s, } datas = append(datas, vikingdb.Data{Fields: field}) } progressBar := pb.StartNew(num) for _, data := range datas { queue <- data progressBar.Increment() } close(stopChan) progressBar.Finish() // 等待所有消费者完成工作 wg.Wait() fmt.Println("Main process exiting...") }
若需要上传多模态数据,请先将图片上传至TOS,并将图片的tos存储路径传入"image"字段。
{"animal_image": "tos://best-practice-pic-search-tos/pic_search_1000_images/0009fc27d9.jpg"}
具体执行逻辑可参考如下流程图。
# 使用 pip 安装 SDK for Python,支持 Python 3.7 及其以上版本 pip3 install --user volcengine
//安装 SDK for Go,支持Go 1.14及其以上版本 go get -u github.com/volcengine/volc-sdk-golang
//推荐通过 Maven 依赖使用火山引擎 SDK for Java <dependency> <groupId>com.volcengine</groupId> <artifactId>volc-sdk-java</artifactId> <version>最新版本</version> </dependency>
您可以下载代码样例文件后通过文件导入本地数据
pythonDemo.py
您可以下载代码样例文件后通过文件导入本地数据
goDemo.go
您可以下载代码样例文件后通过文件导入本地数据
javaDemo.java
本地数据导入时,如果您需要上传多模态信息,也请上传tos地址。
此外,你还可以在数据集详情页面插入单条数据
写入数据后,您可以在数据集详情页面通过主键对数据进行查询
如您在第一步中按示例创建了数据集,并完成了SDK的初始化,您可以使用以下代码写入一份测试数据。
import asyncio import nest_asyncio nest_asyncio.apply() # 异步插入数据函数 async def upsert_data(): try: # 获取异步集合对象 collection = await vikingdb_service.async_get_collection("VikingDB_Example") fields = [ # 数据内容 {"ID": 1, "description": "苹果是红色的", "title": "水果", "date": "202408"}, {"ID": 2, "description": "香蕉是黄色的", "title": "水果", "date": "202408"}, {"ID": 3, "description": "苹果长在苹果树上", "title": "水果", "date": "202410"}, {"ID": 4, "description": "鱼生活在水里", "title": "动物", "date": "202411"}, {"ID": 5, "description": "欢迎使用VikingDB", "title": "欢迎", "date": "202412"} ] datas = [ # 构造数据对象列表 Data({ "ID": str(field["ID"]), # 文档唯一标识符 "description": field["description"], # 文本描述 "title": field["title"], # 数据分类 "date": field["date"] # 日期字段 }) for field in fields ] await collection.async_upsert_data(datas) # 异步插入或更新数据 print("数据插入完成!") # 日志输出 except Exception as e: # 捕获并处理可能的异常 print(f"插入数据时发生错误: {e}") # 执行异步函数 await upsert_data()
func main() { collection := vikingdb.GetCollection("VikingDB_Example") // 获取指定数据集 // 数据内容 field1 := map[string]interface{}{ "ID": 1, "description": "苹果是红色的", "title": "水果", "date": "202408", } field2 := map[string]interface{}{ "ID": 2, "description": "香蕉是黄色的", "title": "水果", "date": "202408", } field3 := map[string]interface{}{ "ID": 3, "description": "苹果长在苹果树上", "title": "水果", "date": "202410", } field4 := map[string]interface{}{ "ID": 4, "description": "鱼生活在水里", "title": "动物", "date": "202411", } field5 := map[string]interface{}{ "ID": 5, "description": "欢迎使用VikingDB", "title": "欢迎", "date": "202412", } // 创建数据对象 data1 := vikingdb.Data{ Fields: field1, } data2 := vikingdb.Data{ Fields: field2, } data3 := vikingdb.Data{ Fields: field3, } data4 := vikingdb.Data{ Fields: field4, } data5 := vikingdb.Data{ Fields: field5, } datas := []vikingdb.Data{data1, data2, data3, data4, data5}// 将数据对象添加到数据列表 err := collection.UpsertData(datas) // 执行数据插入 if err != nil { log.Fatal("插入数据时发生错误:", err) } else { fmt.Println("数据插入完成!") } }
import java.util.*; public class VikingDBExample { public static void main(String[] args) { try { // 获取指定数据集 Collection collection = vikingDBService.getCollection("VikingDB_Example"); List<Map<String, Object>> fieldsList = Arrays.asList( // 数据内容 createField(1, "苹果是红色的", "水果", "202408"), createField(2, "香蕉是黄色的", "水果", "202408"), createField(3, "苹果长在苹果树上", "水果", "202410"), createField(4, "鱼生活在水里", "动物", "202411"), createField(5, "欢迎使用VikingDB", "欢迎", "202412") ); List<DataObject> dataObjects = new ArrayList<>(); for (Map<String, Object> field : fieldsList) { dataObjects.add(new DataObject().setFields(field).build()); } collection.upsertData(dataObjects); // 执行数据插入 System.out.println("数据插入完成!"); } catch (Exception e) { e.printStackTrace(); System.out.println("插入数据时发生错误: " + e.getMessage()); } } private static Map<String, Object> createField(int id, String description, String title, String date) { Map<String, Object> field = new HashMap<>(); field.put("ID", id); field.put("description", description); field.put("title", title); field.put("date", date); return field; } }
import { vikingdb } from '@volcengine/openapi'; declare const service: vikingdb.VikingdbService // 替换为你初始化好的实例 // 准备要插入的数据 const fields = [ { Id: 1, description: "苹果是红色的", title: "水果", date: "202408" }, { Id: 2, description: "香蕉是黄色的", title: "水果", date: "202408" }, { Id: 3, description: "苹果长在苹果树上", title: "水果", date: "202410" }, { Id: 4, description: "鱼生活在水里", title: "动物", date: "202411" }, { Id: 5, description: "欢迎使用VikingDB", title: "欢迎", date: "202412" } ]; // 插入数据函数 async function insertData() { try { // 使用 UpsertData 插入数据 await service.data.UpsertData({ CollectionName: 'VikingDB_Example', // 指定集合名称 Fields: fields, // 数据字段 }); console.log("数据插入完成!"); } catch (error) { console.error("插入数据时发生错误:", error); } } // 执行插入数据操作 insertData();
此外,我们在开始使用页面还为您准备了探索指南,您可以根据需要按照指引深入探索VikingDB向量数据库: