upsertData 用于在指定的数据集 Collection 内写入数据。指定写入的数据是一个数组,允许单次插入一条数据或者多条数据,单次最多可插入100条数据。
对 V1 版本的 upsertData 接口进行了调整(仅影响含 vectorize/pipeline 配置的需要向量化数据集,已带 vector 类型字段的数据集不受影响),核心信息如下:
need_token_usage 参数信息。参数名 | 子参数 | 类型 | 是否必选 | 参数说明 |
|---|---|---|---|---|
DataObject | fields | array | 是 | 指定写入的数据。
|
TTL | integer | 否 | 数据过期时间,单位为秒。
| |
async_upsert | bool | 否 | 对于“需要向量化”的数据集:本参数仅区分是否流式更新。
对于“已有向量数据”的数据集:异步写入开关。
|
运行示例前,请完成以下准备:
- 在 Java 项目中引入 VikingDB SDK,并将示例放入可执行的
main方法后编译运行。- 将
<YOUR_HOST>、<YOUR_REGION>和<YOUR_SCHEME>替换为地域和访问域名中与实例一致的服务地址、地域和协议。- 将
<YOUR_AK>、<YOUR_SK>替换为火山引擎控制台“密钥管理”中创建的 Access Key ID 和 Secret Access Key;请勿把真实凭证提交到代码仓库。- 将 Collection、Index、Task 等资源占位符替换为控制台中对应资源的名称或接口返回的 ID。若示例包含 TOS 路径,请从 TOS 控制台确认桶名和对象路径,并使用
tos://<YOUR_BUCKET_NAME>/<YOUR_OBJECT_KEY>或文档要求的路径格式。
//getCollection获取指定数据集,程序初始化时调用即可,无需重复调用 collectionClient = new CollectionClient("<YOUR_COLLECTION_NAME>", "api-vikingdb.volces.com", "cn-beijing", "<YOUR_AK>", "<YOUR_SK>", "http");
//构建向量 HashMap<String,Object> field1 = new HashMap<String,Object>(); List<String> author1 = new ArrayList<>(); author1.add("name1"); author1.add("name2"); field1.put("doc_id", "11"); field1.put("text_vector", genRandomVector(12)); field1.put("text_sparse_vector", Map.of("hello", 0.34f, "world", 0.03f, "!", 0.11f)); field1.put("like", 1); field1.put("price", 1.11); field1.put("aim", true); field1.put("author", author1); DataObject dataObject1 = new DataObject() .setFields(field1) .build(); HashMap<String,Object> field2 = new HashMap<String,Object>(); List<String> author2 = new ArrayList<>(); author2.add("name3"); author2.add("name4"); field2.put("doc_id", "22"); field2.put("text_vector", genRandomVector(12)); field2.put("text_sparse_vector", {"hi": 0.12, "there": 0.043, "!": 0.5}); field2.put("like", 2); field2.put("price", 1.11); field2.put("aim", false); field2.put("author", author2); DataObject dataObject2 = new DataObject() .setFields(field2) .build(); HashMap<String,Object> field3 = new HashMap<String,Object>(); List<String> author3 = new ArrayList<>(); author3.add("name5"); author3.add("name6"); field3.put("doc_id", "33"); field3.put("text_vector", genRandomVector(12)); field3.put("text_sparse_vector", {"hi": 0.12, "there": 0.043, "!": 0.5}); field3.put("like", 3); field3.put("price", 3.33); field3.put("aim", false); field3.put("author", author3); DataObject dataObject3 = new DataObject() .setFields(field3) .build(); HashMap<String,Object> field4 = new HashMap<String,Object>(); List<String> author4 = new ArrayList<>(); author4.add("name7"); author4.add("name8"); field4.put("doc_id", "44"); field4.put("text_vector", genRandomVector(12)); field4.put("text_sparse_vector", {"hi": 0.12, "there": 0.043, "!": 0.5}); field4.put("like", 4); field4.put("price", 4.44); field4.put("aim", false); field4.put("author", author4); DataObject dataObject4 = new DataObject() .setFields(field4) .build(); List<DataObject> dataObjects = new ArrayList<>(); dataObjects.add(dataObject1); dataObjects.add(dataObject2); dataObjects.add(dataObject3); dataObjects.add(dataObject4); collectionClient.upsertData(dataObjects);
异步写入数据示例:
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(); } CollectionClient collectionClient = null; try { collectionClient = new CollectionClient("<YOUR_COLLECTION_NAME>", "api-vikingdb.volces.com", "cn-beijing", "<YOUR_AK>", "<YOUR_SK>", "http"); } 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 { collectionClient.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); UUID uuid4 = UUID.randomUUID(); HashMap<String,Object> field = new HashMap<String,Object>(); field.put("id", uuid4); field.put("text_vector", floatArray); 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..."); } }
Java 调用执行上面的任务,执行成功无返回信息。
向量字段必须传浮点数数组。Java 示例直接把 float[] floatArray 写入 field.put("text_vector", floatArray),不再转为 Base64 字符串。
async_upsert=true 表示异步写入:接口接收后后台处理,数据可见存在延迟;async_upsert=false 或省略表示同步写入:请求在本批写入处理完成后返回。已带向量字段的数据集使用同步模式;需要后台向量化时使用异步模式。