接口定义
upsert() 接口用于给创建的 Collection 中插入 Document。如果 Collection 在创建时,已配置 Embedding 参数,则仅需要插入文本信息,Embedding 服务会自动将文本信息转换为向量数据,存入数据库。
public AffectRes upsert(String database, String collection, InsertParam param)
使用示例
说明:
在插入数据时, Collection 中已经存在相同 ID 的 Document,则会删除源 Document 后插入新的 Document 数据。
如果 Collection 在创建时,配置 Embedding 参数,则插入文本,Embedding 服务会自动将文本信息转换为向量数据,存入数据库。
如果您使用 Embedding 功能,在 createCollection() 建表时,配置 Embedding 模型相关参数之后,便可以通过 upsert() 接口可直接传入原始文本。Embedding 模型会将原始文本转换为向量数据,并将转换后的向量数据以及原始文本一并存入数据库。具体信息,请参见 Embedding 介绍。如下示例,基于 createCollection() 创建的集合 book-emb,写入原始文本。
Document doc1 = Document.newBuilder().withId("0001").addDocField(new DocField("text", "话说天下大势,分久必合,合久必分。")).addDocField(new DocField("bookName", "三国演义")).addDocField(new DocField("author", "罗贯中")).addDocField(new DocField("page", 21)).addDocField(new DocField("tags", Arrays.asList("曹操","诸葛亮","刘备"))).build();Document doc2 = Document.newBuilder().withId("0002").addDocField(new DocField("text","正大光明,混沌未分天地乱,茫茫渺渺无人间。")).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).addDocField(new DocField("page", 22)).addDocField(new DocField("tags", Arrays.asList("孙悟空","猪八戒","唐僧"))).build();Document doc3 = Document.newBuilder().withId("0003").addDocField(new DocField("text", "甄士隐梦幻识通灵,贾雨村风尘怀闺秀。")).addDocField(new DocField("bookName", "红楼梦")) .addDocField(new DocField("author", "曹雪芹")) .addDocField(new DocField("page", 23)) .addDocField(new DocField("tags", Arrays.asList("贾宝玉","林黛玉","王熙凤"))).build();InsertParam insertParam = InsertParam.newBuilder().addDocument(doc1).addDocument(doc2).addDocument(doc3).withBuildIndex(true).build();AffectRes affectRes = client.upsert("db-test", "book-emb", insertParam);System.out.println("\\tres: " + affectRes);
如果您无需使用腾讯云向量数据库(Tencent Cloud VectorDB)的 Embedding 功能做向量化,则可以直接写入向量数据。
Document doc1 = Document.newBuilder().withId("0001").withVector(Arrays.asList(0.2123, 0.21, 0.213)).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).addDocField(new DocField("page", 21)).addDocField(new DocField("tags", Arrays.asList("孙悟空","猪八戒","唐僧"))).build();Document doc2 = Document.newBuilder().withId("0002").withVector(Arrays.asList(0.2123, 0.22, 0.213)).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).addDocField(new DocField("page", 22)).addDocField(new DocField("tags", Arrays.asList("孙悟空","猪八戒","唐僧"))).build();Document doc3 = Document.newBuilder().withId("0003").withVector(Arrays.asList(0.2123, 0.23, 0.213)).addDocField(new DocField("bookName", "三国演义")).addDocField(new DocField("author", "罗贯中")).addDocField(new DocField("page", 23)).addDocField(new DocField("tags", Arrays.asList("曹操","诸葛亮","刘备"))).build();InsertParam insertParam = InsertParam.newBuilder().addDocument(doc1).addDocument(doc2).addDocument(doc3).addDocument(doc4).addDocument(doc5).withBuildIndex(true).build();collection.upsert(insertParam);AffectRes affectRes = client.upsert("db-test", "book-vector", insertParam);System.out.println("\\tres: " + affectRes);
如果您无需使用腾讯云向量数据库(Tencent Cloud VectorDB)的 Embedding 功能做向量化,则可以直接写入向量数据与稀疏向量。
Document doc1 = Document.newBuilder().withId("0001").withVector(Arrays.asList(0.2123, 0.21, 0.213)).withSparseVector(Arrays.asList(Pair.of(2l, 0.96f), Pair.of(5l, 0.53f),Pair.of(100l, 0.443f))).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).addDocField(new DocField("page", 21)).addDocField(new DocField("tags", Arrays.asList("孙悟空","猪八戒","唐僧"))).build();Document doc2 = Document.newBuilder().withId("0002").withVector(Arrays.asList(0.2123, 0.22, 0.213)).withSparseVector(Arrays.asList(Pair.of(2l, 0.97f), Pair.of(5l, 0.54f),Pair.of(100l, 0.444f))).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).addDocField(new DocField("page", 22)).addDocField(new DocField("tags", Arrays.asList("孙悟空","猪八戒","唐僧"))).build();Document doc3 = Document.newBuilder().withId("0003").withVector(Arrays.asList(0.2123, 0.23, 0.213)).withSparseVector(Arrays.asList(Pair.of(2l, 0.98f), Pair.of(5l, 0.55f),Pair.of(100l, 0.445f))).addDocField(new DocField("bookName", "红楼梦")).addDocField(new DocField("author", "曹雪芹")).addDocField(new DocField("page", 23)).addDocField(new DocField("tags", Arrays.asList("贾宝玉","林黛玉","王熙凤"))).build();InsertParam insertParam = InsertParam.newBuilder().addDocument(doc1).addDocument(doc2).addDocument(doc3).withBuildIndex(true).build();AffectRes affectRes = client.upsert("db-test", "book-vector-sparse", insertParam);System.out.println("\\tres: " + affectRes);
SparseVectorBm25Encoder bm25Encoder = SparseVectorBm25Encoder.getDefaultBm25Encoder();List<String> texts = Arrays.asList("腾讯云向量数据库(Tencent Cloud VectorDB)是一款全托管的自研企业级分布式数据库服务,专用于存储、索引、检索、管理由深度神经网络或其他机器学习模型生成的大量多维嵌入向量。","作为专门为处理输入向量查询而设计的数据库,它支持多种索引类型和相似度计算方法,单索引支持10亿级向量规模,高达百万级 QPS 及毫秒级查询延迟。","不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、NLP 服务、计算机视觉、智能客服等 AI 领域。","腾讯云向量数据库(Tencent Cloud VectorDB)作为一种专门存储和检索向量数据的服务提供给用户, 在高性能、高可用、大规模、低成本、简单易用、稳定可靠等方面体现出显著优势。 ","腾讯云向量数据库可以和大语言模型 LLM 配合使用。企业的私域数据在经过文本分割、向量化后,可以存储在腾讯云向量数据库中,构建起企业专属的外部知识库,从而在后续的检索任务中,为大模型提供提示信息,辅助大模型生成更加准确的答案。");List<List<Pair<Long, Float>>> sparseVectors = bm25Encoder.encodeTexts(texts);// upsertList<Document> documentList = new ArrayList<>(Arrays.asList(Document.newBuilder().withId("0001").addDocField(new DocField("text", texts.get(0))).withSparseVector(sparseVectors.get(0)).build(),Document.newBuilder().withId("0002").withSparseVector(sparseVectors.get(1)).addDocField(new DocField("text", texts.get(1))).build(),Document.newBuilder().withId("0003").withSparseVector(sparseVectors.get(2)).addDocField(new DocField("text", texts.get(2))).build(),Document.newBuilder().withId("0004").withSparseVector(sparseVectors.get(3)).addDocField(new DocField("text", texts.get(3))).build(),Document.newBuilder().withId("0005").withSparseVector(sparseVectors.get(4)).addDocField(new DocField("text", texts.get(4))).build()));System.out.println("---------------------- upsert ----------------------");InsertParam insertParam = InsertParam.newBuilder().withDocuments(documentList).build();AffectRes affectRes = client.upsert("db-test", "book-emb-sparse", insertParam);System.out.println("\\tres: " + affectRes);
List<Document> documentList = new ArrayList<>(Arrays.asList(Document.newBuilder().withId("0001").withVector(BinaryUtils.binaryToUint8(Arrays.asList(1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0))).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).build(),Document.newBuilder().withId("0002").withVector(BinaryUtils.binaryToUint8(Arrays.asList(1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0))).addDocField(new DocField("bookName", "西游记")).addDocField(new DocField("author", "吴承恩")).build(),Document.newBuilder().withId("0003").withVector(BinaryUtils.binaryToUint8(Arrays.asList(0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0))).addDocField(new DocField("bookName", "三国演义")).addDocField(new DocField("author", "罗贯中")).build(),Document.newBuilder().withId("0004").withVector(BinaryUtils.binaryToUint8(Arrays.asList(0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0))).addDocField(new DocField("bookName", "三国演义")).addDocField(new DocField("author", "罗贯中")).build(),Document.newBuilder().withId("0005").withVector(BinaryUtils.binaryToUint8(Arrays.asList(0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0))).addDocField(new DocField("bookName", "三国演义")).addDocField(new DocField("author", "罗贯中")).build()));System.out.println("---------------------- upsert ----------------------");InsertParam insertParam = InsertParam.newBuilder().withDocuments(documentList).build();AffectRes affectRes = client.upsert("db-test", "bin-vector", insertParam);System.out.println("\\tres: " + affectRes);
List<Document> documentList = new ArrayList<>(Arrays.asList(Document.newBuilder().withId("0001").withVector(Arrays.asList(0.2123, 0.21, 0.213)).addDocField(new DocField("bookInfo",new JSONObject(new HashMap<Object,Object>(){{put("bookName", "西游记");put("page", 24);put("author", "吴承恩");}}))).build(),Document.newBuilder().withVector(Arrays.asList(0.2123, 0.23, 0.213)).addDocField(new DocField("bookInfo",new JSONObject(new HashMap<Object,Object>(){{put("bookName", "西游记");put("page", 22);put("author", "吴承恩");put("array", Arrays.asList("test_6", "test_7", "test_3"));}}))).build(),Document.newBuilder().withVector(Arrays.asList(0.2123, 0.23, 0.213)).addDocField(new DocField("bookInfo",new JSONObject(new HashMap<Object,Object>(){{put("bookName", "红楼梦");put("page", 26);put("author", "曹雪芹");put("array", Arrays.asList("test_4", "test_2", "test_6"));}}))).build()));System.out.println("---------------------- upsert ----------------------");InsertParam insertParam = InsertParam.newBuilder().withDocuments(documentList).build();AffectRes affectRes = client.upsert("db-test", "coll-json-autoid", insertParam);System.out.println("\\tres: " + affectRes);
请求参数
参数名称 | 参数含义 | 子参数 | 是否必选 | 配置方法 |
database | 指定插入数据的数据库名。 | - | 是 | Database 命名要求如下: 只能使用英文字母,数字,下划线_、中划线-,并以英文字母开头。 长度要求:[1,128]。 |
collection | 指定插入数据的集合名。 | - | 是 | Collection 命名要求如下: 只能使用英文字母,数字,下划线_、中划线-,并以英文字母开头。 长度要求:[1,128]。 |
insertParam | 指定要插入的 Document数据,是一个数组,支持单次插入一条或者多条 Document,最大可插入1000条。 | Id | 是 | Document 主键,长度限制为[1,128]。 |
| | Vector | 否 | 表示文档的向量值, 集合的向量索引为 FLAT/HNSW/IVF 时,直接传入向量数据,以32位浮点数存储,如[0.2123, 0.9281, ..., 0.6712]。 集合的向量索引为二进制索引时,写入向量时可以直接写入二进制数据,也可以十进制写入 .withVector(Arrays.asList(123, 53)) 。十进制写入数据时,数据维度是创建集合时指定维度的1/8。例如:upsert 时 vector=[12, 21],则创建集合时维度为16维,其代表的二进制数据为[00001100, 00010101]。说明: 如果使用 Embedding 功能做向量化,则无需写入向量数据。 |
| | DocField | 否 | text 字段为该参数为创建集合 时,Embedding 参数 field 对应指定的文本字段名。您可以自定义其他便于识别的字段名。 说明: 写入原始文本数据,系统会自动从该字段中提取原始文本信息,并将其转换为向量数据,并将原始文本以及转化后的向量数据一起存储在数据库中。 |
| | | | sparse_vector 为创建集合时自定义的稀疏向量的字段名。 |
| | | | 其他标量字段,用于存储文档的其他信息。例如:bookName、author、page。 说明: 若字段为存储数据过期时间戳的标量字段,需以标准的 Unix 时间戳格式为该字段赋值,且数据类型为 uint64。例如: .addDocField(new DocField("expired_at", System.currentTimeMillis()/1000 + 24*60*60)) 。具体示例,请参见 example。若时间戳字段为空未指定具体的过期时间,插入的该条数据将不会执行过期删除操作,数据将永久保留。 若时间戳字段传入 Value 的数据类型有误或者不符合 Unix 时间戳规范时,将会报出错误信息,请根据提示信息修改。 若时间戳字段指定的过期时间小于当前插入数据时的时间,则在下一个定时删除操作时,直接删除该条数据。 |
| | BuildIndex | 否 | 指定是否需要更新索引,取值如下所示: true:需更新索引。默认值是 true。 false:不更新索引。 注意: 如果创建 Collection 选择的索引类型为 IVF 系列: 当第一次写入时,当前集合还没有向量索引,此时 BuildIndex 必须为 false。插入原始数据之后,需通过 rebuildIndex() 训练数据并重建索引。 当集合已经调用过 rebuildIndex() 创建索引后,集合已经存在向量索引,此时: 如果 BuildIndex = true,表示新写入的数据会加入到已有的 IVF 索引中,但不会更新索引结构,此时新写入的数据可以被检索到。 如果 BuildIndex = false,表示新写入的数据不会加入到已有的 IVF 索引中,此时新写入的数据无法被检索到。 |
出参描述
res: AffectRes{affectedCount=5, code=0, msg='operation success'}
参数名 | 参数含义 |
affectedCount | 插入的文档数量。 |