有奖捉虫:行业应用 & 管理与支持文档专题 HOT
腾讯云向量数据库(Tencent Cloud VectorDB)默认开通 Embedding 功能。本章节介绍如何应用 Embedding 功能写入原始文本,并基于输入的文本信息进行相似性检索。以 Linux 操作系统为例,使用 Python、Java、Go SDK 与 HTTP API 示例代码分别演示。运行本章节所提供的示例代码,您将初步了解基于文本信息进行数据写入检索的能力。

导入 SDK 依赖模块

Python
Java
Go
import tcvectordb
from tcvectordb.model.enum import FieldType, IndexType, MetricType, ReadConsistency, EmbeddingModel
from tcvectordb.model.index import Index, VectorIndex, FilterIndex, HNSWParams, IVFFLATParams
from tcvectordb.model.collection import UpdateQuery
from tcvectordb.model.document import Document, SearchParams, Filter
from tcvectordb.model.collection import Embedding, UpdateQuery
import com.tencentcloudapi.client.VectorDBClient;
import com.tencentcloudapi.model.*;
package main
?
import (
"context"
"log"
"time"
?
"github.com/tencent/vectordatabase-sdk-go/tcvectordb"
)

创建 Client

导入 SDK 所需的模块之后,需先创建一个向量数据库的客户端对象,与向量数据库服务器连接才能进行交互。
说明:
如下示例 url key 需要分别替换为已购买的免费版实例的外网访问地址与 API Key。请登录 向量数据库控制台,在实例详情页面网络信息区域直接复制外网地址,密钥管理页面直接复制密钥。
Python
Java
Go
client = tcvectordb.VectorDBClient(url='http://10.0.X.X', username='root', key='eC4bLRy2va******************************', read_consistency=ReadConsistency.EVENTUAL_CONSISTENCY, timeout=30)
public class VectorDBExample {
public static void main(String[] args) {
// 创建VectorDB Client
ConnectParam connectParam = ConnectParam.newBuilder()
.withUrl("http://10.0.X.X:80")
.withUsername("root")
.withKey("eC4bLRy2va******************************")
.withTimeout(30)
.build();
VectorDBClient client = new VectorDBClient(connectParam, ReadConsistencyEnum.EVENTUAL_CONSISTENCY);
}
}
func main() {
var defaultOption = &tcvectordb.ClientOption{
Timeout: time.Second * 5,
MaxIdldConnPerHost: 2,
IdleConnTimeout: time.Minute,
ReadConsistency: tcvectordb.EventualConsistency,
}
client, err := tcvectordb.NewClient("http://10.0.X.X:80", "root", "eC4bLRy2va******************************", defaultOption)
if err != nil {
panic(err)
}
}

创建数据库

Python
Java
Go
Curl
Python SDK 通过 create_database() 接口创建数据库 db-test
db = client.create_database(database_name='db-test')
Java SDK 通过 createDatabase() 创建数据库 db-test
Database db = client.createDatabase("db-test");
Go SDK 通过 CreateDatabase() 创建数据库 db-test
var (
ctx = context.Background()
database = "db-test"
)
db, _ := client.CreateDatabase(ctx, database)
HTTP 使用 /database/create 接口创建名为 db_test 的数据库。其中, url 地址与 api_key 需要分别替换为已购买的免费版实例的外网地址与 API Key。
curl -i -X POST \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer account=root&api_key=A5VOgsMpGWJhUI0WmUbY********************' \\
http://10.0.X.X:80/database/create \\
-d '{
"database": "db-test"
}'

创建集合

1. 创建集合之前,需先设计索引结构,指定索引字段。如下示例,创建一个可写入3维向量数据存储书籍的集合 book-emb,其书籍信息字段包括: id、vector、bookName,分别对各字段构建索引。有关索引的具体信息,请参见Index
主键索引(Primary Key Index):固定且必须,对应字段 id,每条数据的唯一标识。并对主键 id 构建 Filter 索引,以便可通过 id 的条件表达式进行特定行的检索。
向量索引(Vector Index):固定且必须,对应字段 vector,对向量数据构建索引,指定向量数据存储的索引类型、相似性计算方法及相关索引参数。
说明:
应用 Embedding 功能,向量数据的维度 Dimension 可以不配置,默认会使用 Embedding 模型支持的数据维度。如下示例,model 指定的模型为 BGE_BASE_ZH,默认数据维度为 768 维。若配置 Dimension,则务必与 Embedding 的模型维数一致。
Filter 索引(Filter Index):需根据检索需求选取可作为条件查询过滤数据的字段。通常,向量数据对应的文本字段,不具有过滤属性,则无需对该字段建立索引,否则,将浪费较大的内存也无实际意义。如下示例,预按书籍的名称过滤数据,对 bookName 字段建立 Filter 索引。
2. 应用 Embedding 功能,则需配置 Embedding 参数。如下示例,自定义文本信息的字段名为 text、选择 Embedding 模型 bge-base-zh,向量数据字段固定为 vector
3. 创建集合,免费测试版实例,其分片 shard 只能为 1,副本 replicas 仅能为 0。
Python
Java
Go
Curl
Python SDK 通过接口 create_collection() 创建集合 book-vector
# 第一步:设计索引字段
index = Index(
FilterIndex(name='id', field_type=FieldType.String, index_type=IndexType.PRIMARY_KEY),
VectorIndex(name='vector', dimension=768, index_type=IndexType.HNSW,
metric_type=MetricType.COSINE, params=HNSWParams(m=16, efconstruction=200)),
FilterIndex(name='bookName', field_type=FieldType.String, index_type=IndexType.FILTER)
)
# 第二步:配置 Embedding 参数
# 1. 指定文本字段与向量字段,向量字段固定为vector
# 2. 指定 Embedding 模型,推荐使用 BGE_BASE_ZH。
ebd = Embedding(vector_field='vector', field='text', model=EmbeddingModel.BGE_BASE_ZH)
?
# 第三步,创建 Collection
coll = db.create_collection(
name='book-emb',
shard=1,
replicas=0,
description='this is an embedding collection',
embedding=ebd,
index=index
)
print(vars(coll))
Java SDK 通过接口 createCollection 创建集合 book-emb
CreateCollectionParam collectionParam = CreateCollectionParam.newBuilder()
.withName("book-emb")
.withShardNum(1)
.withReplicaNum(0)
.withDescription("this is an embedding collection")
.addField(new FilterIndex("id", FieldType.String, IndexType.PRIMARY_KEY))
.addField(new VectorIndex("vector", BGE_BASE_ZH.getDimension(), IndexType.HNSW,
MetricType.COSINE, new HNSWParams(16, 200)))
.addField(new FilterIndex("bookName", FieldType.String, IndexType.FILTER))
.withEmbedding(
Embedding
.newBuilder()
.withModel(BGE_BASE_ZH)
.withField("text")
.withVectorField("vector")
.build())
.build();
Collection collection = db.createCollection(collectionParam);
Go SDK 通过接口 CreateCollection() 创建集合 book-emb
var (
embeddingCollection = "book-emb"
)
// 第一步:设计索引字段
index := tcvectordb.Indexes{
VectorIndex: []tcvectordb.VectorIndex{
{
FilterIndex: tcvectordb.FilterIndex{
FieldName: "vector",
FieldType: tcvectordb.Vector,
IndexType: tcvectordb.HNSW,
},
MetricType: tcvectordb.COSINE,
Params: &tcvectordb.HNSWParam{
M: 16,
EfConstruction: 200,
},
},
},
FilterIndex: []tcvectordb.FilterIndex{
{
FieldName: "id",
FieldType: tcvectordb.String,
IndexType: tcvectordb.PRIMARY,
},
{
FieldName: "bookName",
FieldType: tcvectordb.String,
IndexType: tcvectordb.FILTER,
},
},
}
// 第二步:配置 Embedding 参数
param := &tcvectordb.CreateCollectionParams{
Embedding: &tcvectordb.Embedding{
Field: "text",
VectorField: "vector",
Model: tcvectordb.BGE_BASE_ZH,
},
}
// 第三步:创建集合
coll, _ := db.CreateCollection(ctx, embeddingCollection, 1, 0, "this is an embedding collection", index, param)
log.Printf("CreateCollection success: %v: %v", coll.DatabaseName, coll.CollectionName)
HTTP 通过 /collection/create 创建集合 book-emb
curl -i -X POST \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer account=root&api_key=A5VOgsMpGWJhUI0WmUbY********************' \\
http://10.0.X.X:80/collection/create \\
-d '{
"database": "db-test",
"collection": "book-emb",
"replicaNum": 0,
"shardNum": 1,
"description": "this is an embedding collection",
"embedding": {
"field": "text",
"vectorField": "vector",
"model": "bge-base-zh"
},
"indexes": [
{
"fieldName": "id",
"fieldType": "string",
"indexType": "primaryKey"
},
{
"fieldName": "vector",
"fieldType": "vector",
"indexType": "HNSW",
"metricType": "COSINE",
"params": {
"M": 16,
"efConstruction": 200
}
},
{
"fieldName": "bookName",
"fieldType": "string",
"indexType": "filter"
}
]
}'
?

基于文本信息写入数据

如下示例,为书籍集合 book-emb 写入3条数据,其中 text 字段为写入的文本信息。Embedding 将文本信息自动向量化后写入数据库,并保存原始文本。
说明:
向量数据库支持动态 Schema,写入数据时可以写入任何字段,无需提前定义,类似 MongoDB。如下示例,page 与 author 为新定义的书籍信息字段。
创建集合时,并未对 page 与 author 构建 Filter 索引,因此,二者不具有过滤属性,仅 bookName 具有过滤属性。
写入数据,可能存在一定延迟。
Python
Java
Go
Curl
Pyhton SDK 通过upsert() 接口为集合 book-emb,写入原始文本。
res = coll.upsert(
documents=[
Document(id='0001', text="话说天下大势,分久必合,合久必分。", author='罗贯中', bookName='三国演义', page=21),
Document(id='0002', text="混沌未分天地乱,茫茫渺渺无人间。", author='吴承恩', bookName='西游记', page=22),
Document(id='0003', text="甄士隐梦幻识通灵,贾雨村风尘怀闺秀。", author='曹雪芹', bookName='红楼梦', page=23)
],
)
createCollection() 建表时,配置 Embedding 模型相关参数之后,便可以通过 upsert() 接口可直接传入原始文本。如下示例,基于 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))
.build();
Document doc2 = Document.newBuilder()
.withId("0002")
.addDocField(new DocField("text", "混沌未分天地乱,茫茫渺渺无人间。"))
.addDocField(new DocField("bookName", "西游记"))
.addDocField(new DocField("author", "吴承恩"))
.addDocField(new DocField("page", 22))
.build();
Document doc3 = Document.newBuilder()
.withId("0003")
.addDocField(new DocField("text", "甄士隐梦幻识通灵,贾雨村风尘怀闺秀。"))
.addDocField(new DocField("bookName", "红楼梦"))
.addDocField(new DocField("author", "曹雪芹"))
.addDocField(new DocField("page", 23))
.build();
?
InsertParam insertParam = InsertParam.newBuilder()
.addDocument(doc1)
.addDocument(doc2)
.addDocument(doc3)
.build();
collection.upsert(insertParam);
Go SDK 通过 Upsert() 接口为集合 book-vector 批量插入数据。
result, err := coll.Upsert(ctx, []tcvectordb.Document{
{
Id: "0001",
Fields: map[string]tcvectordb.Field{
"text": {Val: "话说天下大势,分久必合,合久必分。"},
"bookName": {Val: "三国演义"},
"author": {Val: "罗贯中"},
"page": {Val: 21},
},
},
{
Id: "0002",
Fields: map[string]tcvectordb.Field{
"text": {Val: "混沌未分天地乱,茫茫渺渺无人间。"},
"bookName": {Val: "西游记"},
"author": {Val: "吴承恩"},
"page": {Val: 22},
},
},
{
Id: "0003",
Fields: map[string]tcvectordb.Field{
"text": {Val: "甄士隐梦幻识通灵,贾雨村风尘怀闺秀。"},
"bookName": {Val: "红楼梦"},
"author": {Val: "曹雪芹"},
"page": {Val: 23},
},
},
}, &tcvectordb.UpsertDocumentParams{})
log.Printf("upsert result: %+v", result)
如下示例,通过 /document/upsert 为集合 book-emb,写入原始文本。
curl -i -X POST \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer account=root&api_key=A5VOgsMpGWJhUI0WmUbY********************' \\
http://10.0.X.X:80/document/upsert \\
-d '{
"database": "db-test",
"collection": "book-emb",
?
"documents": [
{
"id": "0001",
"text": "话说天下大势,分久必合,合久必分。",
"author": "罗贯中",
"bookName": "三国演义",
"page": 21
},
{
"id": "0002",
"text": "混沌未分天地乱,茫茫渺渺无人间。",
"author": "吴承恩",
"bookName": "西游记",
"page": 22
},
{
"id": "0003",
"text": "甄士隐梦幻识通灵,贾雨村风尘怀闺秀。",
"author": "曹雪芹",
"bookName": "红楼梦",
"page": 23
}
]
}'

相似性检索

基于 Embedding 功能的相似性检索,支持检索与输入的文本信息相似的文本。如下示例,检索与 embeddingItems 参数输入的文本信息相似度最高,且满足 bookName 条件表达式的文本。
说明:
params:指定索引类型对应的查询参数。其中,ef 为 HWSN 索引类型对应的检索参数,指定寻找节点邻居遍历的范围,默认为200。ef 越大,召回率越高。
filter:指定了 bookName 字段的条件表达式,过滤数据。
limit: 限制每个单元返回的相似性数据的条数,如 limit 为3,则返回 top3 的相似数据。
retrieve_vector 指定是否输出向量字段。示例中,文本信息被 Embedding 向量化为768 维数据,数据量大,不变展示,设置为 False。
output_fields:可自定义需要输出的字段。若不自定,则返回所有字段。
Python
Java
Go
Curl
Python SDK 提供了 searchByText() 接口按照输入的文本批量进行相似性查询的能力。如下示例,在集合 book-emb 中,检索与 embeddingItems 参数配置的文本信息相似,且满足 bookName 条件表达式的文本。
doc_lists = coll.searchByText(
embeddingItems=['天下大势,分久必合,合久必分'],
filter=Filter(Filter.In("bookName",["三国演义", "西游记"])),
params=SearchParams(ef=200),
limit=3,
retrieve_vector=False,
output_fields=['bookName','author','text']
)
for i, docs in enumerate(doc_lists.get("documents")):
print(i)
for doc in docs:
print(doc)
检索结果,如下所示。
说明:
检索结果将按照相似程度的高低排列。相似度最高的结果会排在最前面,最低的结果则排在后面。相似程度则通过 L2(欧几里得距离)、IP(内积)或 COSINE(余弦相似度)计算得出的分数来衡量。输出参数 score 表示相似性计算分数。其中,欧式距离(L2)计算所得的分数越小与搜索值越相似;而余弦相似度(COSINE)与 内积(IP) 计算所得的分数越大与搜索值越相似。
{'id': '0001', 'score': 0.979274, 'text': '话说天下大势,分久必合,合久必分。', 'bookName': '三国演义', 'author': '罗贯中'}
{'id': '0002', 'score': 0.790986, 'bookName': '西游记', 'text': '混沌未分天地乱,茫茫渺渺无人间。', 'author': '吴承恩'}
Java SDK 通过 searchByEmbeddingItems() 接口,在集合 book-emb 中,检索与 EmbeddingItems 参数的文本信息最相似,且满足 bookName 条件表达式的文本。
SearchByEmbeddingItemsParam searchByEmbeddingItemsParam = SearchByEmbeddingItemsParam.newBuilder()
.withEmbeddingItems(Arrays.asList("天下大势,分久必合,合久必分"))
// 若使用 HNSW 索引,则需要指定参数 ef,ef 越大,召回率越高,但也会影响检索速度
.withParams(new HNSWSearchParams(200))
// 设置标量字段的 Filter 表达式,过滤所需查询的文档
.withRetrieveVector(false)
// 指定 Top K 的 K 值
.withLimit(5)
// 使用 filter 过滤数据
.withFilter(new Filter(Filter.in("bookName", Arrays.asList("三国演义","西游记"))))
// 指定返回的 fields
.withOutputFields(Arrays.asList("author", "bookName", "text"))
.build();
List<List<Document>> siDocs = collection.searchByEmbeddingItems(searchByEmbeddingItemsParam);
int i = 0;
for (List<Document> docs : siDocs) {
System.out.println("\\tres: " + i++);
for (Document doc : docs) {
System.out.println(doc.toString());
}
}
检索结果,如下所示。
说明:
检索结果将按照相似程度的高低排列。相似度最高的结果会排在最前面,最低的结果则排在后面。相似程度则通过 L2(欧几里得距离)、IP(内积)或 COSINE(余弦相似度)计算得出的分数来衡量。输出参数 score 表示相似性计算分数。其中,欧式距离(L2)计算所得的分数越小与搜索值越相似;而余弦相似度(COSINE)与 内积(IP) 计算所得的分数越大与搜索值越相似。
res: 0
res: {"id":"0001","score":0.979274,"bookName":"三国演义","author":"罗贯中","text":"话说天下大势,分久必合,合久必分。"}
res: {"id":"0002","score":0.790986,"bookName":"西游记","author":"吴承恩", "text":"沌未分天地乱,茫茫渺渺无人间。"}
Go SDK 通过 SearchByText() 接口,在集合 book-emb 中,检索与 text 字段的文本信息最相似,且满足 bookName 条件表达式的文本。
filter := tcvectordb.NewFilter(`bookName in ("三国演义","西游记")`)
searchRes, _ := coll.SearchByText(ctx, map[string][]string{"text": {"天下大势,分久必合,合久必分"}}, &tcvectordb.SearchDocumentParams{
Params: &tcvectordb.SearchDocParams{Ef: 200},
RetrieveVector: false,
Limit: 3,
Filter: filter,
OutputFields: []string{"author", "bookName", "text"},
})
for i, docs := range searchRes.Documents {
log.Printf("doc %d result: ", i)
for _, doc := range docs {
log.Printf("document: %+v", doc)
}
}
检索结果,如下所示。
说明:
检索结果将按照相似程度的高低排列。相似度最高的结果会排在最前面,最低的结果则排在后面。相似程度则通过 L2(欧几里得距离)、IP(内积)或 COSINE(余弦相似度)计算得出的分数来衡量。输出参数 score 表示相似性计算分数。其中,欧式距离(L2)计算所得的分数越小与搜索值越相似;而余弦相似度(COSINE)与 内积(IP) 计算所得的分数越大与搜索值越相似。
2024/01/04 17:42:05 doc 0 result:
2024/01/04 17:42:05 document: {Id:0001 Vector:[] Score:0.979274 Fields:map[author:罗贯中 bookName:三国演义 page:21 text:话说天下大势,分久必合,合久必分。]}
2024/01/04 17:42:05 document: {Id:0002 Vector:[] Score:0.790986 Fields:map[author:吴承恩 bookName:西游记 page:22 text:混沌未分天地乱,茫茫渺渺无人间。]}
HTTP 使用 /document/search 接口,在集合 book-emb 中,检索与 embeddingItems 参数的文本信息相似最高,且满足 bookName 条件表达式的文本。
curl -i -X POST \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer account=root&api_key=A5VOgsMpGWJhUI0WmUbY********************' \\
http://10.0.X.X:80/document/search \\
-d '{
"database": "db-test",
"collection": "book-emb",
"search": {
"embeddingItems": [
"天下大势,分久必合,合久必分"
],
"limit": 3,
"params": {
"ef": 200
},
"retrieveVector": false,
"filter": "bookName in (\\"三国演义\\",\\"西游记\\")",
"outputFields": [
"id",
"author",
"text",
"bookName"
]
}
}'
检索结果,如下所示。
说明:
检索结果将按照相似程度的高低排列。相似度最高的结果会排在最前面,最低的结果则排在后面。相似程度则通过 L2(欧几里得距离)、IP(内积)或 COSINE(余弦相似度)计算得出的分数来衡量。输出参数 score 表示相似性计算分数。其中,欧式距离(L2)计算所得的分数越小与搜索值越相似;而余弦相似度(COSINE)与 内积(IP) 计算所得的分数越大与搜索值越相似。
{
"code": 0,
"msg": "operation success",
"documents": [
[
{
"id": "0001",
"score": 0.979274,
"author": "罗贯中",
"bookName": "三国演义",
"text": "话说天下大势,分久必合,合久必分。"
},
{
"id": "0002",
"score": 0.790986,
"text": "混沌未分天地乱,茫茫渺渺无人间。",
"bookName": "西游记",
"author": "吴承恩"
}
]
]
}

删除数据库

Python
Java
Go
Curl
Python SDK 通过 drop_database() 接口删除数据库 db-test
client.drop_database(database_name='db-test')
Java SDK 通过 dropDatabase() 删除数据库 db-test
client.dropDatabase("db-test");
Go SDK 通过 DropDatabase() 删除数据库 db-test
result, _ := client.DropDatabase(context.Background(), database)
HTTP 使用 /database/drop 接口删除数据库 db_test。如下示例,url 地址与 api_key 需要分别替换为已购买的免费版实例的外网地址与 API Key。
curl -i -X POST \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer account=root&api_key=A5VOgsMpGWJhUI0WmUbY********************' \\
http://10.0.X.X:80/database/drop \\
-d '{
"database": "db-test"
}'
?


http://www.vxiaotou.com