向量Vectors

更新时间:
复制 MD 格式

向量数据是向量Bucket的核心资源,由三个部分组成:

  • Key(主键):向量的唯一标识符

  • Data(向量数据):高维数值数组

  • Metadata(元数据):Key-Value结构,用于存储向量的附加属性信息(如类别、来源、时间戳等),可用于查询时的后置过滤。

每个向量都存储在特定的向量索引中,继承索引的维度、数据类型和距离度量配置。

写入向量数据

将向量数据及其元数据上传到指定的向量索引中。

  • 单个向量索引表最多可存储 20 亿行向量数据。

  • 写入向量数据的 API (PutVectors)的 QPS 上限为 1000,单并发最大支持批量写入 500 条,所有并发批量最多写入 2500 条。

说明

PutVectors 接口对 Standard 模式和 Fusion 模式的向量索引通用,在 Fusion 模式下部分请求参数和返回字段会有所不同,具体请参见 PutVectors。

控制台

  1. 在向量Bucket页面,单击已创建的向量Bucket。

  2. 在刚创建的索引行,单击查看数据,单击向量数据插入。

  3. 配置向量数据,可以同时添加多条向量数据:

    • 主键值:为向量设置唯一标识符。

    • 向量数据:输入向量数值数组,格式为 JSON 数组,如:[0.1, 0.2, 0.3, 0.4, 0.5]。向量维度需要和选择的 embedded 模型的维度一致。

    • 元数据:可添加元数据信息,如类别、标题、时间戳等。总大小最大支持 200KB。

      • 支持添加的元数据类型为 String、Number、Boolean、List。

      • 单行向量最多支持添加共 100 个可过滤元数据和不可过滤元数据字段。

      • 不可过滤元数据key的大小是 1 ~ 63字符。

      • 单个向量的单个可筛选元数据大小上限:2 KB。

      • 根据可过滤元数据进行标量后过滤时,单次过滤指令中的可过滤元数据长度最大为 20KB,单次过滤指令中的可过滤元数据数量最多为 1024 个,过滤指令最多支持 8 层,且支持过滤内容为空。

  4. 单击确定完成数据插入。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="vector put vectors sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--index_name', help='The name of the vector index.', required=True)
parser.add_argument('--account_id', help='The account id.', required=True)

def main():
    args = parser.parse_args()

    # Loading credentials values from the environment variables
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Using the SDK's default configuration
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    cfg.use_internal_endpoint = True  # 如需通过公网访问,请将此处设置为False或删除此行
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    vector_client = oss_vectors.Client(cfg)

    vectors = [
        {
            "data": {"float32":  [0.1] * 128},
            "key": "key1",
            "metadata": {"metadata1": "value1", "metadata2": "value2"}
        },
        {
            "data": {"float32": [0.2] * 128},
            "key": "key2",
            "metadata": {"metadata3": "value3", "metadata4": "value4"}
        }
    ]

    result = vector_client.put_vectors(oss_vectors.models.PutVectorsRequest(
        bucket=args.bucket,
        index_name=args.index_name,
        vectors=vectors,
    ))

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
    )

if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
}

func main() {
	flag.Parse()
	if len(bucketName) == 0 || len(region) == 0 || len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).WithAccountId(accountId).
		// 如需通过公网访问,请将此处设置为false或删除此行
		WithUseInternalEndpoint(true)

	client := vectors.NewVectorsClient(cfg)

	request := &vectors.PutVectorsRequest{
		Bucket:    oss.Ptr(bucketName),
		IndexName: oss.Ptr("exampleIndex"),

		Vectors: [ ]map[string]any{

			{
				"key": "vector1",
				"data": map[string]any{

					"float32": [ ]float32{1.2, 2.5, 3},

				},
				"metadata": map[string]any{
					"Key1": "value2",

					"Key2": [ ]string{"1", "2", "3"},

				},
			},
		},
	}
	result, err := client.PutVectors(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to put vectors %v", err)
	}
	log.Printf("put vectors result:%#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.PutVectorsRequest;
import com.aliyun.sdk.service.oss2.vectors.models.PutVectorsResult;
import java.util.*;

public class PutVectorsSample {
    public static void main(String[] args) throws Exception {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {
            List<Map<String, Object>> vectors = Arrays.asList(
                    createVector("key1", new Float[]{1.0f, 2.0f, 3.0f}, "description1"),
                    createVector("key2", new Float[]{4.0f, 5.0f, 6.0f}, "description2"));
            PutVectorsRequest request = PutVectorsRequest.newBuilder()
                    .bucket("examplebucket")
                    .indexName("exampleindex")
                    .vectors(vectors)
                    .build();
            PutVectorsResult result = client.putVectors(request);
            System.out.printf("status code: %d, request id: %s%n", result.statusCode(), result.requestId());
        }
    }

    private static Map<String, Object> createVector(String key, Float[] data, String description) {
        Map<String, Object> vector = new HashMap<>();
        vector.put("key", key);
        Map<String, Object> vectorData = new HashMap<>();
        vectorData.put("float32", Arrays.asList(data));
        vector.put("data", vectorData);
        Map<String, String> meta = new HashMap<>();
        meta.put("description", description);
        vector.put("metadata", meta);
        return vector;
    }
}

ossutil

在名为 examplebucket 的向量Bucket中,向名为 index 的向量索引添加一个向量,该向量的数据为 1,向量主键为 vector1,元数据为 {"Key1": "32"}。

  • 使用JSON配置文件,vectors.json内容如下:

    [
      {
        "data": {
          "float32": [1]
        },
        "key": "vector1",
        "metadata": {
          "Key1": "32"
        }
      }
    ]

    命令示例:

    ossutil vectors-api put-vectors --bucket examplebucket --index-name index --vectors file://vectors.json
  • 使用JSON配置参数:

    ossutil vectors-api put-vectors --bucket examplebucket --index-name index --vectors "[{\"data\":{\"float32\":[1]},\"key\":\"vector1\",\"metadata\":{\"Key1\":\"32\"}}]"

API

调用PutVectors接口以写入向量数据。

执行向量检索

使用语义内容、元数据等条件,执行向量检索操作,快速定位目标数据。具备亚秒级检索性能,召回率为 90% 左右。

Standard Mode

Standard 模式索引使用 QueryVectors 接口进行向量相似性检索。

控制台

当前使用控制台进行向量数据查询仅支持单行向量相似检索,多次循环检索请使用 API 或 SDK。

  1. 在向量Bucket页面,单击已创建的向量Bucket。

  2. 在刚创建的索引行,单击查看数据,单击向量数据查询。

  3. 配置检索参数:

    • 向量数据:输入查询向量数据,格式为 JSON 数组,如:[0.15, 0.25, 0.35, 0.45, 0.55]

    • 可过滤元数据:通过元数据进行结果过滤,如类别、时间范围等。

    • TopK(返回数量):设置返回最相似结果的数量,默认范围:1~30。

    • 返回相似距离:选择是否返回相似度距离值

    • 返回元数据:选择是否返回向量的元数据信息

  4. 单击确定执行查询

系统返回按相似度排序的向量列表。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="vector query vectors sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--index_name', help='The name of the vector index.', required=True)
parser.add_argument('--account_id', help='The account id.', required=True)

def main():
    args = parser.parse_args()

    # Loading credentials values from the environment variables
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Using the SDK's default configuration
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    cfg.use_internal_endpoint = True  # 如需通过公网访问,请将此处设置为False或删除此行
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    vector_client = oss_vectors.Client(cfg)

    query_filter = {
        "$and": [{
            "type": {
                "$nin": ["comedy", "documentary"]
            }
        }]
    }

    query_vector = {"float32": [0.1] * 128}

    result = vector_client.query_vectors(oss_vectors.models.QueryVectorsRequest(
        bucket=args.bucket,
        index_name=args.index_name,
        filter=query_filter,
        query_vector=query_vector,
        return_distance=True,
        return_metadata=True,
        top_k=10
    ))

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          )

    if result.vectors:
        for vector in result.vectors:
            print(f'vector: {vector}')


if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
	indexName  string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
	flag.StringVar(&indexName, "index", "", "The name of vector index.")
}

func main() {
	flag.Parse()
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, accounId required")
	}

	if len(indexName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, index required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).WithAccountId(accountId).
		// 如需通过公网访问,请将此处设置为false或删除此行
		WithUseInternalEndpoint(true)

	client := vectors.NewVectorsClient(cfg)

	request := &vectors.QueryVectorsRequest{
		Bucket:    oss.Ptr(bucketName),
		IndexName: oss.Ptr(indexName),
		Filter: map[string]any{
			"$and": []map[string]any{
				{
					"type": map[string]any{
						"$in": []string{"comedy", "documentary"},
					},
				},
			},
		},
		QueryVector: map[string]any{
			"float32": []float32{float32(32)},
		},
		ReturnMetadata: oss.Ptr(true),
		ReturnDistance: oss.Ptr(true),
		TopK:           oss.Ptr(10),
	}
	result, err := client.QueryVectors(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to query vectors %v", err)
	}
	log.Printf("query vectors result:%#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.QueryVectorsRequest;
import com.aliyun.sdk.service.oss2.vectors.models.QueryVectorsResult;
import java.util.*;

public class QueryVectorsSample {
    public static void main(String[] args) throws Exception {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {
            Map<String, Object> queryVector = new HashMap<>();
            queryVector.put("float32", new float[]{0.1f, 0.2f, 0.3f});
            QueryVectorsRequest request = QueryVectorsRequest.newBuilder()
                    .bucket("examplebucket")
                    .indexName("exampleindex")
                    .queryVector(queryVector)
                    .topK(10)
                    .returnDistance(true)
                    .returnMetadata(false)
                    .build();
            QueryVectorsResult result = client.queryVectors(request);
            System.out.printf("status code: %d, request id: %s%n", result.statusCode(), result.requestId());
        }
    }
}

ossutil

在名为examplebucket的向量Bucket中名为 index 的向量索引里,type为comedy和documentary的向量中与查询向量最相似的前 10 条。

ossutil vectors-api query-vectors --bucket examplebucket --index-name index --filter "{\"$and\":[{\"type\":{\"$in\":[\"comedy\",\"documentary\"]}}]}" --query-vector "{\"float32\":[32]}" --top-k 10

API

调用QueryVectors接口以进行向量相似性检索。

Fusion Mode

Fusion 模式索引使用 QueryVectorsFusion 接口进行检索,支持向量检索、标量过滤、全文检索以及多路召回融合。相比 QueryVectors 按距离(distance)返回结果,QueryVectorsFusion 按相关性得分(score)返回结果,score 越大表示相关性越高。当前 Fusion 模式暂不支持通过控制台进行检索,请使用 SDK、ossutil 或 API。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="query vectors fusion sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--index_name', help='The name of the fusion vector index.', required=True)
parser.add_argument('--account_id', help='The account id.', required=True)

def main():
    args = parser.parse_args()

    # 从环境变量中加载访问凭证
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用 SDK 默认配置
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    vector_client = oss_vectors.Client(cfg)

    # QueryVectorsFusion 支持三种查询方式:
    #   knn        最近邻向量检索,可传入单个 dict 或最多三个 dict 的列表。
    #              knn 和 query 可在同一请求中使用,得分叠加。
    #   query      标量、全文和地理条件查询。逻辑运算符采用对象形式
    #              {"$and": {"clauses": [...]}},全文匹配采用
    #              {"$textMatch": {"value": "..."}}。
    #   retriever  将多个检索引擎组合为一个排序结果,例如包含向量和文本
    #              两个叶子节点的 RRF 融合节点。与 knn、query、sort 互斥。
    #
    # 以下示例将 knn 和 query 混合使用:双向量召回加上品牌和标题加权,
    # 按 _score 降序排序(_score 仅支持 desc)。每条命中均携带 score。

    result = vector_client.query_vectors_fusion(oss_vectors.models.QueryVectorsFusionRequest(
        bucket=args.bucket,
        index_name=args.index_name,
        knn=[
            {
                "field": "text_vector",
                "queryVector": [0.1] * 768,
                "topK": 100,
                "boost": 2.0
            },
            {
                "field": "image_vector",
                "queryVector": [0.1] * 512,
                "topK": 100,
                "boost": 0.5
            }
        ],
        query={
            "$or": {
                "clauses": [
                    {"brand": {"$in": {"value": ["AliBrand"], "boost": 1.0}}},
                    {"title": {"$textMatch": {"value": "耳机", "boost": 4.0}}}
                ]
            }
        },
        return_metadata=True,
        return_metadata_fields=["title", "brand", "price"],
        sort=[{
            "_score": {
                "order": "desc"
            }
        }],
        limit=20
    ))

    # retriever 方式(RRF 融合),与 knn、query、sort 互斥,示例如下:
    #
    # result = vector_client.query_vectors_fusion(oss_vectors.models.QueryVectorsFusionRequest(
    #     bucket=args.bucket,
    #     index_name=args.index_name,
    #     retriever={
    #         "rrf": {
    #             "k": 50,
    #             "windowSize": 100,
    #             "retrievers": [
    #                 {
    #                     "retriever": {
    #                         "knn": {
    #                             "field": "text_vector",
    #                             "queryVector": [0.1] * 768,
    #                             "topK": 100
    #                         }
    #                     },
    #                     "weight": 2.0
    #                 },
    #                 {
    #                     "retriever": {
    #                         "simple": {
    #                             "query": {
    #                                 "title": {"$textMatch": {"value": "无线 耳机"}}
    #                             }
    #                         }
    #                     },
    #                     "weight": 0.5
    #                 }
    #             ]
    #         }
    #     },
    #     limit=10,
    #     return_metadata=True,
    #     return_metadata_fields=["title", "brand"]
    # ))

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' next token: {result.next_token},'
    )

    if result.vectors:
        for vector in result.vectors:
            print(f'vector: {vector}')


if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
	indexName  string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
	flag.StringVar(&indexName, "index", "", "The name of vector index.")
}

func main() {
	flag.Parse()
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}
	if len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, accountId required")
	}
	if len(indexName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, index required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).WithAccountId(accountId)

	client := vectors.NewVectorsClient(cfg)

	// QueryVectorsFusion 支持多种查询方式,可通过 Knn、Retriever 等结构体构建请求
	request := &vectors.QueryVectorsFusionRequest{
		Bucket:    oss.Ptr(bucketName),
		IndexName: oss.Ptr(indexName),
		Knn: []map[string]any{
			vectors.Knn{
				Field:         oss.Ptr("demo"),
				QueryVector:   []float32{0.1, 0.2, 0.3, 0.4},
				TopK:          oss.Ptr(10),
				NumCandidates: oss.Ptr(9),
				Filter: map[string]any{
					"meta_field_1": map[string]any{
						"$eq": "abc",
					},
				},
				Boost: oss.Ptr(float32(1)),
			}.ToMap(),
		},
		Retriever: map[string]any{
			"simple": vectors.SimpleRetriever{
				Query: map[string]any{
					"$and": []map[string]any{
						{"type": map[string]any{"$in": []string{"a", "b"}}},
						{"year": map[string]any{"$gte": 2020}},
					},
				},
			}.ToMap(),
		},
		ReturnMetadata:       oss.Ptr(true),
		ReturnMetadataFields: []string{"key1", "key2"},
		PartitionKeys:        []string{"key1", "key2"},
		Limit:                oss.Ptr(10),
		NextToken:            oss.Ptr("nextToken"),
		Sort: []vectors.Sort{
			{"field_a": vectors.SortOptions{Order: oss.Ptr("asc")}},
			{"_score": vectors.SortOptions{Order: oss.Ptr("desc")}},
			{"_primaryKey": vectors.SortOptions{Order: oss.Ptr("asc")}},
		},
	}

	result, err := client.QueryVectorsFusion(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to query vectors fusion: %v", err)
	}
	log.Printf("query vectors fusion result: %#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.Knn;
import com.aliyun.sdk.service.oss2.vectors.models.NormalizerType;
import com.aliyun.sdk.service.oss2.vectors.models.QueryVectorsFusionRequest;
import com.aliyun.sdk.service.oss2.vectors.models.QueryVectorsFusionResult;
import com.aliyun.sdk.service.oss2.vectors.models.QueryVectorsFusionSummary;
import com.aliyun.sdk.service.oss2.vectors.models.RetrieverComponent;
import com.aliyun.sdk.service.oss2.vectors.models.RrfRetriever;
import com.aliyun.sdk.service.oss2.vectors.models.SimpleRetriever;
import com.aliyun.sdk.service.oss2.vectors.models.WeightRetriever;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class QueryVectorsFusionSample {
    public static void main(String[] args) {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();

        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {

            String bucket = "examplebucket";
            String indexName = "exampleindex";

            // 构造向量检索请求
            Knn knn = Knn.newBuilder()
                    .field("vector_1")
                    .queryVector(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f))
                    .topK(10)
                    .build();

            // 构造全文检索查询条件
            Map<String, Object> titleQuery = new HashMap<>();
            titleQuery.put("title", new HashMap<String, Object>() {{
                put("$textMatch", new HashMap<String, Object>() {{
                    put("value", "hello world");
                    put("boost", 2.0f);
                }});
            }});

            // 模式 1(默认):单路向量检索
            QueryVectorsFusionRequest knnRequest = QueryVectorsFusionRequest.newBuilder()
                    .bucket(bucket)
                    .indexName(indexName)
                    .knn(knn)
                    .limit(10)
                    .returnMetadata(true)
                    .build();

            // 模式 2:RRF 多路召回融合
            RrfRetriever rrf = RrfRetriever.newBuilder()
                    .k(50)
                    .windowSize(100)
                    .retrievers(Arrays.asList(
                            RetrieverComponent.newBuilder()
                                    .retriever(knn)
                                    .weight(1.0f)
                                    .build(),
                            RetrieverComponent.newBuilder()
                                    .retriever(SimpleRetriever.newBuilder().query(titleQuery).build())
                                    .weight(2.0f)
                                    .build()))
                    .build();

            QueryVectorsFusionRequest rrfRequest = QueryVectorsFusionRequest.newBuilder()
                    .bucket(bucket)
                    .indexName(indexName)
                    .retriever(rrf)
                    .limit(10)
                    .returnMetadata(true)
                    .build();

            // 模式 3:Weight 加权融合
            WeightRetriever weight = WeightRetriever.newBuilder()
                    .windowSize(100)
                    .retrievers(Arrays.asList(
                            RetrieverComponent.newBuilder()
                                    .retriever(knn)
                                    .weight(0.7f)
                                    .normalizer(NormalizerType.MIN_MAX)
                                    .build(),
                            RetrieverComponent.newBuilder()
                                    .retriever(SimpleRetriever.newBuilder().query(titleQuery).build())
                                    .weight(0.3f)
                                    .normalizer(NormalizerType.MIN_MAX)
                                    .build()))
                    .build();

            QueryVectorsFusionRequest weightRequest = QueryVectorsFusionRequest.newBuilder()
                    .bucket(bucket)
                    .indexName(indexName)
                    .retriever(weight)
                    .limit(10)
                    .returnMetadata(true)
                    .build();

            // 以 RRF 模式为例执行查询
            QueryVectorsFusionResult result = client.queryVectorsFusion(rrfRequest);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());

            List<QueryVectorsFusionSummary> vectors = result.vectors();
            for (int i = 0; i < vectors.size(); i++) {
                QueryVectorsFusionSummary vector = vectors.get(i);
                System.out.printf("Vector %d: key=%s, score=%s%n",
                        i + 1, vector.key(), vector.score());
            }

            if (result.nextToken() != null) {
                System.out.printf("Next token: %s%n", result.nextToken());
            }
        }
    }
}

ossutil

命令格式

ossutil vectors-api query-vectors-fusion --bucket value --index-name value --account-id value [flags]

参数说明

参数

类型

说明

--bucket

string

向量Bucket名称。

--index-name

string

向量索引名称。

--account-id

string

阿里云账号ID。该选项为必填项,未指定时命令会返回AccountId is null错误。

--knn

string

向量检索条件,JSON格式。当选项值包含file://前缀时,表示从文件中读取配置。

--query

string

标量与全文过滤条件容器,JSON格式。当选项值包含file://前缀时,表示从文件中读取配置。

--retriever

string

多路召回融合配置,JSON格式,用于多路混合检索(如RRF融合、加权归一化融合)。

--limit

int

返回结果的条数。

--next-token

string

翻页的起始标记,取值为上一次请求返回的NextToken。

--partition-keys

stringArray

需要访问的分区键,可重复指定该选项以传入多个分区键。

--return-metadata

/

是否返回元数据。指定该选项时返回元数据。

--return-metadata-fields

stringArray

元数据中需要返回的字段,可重复指定该选项以传入多个字段。

--sort

string

返回结果的排序方式,JSON格式。

说明
  • 本命令需要ossutil 2.4.1及以上版本。更低版本请通过泛化命令invoke-operation调用QueryVectorsFusion接口。

  • --knn、--query、--retriever分别对应向量检索、标量与全文过滤、多路召回融合,可按需组合使用。

  • 使用--retriever时,仅允许同时指定--index-name、--limit、--partition-keys、--return-metadata、--return-metadata-fields选项。

  • --next-token仅在纯标量与全文过滤(即不指定--knn和--retriever)的检索场景下支持翻页。

  • 关于支持的全局命令行选项,请参见支持的全局命令行选项。

使用示例

在名为examplebucket的向量Bucket中,对名为my_index的Fusion模式向量索引进行检索,返回与查询向量最相似的前 10 条向量及其元数据。

ossutil vectors-api query-vectors-fusion --bucket examplebucket --index-name my_index --knn '{"field":"text_vector","queryVector":[0.1,0.2,0.3],"topK":10,"numCandidates":100}' --return-metadata --account-id 123456789012****

在上述检索的基础上增加标量过滤,仅返回category为book的结果,限定返回20条,并指定元数据只返回title和year字段。

ossutil vectors-api query-vectors-fusion --bucket examplebucket --index-name my_index --knn '{"field":"text_vector","queryVector":[0.1,0.2,0.3],"topK":10,"numCandidates":100}' --query '{"category":{"$eq":"book"}}' --limit 20 --return-metadata --return-metadata-fields title --return-metadata-fields year --account-id 123456789012****

API

调用QueryVectorsFusion接口对 Fusion 模式的向量索引进行检索。

获取向量数据

说明

GetVectors 接口对 Standard 模式和 Fusion 模式的向量索引通用,在 Fusion 模式下部分请求参数和返回字段会有所不同,具体请参见 GetVectors。

控制台

在向量Bucket页面,单击已创建的向量Bucket,进入索引列表页面,单击索引名称,可以进入向量数据页面查看向量信息。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="vector get vectors sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--index_name', help='The name of the vector index.', required=True)
parser.add_argument('--account_id', help='The account id.', required=True)

def main():
    args = parser.parse_args()

    # Loading credentials values from the environment variables
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Using the SDK's default configuration
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    cfg.use_internal_endpoint = True  # 如需通过公网访问,请将此处设置为False或删除此行
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    vector_client = oss_vectors.Client(cfg)

    keys = ['key1', 'key2']

    result = vector_client.get_vectors(oss_vectors.models.GetVectorsRequest(
        bucket=args.bucket,
        index_name=args.index_name,
        keys=keys,
        return_data=True,
        return_metadata=True
    ))

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          )

    if result.vectors:
        for vector in result.vectors:
            print(f'vector id: {vector}')


if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
}

func main() {
	flag.Parse()
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, accounId required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).WithAccountId(accountId).
		// 如需通过公网访问,请将此处设置为false或删除此行
		WithUseInternalEndpoint(true)

	client := vectors.NewVectorsClient(cfg)

	request := &vectors.GetVectorsRequest{
		Bucket:         oss.Ptr(bucketName),
		IndexName:      oss.Ptr("index"),
		Keys:           []string{"key1", "key2", "key3"},
		ReturnData:     oss.Ptr(true),
		ReturnMetadata: oss.Ptr(false),
	}
	result, err := client.GetVectors(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to get vectors %v", err)
	}
	log.Printf("get vectors result:%#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.GetVectorsRequest;
import com.aliyun.sdk.service.oss2.vectors.models.GetVectorsResult;
import java.util.*;

public class GetVectorsSample {
    public static void main(String[] args) throws Exception {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {
            GetVectorsRequest request = GetVectorsRequest.newBuilder()
                    .bucket("examplebucket")
                    .indexName("exampleindex")
                    .keys(Arrays.asList("key1", "key2"))
                    .returnData(true)
                    .returnMetadata(true)
                    .build();
            GetVectorsResult result = client.getVectors(request);
            System.out.printf("status code: %d, request id: %s%n", result.statusCode(), result.requestId());
        }
    }
}

ossutil

获取名为 examplebucket 的向量Bucket中索引名为index,主键为key和key1的向量属性。

ossutil vectors-api get-vectors --bucket examplebucket --index-name index --keys key,key1

API

调用GetVectors接口以获取指定的向量数据。

列举向量数据

说明

ListVectors 接口对 Standard 模式和 Fusion 模式的向量索引通用,在 Fusion 模式下部分请求参数和返回字段会有所不同,具体请参见 ListVectors。

控制台

在向量Bucket页面,单击已创建的向量Bucket,进入索引列表页面,单击索引名称。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="list vectors sample")

parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--account_id', help='The account id.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--index_name', help='The name of the vector index.', required=True)

def main():

    args = parser.parse_args()

    # Loading credentials values from the environment variables
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Using the SDK's default configuration
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    cfg.use_internal_endpoint = True  # 如需通过公网访问,请将此处设置为False或删除此行
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_vectors.Client(cfg)

    # Create the Paginator for the ListVectors operation
    paginator = client.list_vectors_paginator()

    # Create request with bucket and index name
    request = oss_vectors.models.ListVectorsRequest(
        bucket=args.bucket,
        index_name=args.index_name
    )

    # Iterate through the vectors pages
    for page in paginator.iter_page(request):
        for o in page.vectors:
            print(f'Vector: {o}')

if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
	indexName  string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
	flag.StringVar(&indexName, "index", "", "The name of vector index.")
}

func main() {
	flag.Parse()
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	if len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, accounId required")
	}

	if len(indexName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, index required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).WithAccountId(accountId).
		// 如需通过公网访问,请将此处设置为false或删除此行
		WithUseInternalEndpoint(true)

	client := vectors.NewVectorsClient(cfg)

	request := &vectors.ListVectorsRequest{
		Bucket:         oss.Ptr(bucketName),
		IndexName:      oss.Ptr(indexName),
		ReturnMetadata: oss.Ptr(true),
		ReturnData:     oss.Ptr(false),
	}

	p := client.NewListVectorsPaginator(request)

	var i int
	log.Println("Vectors:")
	for p.HasNext() {
		i++

		page, err := p.NextPage(context.TODO())
		if err != nil {
			log.Fatalf("failed to get page %v, %v", i, err)
		}

		for _, v := range page.Vectors {
			log.Printf("vector:%v\n", v)
		}
	}
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.ListVectorsRequest;
import com.aliyun.sdk.service.oss2.vectors.models.ListVectorsResult;

public class ListVectorsSample {
    public static void main(String[] args) throws Exception {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {
            ListVectorsRequest request = ListVectorsRequest.newBuilder()
                    .bucket("examplebucket")
                    .indexName("exampleindex")
                    .build();
            ListVectorsResult result = client.listVectors(request);
            System.out.printf("status code: %d, request id: %s%n", result.statusCode(), result.requestId());
        }
    }
}

ossutil

列举名为 examplebucket 的向量Bucket中索引名为index下的所有向量。

ossutil vectors-api list-vectors --bucket examplebucket --index-name index

API

调用ListVectors接口以列举向量索引中的所有向量数据。

删除向量数据

支持批量删除向量数据。删除操作不可逆,请谨慎操作,确保已备份重要数据。

说明

DeleteVectors 接口对 Standard 模式和 Fusion 模式的向量索引通用,在 Fusion 模式下部分请求参数和返回字段会有所不同,具体请参见 DeleteVectors。

控制台

在向量Bucket页面,单击已创建的向量Bucket,进入索引列表页面,单击索引名称,进入向量数据页面查看向量信息,选择需要删除的向量数据完成删除操作。

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors

parser = argparse.ArgumentParser(description="vector delete vectors sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--index_name', help='The name of the vector index.', required=True)
parser.add_argument('--account_id', help='The account id.', required=True)

def main():
    args = parser.parse_args()

    # Loading credentials values from the environment variables
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Using the SDK's default configuration
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    cfg.account_id = args.account_id
    cfg.use_internal_endpoint = True  # 如需通过公网访问,请将此处设置为False或删除此行
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    vector_client = oss_vectors.Client(cfg)

    keys = ['key1', 'key2', 'key3']

    result = vector_client.delete_vectors(oss_vectors.models.DeleteVectorsRequest(
        bucket=args.bucket,
        index_name=args.index_name,
        keys=keys,
    ))

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
    )

if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)

var (
	region     string
	bucketName string
	accountId  string
)

func init() {
	// 定义命令行参数
	flag.StringVar(&region, "region", "", "The region in which the vector bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the vector bucket.")
	flag.StringVar(&accountId, "account-id", "", "The id of vector account.")
}

func main() {
	// 解析命令行参数
	flag.Parse()
	
	// 验证必需参数
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(accountId) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, accountId required")
	}

	// 创建配置,设置凭证提供者、区域和账号ID
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).
		WithAccountId(accountId).
		// 如需通过公网访问,请将此处设置为false或删除此行
		WithUseInternalEndpoint(true)

	// 创建向量存储客户端
	client := vectors.NewVectorsClient(cfg)

	// 构造删除向量数据的请求
	request := &vectors.DeleteVectorsRequest{
		Bucket:    oss.Ptr(bucketName),
		IndexName: oss.Ptr("index"),
		Keys: [ ]string{

			"key1", "key2",                          // 要删除的向量键列表
		},
	}
	
	// 执行删除向量数据的操作
	result, err := client.DeleteVectors(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to delete vectors %v", err)
	}

	// 输出操作结果
	log.Printf("delete vectors result:%#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.vectors.OSSVectorsClient;
import com.aliyun.sdk.service.oss2.vectors.models.DeleteVectorsRequest;
import com.aliyun.sdk.service.oss2.vectors.models.DeleteVectorsResult;
import java.util.*;

public class DeleteVectorsSample {
    public static void main(String[] args) throws Exception {
        CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
        try (OSSVectorsClient client = OSSVectorsClient.newBuilder()
                .region("cn-hangzhou")
                .accountId("1234567890")
                .credentialsProvider(provider)
                .build()) {
            DeleteVectorsRequest request = DeleteVectorsRequest.newBuilder()
                    .bucket("examplebucket")
                    .indexName("exampleindex")
                    .keys(Arrays.asList("key1", "key2"))
                    .build();
            DeleteVectorsResult result = client.deleteVectors(request);
            System.out.printf("status code: %d, request id: %s%n", result.statusCode(), result.requestId());
        }
    }
}

ossutil

删除向量存储空间examplebucket中向量名字为index,向量主键为key、key1的向量。

ossutil vectors-api delete-vectors --bucket examplebucket --index-name index --keys key,key1

API

调用DeleteVectors接口以删除向量数据。