
# 使用IVF_GRAPH_PQ算法实现向量检索
本文介绍如何通过IVF_GRAPH_PQ算法在CSS向量数据库中实现对百亿级向量的高性能、低成本检索。
#### 应用场景
在处理大规模向量数据时，传统的索引方法经常无法满足高性能和低成本的要求。例如，在图像识别、推荐系统、自然语言处理等业务中，当数据总量超过百亿、每日新增写入超1亿时，如何实现高效、低成本的向量相似性检索成为一大挑战。CSS向量数据库通过预构建共享中心点索引（GRAPH_PQ）并关联IVF_GRAPH_PQ算法类型的向量索引，实现对百亿级向量的高性能、低成本检索。
IVF_GRAPH_PQ是组合索引算法，核心组件包括：
- IVF（Inverted File）：通过聚类生成中心点向量，将数据划分子空间（Centroid）。构建图索引（Graph）加速子空间选择，提升查询效率。
- PQ（Product Quantization）：对向量进行量化压缩，降低存储和计算开销。
- 共享中心点机制：多个分片/段共享同一组中心点，减少重复聚类开销。
IVF_GRAPH_PQ索引算法的向量数据库适用于数据总量超过百亿、每日新增写入超1亿的海量数据场景，例如图像识别、推荐系统、自然语言处理等需要向量相似性检索的业务。
#### 方案流程
1. 通过聚类或采样生成中心点向量，构建GRAPH_PQ中心点索引。
2. 关联中心点索引表，使用IVF_GRAPH_PQ算法创建向量索引。
3. 写入向量数据。
4. 通过向量相似性计算实现高效检索。
 
#### 方案优势
- 共享中心点：索引跨分片/分段全局共享中心点向量，减少重复聚类开销。
- 图索引加速：通过图结构优化子空间选择效率，提升性能。
- PQ量化降本：降低索引存储和查询计算开销。
- 资源优化：索引无需常驻内存，节省集群资源成本。
 
#### 约束限制
该解决方案适用的集群版本：Elasticsearch 7.6.2、Elasticsearch 7.10.2、OpenSearch 1.3.6、OpenSearch 2.19.0、OpenSearch 3.4.0（镜像版本不低于3.4.0_26.6.0_xxx）。
#### 前提条件
- 已创建CSS向量数据库，本文以Elasticsearch 7.10.2集群为例，集群节点规格是"内存优化型"。
- 已通过聚类或随机采样获取中心点向量数据（数量为总数据量的千分之一\~万分之一）。
 
#### 操作步骤
1. 登录Kibana进入命令执行页面。Elasticsearch集群支持多种客户端访问，本文仅以CSS服务集成的Kibana为例介绍操作步骤。 
   1. 登录[云搜索服务管理控制台](https://console.huaweicloud.com/elasticsearch/)。
   
   2. 在左侧导航栏，选择"集群管理 \> Elasticsearch"。
   
   3. 在集群列表，选择目标集群，单击操作列的"Kibana"，登录Kibana。
   
   4. 在Kibana左侧导航栏选择"Dev Tools"，进入操作页面。 控制台左侧是命令输入框，其右侧的三角形图标为执行按钮，右侧区域则显示执行结果。
      
   
   
   
   
2. 创建中心点索引表。 
   执行如下命令，创建中心点索引表，例如"my_dict"。
   其中，索引分片数"number_of_shards"必须配置为"1"，向量索引的算法类型"algorithm"必须配置为"GRAPH_PQ"。
   ```
   PUT my_dict 
   { 
     "settings": { 
       "index": { 
         "vector": true 
       }, 
       "number_of_shards": 1, 
       "number_of_replicas": 0 
     }, 
     "mappings": { 
       "properties": { 
         "my_vector": { 
           "type": "vector", 
           "dimension": 4, 
           "indexing": true, 
           "algorithm": "GRAPH_PQ", 
           "metric": "euclidean" 
         } 
       } 
     } 
   }
   ```
   
   
3. 导入中心点向量。 
   执行以下命令，将采样或者聚类得到的中心点向量写入新建的中心点索引表中。
   - 写入单条数据：
     ```
     POST my_dict/_doc
     {
       "my_vector": [1.0, 1.0, 1.0, 1.0]
     }
     ```
     
   
   - 批量写入多条数据：
     ```
     POST my_dict/_bulk
     {"index": {}}
     {"my_vector": [2.0, 2.0, 2.0, 2.0]}
     {"index": {}}
     {"my_vector": [3.0, 3.0, 3.0, 3.0]}
     {"index": {}}
     {"my_vector": [4.0, 4.0, 4.0, 4.0]}
     ```
     
   
   
   
   
4. 注册中心点索引表。 
   执行以下命令，将中心点索引表注册为具有全局唯一标识名称（dict_name）的Dict对象，"dict_name"可以自定义。
   ```
   PUT _vector/register/my_dict 
   { 
     "dict_name": "my_dict_name" 
   }
   ```
   
   
5. 创建IVF_GRAPH_PQ索引。 
   执行以下命令，创建IVF_GRAPH_PQ算法类型的向量索引（例如"my_index"），通过向量字段里的"dict_name"关联上一步注册的中心点索引表。
   ```
   PUT my_index 
   { 
     "settings": { 
       "index": { 
         "vector": true,
         "sort.field": "my_vector.centroid"  # 将向量字段的centroid子字段设置为排序字段
       } 
     }, 
     "mappings": { 
       "properties": { 
         "my_vector": { 
           "type": "vector", 
           "indexing": true, 
           "algorithm": "IVF_GRAPH_PQ", 
           "dict_name": "my_dict_name", 
           "offload_ivf": true 
         } 
       } 
     } 
   }
   ```
   
   
6. 导入全量向量数据。 
   执行以下命令，将全量的向量数据写入新建的IVF_GRAPH_PQ索引。
   - 写入单条数据：
     ```
     POST my_index/_doc
     {
       "my_vector": [2.0, 3.0, 4.0, 5.0]
     }
     ```
     
   
   - 批量写入多条数据：
     ```
     POST my_index/_bulk
     {"index": {}}
     {"my_vector": [2.0, 3.0, 4.0, 5.0]}
     {"index": {}}
     {"my_vector": [1.0, 2.0, 3.0, 4.0]}
     {"index": {}}
     {"my_vector": [3.0, 4.0, 5.0, 6.0]}
     ```
     
   
   
   
   
7. 查询向量数据。 
   执行以下命令，进行向量检索：
   ```
   POST my_index/_search
   {
     "size":2,
     "query": {
       "vector": {
         "my_vector": {
           "vector": [1.0, 1.0, 1.0, 1.0],
           "topk":2
         }
       }
     }
   }
   ```
   如果成功返回最相似的2条结果，则表示检索成功。
   
   
 
#### 相关文档
- 详细了解CSS向量数据库的使用，请参见[向量检索特性介绍](https://support.huaweicloud.com/usermanual-css/css_01_0118.html)。
- 了解如何快速上手CSS向量检索功能，请参见[使用Elasticsearch实现向量检索](https://support.huaweicloud.com/qs-css/css_08_0002.html)。
 
