
# 使用Elasticsearch实现向量检索
随着深度学习技术的不断发展，基于语义向量的检索方法通过将文本、图像等非结构化数据映射到高维向量空间，使相似内容在向量空间中距离相近。相比传统的关键词匹配检索，这种语义层面的相似性计算能显著提升召回率和准确率。该技术已成功应用于图像搜索、视频内容检索、个性化广告推荐等诸多场景，大幅提升了相关应用的实际效果。
CSS向量引擎基于ANN算法实现向量检索。本章节为您提供了一个通过Elasticsearch集群实现向量检索的示例，您可以参考此示例了解CSS向量数据库，包括创建向量索引、导入向量数据、向量检索等操作。
#### 场景描述
某电商平台希望提升商品搜索的准确率，通过深度学习模型将商品图片转换为语义向量，并结合价格、名称等属性存储至Elasticsearch集群。用户可通过以下方式实现混合搜索：
- 纯向量检索：查找与目标图片最相似的商品。
- 过滤检索：在指定价格区间内查找相似商品。
- 组合查询：结合关键词与向量相似度进行搜索。
假设该电商网站经营商品的向量数据如[表1]所示。
 表1某电商网站经营的商品 
| productName    | image_vector     | price |
|:---|:---|:---|
| 2017秋装新款文艺衬衫女装 | \[1.0, 1.0\]     | 100.0 |
| 2017秋装新款文艺衬衫女装 | \[1.0, 2.0\]     | 200.0 |
| 2017秋装新款文艺衬衫女装 | \[1.0, 3.0\]     | 300.0 |
| 2018春装新款牛仔裤女装  | \[10.0, 20.0\]   | 100.0 |
| 2018春装新款牛仔裤女装  | \[10.0, 30.0\]   | 200.0 |
| 2017春装新款休闲裤女装  | \[100.0, 200.0\] | 100.0 |
| 2017春装新款休闲裤女装  | \[100.0, 300.0\] | 200.0 |
   
#### 操作流程
以下是使用Elasticsearch集群完成数据搜索的操作步骤。
开始向量检索前，请务必按[准备工作]指导完成必要操作。
1. [步骤一：创建Elasticsearch集群]：创建一个非安全模式的Elasticsearch集群用于向量检索。
2. [步骤二：登录Kibana]：登录Kibana，访问集群。
3. [步骤三：创建向量索引]：创建向量索引，用于存储向量数据。
4. [步骤四：导入向量数据]：使用开源Elasticsearch API导入数据。
5. [步骤五：向量检索]：在Elasticsearch集群中对数据进行纯向量搜索和组合查询。
6. [步骤六：删除索引]：当不再使用对应的索引数据时，可以删除对应索引节约资源。
 
 #### 准备工作
已注册华为账号并开通华为云，进行了实名认证，且在使用云搜索服务前检查账号状态，账号不能处于欠费或冻结状态。
如果您还没有华为账号，请参考以下步骤创建。
1. 打开[华为云网站](https://www.huaweicloud.com/)。
2. 在页面右上角单击"注册"，根据提示信息完成注册。
3. 勾选服务条款， 单击"开通"。
4. 实名认证，请参考：
   - 个人账号：[实名认证](https://support.huaweicloud.com/usermanual-account/zh-cn_topic_0077914254.html)
   
   - 企业账号：[实名认证](https://support.huaweicloud.com/usermanual-account/zh-cn_topic_0077914253.html)
    
 
 #### 步骤一：创建Elasticsearch集群
创建一个非安全模式的Elasticsearch集群用于向量检索。
1. 登录[云搜索服务管理控制台](https://console.huaweicloud.com/elasticsearch/)。
2. 在左侧导航栏选择"集群管理 \> Elasticsearch"。
3. 在集群列表右上角，单击"创建集群"，默认进入新版创建页面。
   图1新版创建页面   
   ![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002361844584.png "点击放大") 
4. 集群配置，选择集群类型和版本。
   表2集群配置 
   | 参数   | 示例                | 说明                                                                                                                                                                        |
   |:---|:---|:---|
   | 集群类型 | **Elasticsearch** | 选择"Elasticsearch"。                                                                                                                                                        |
   | 集群版本 | **7.10.2**        | 选择所需的集群版本，支持的版本以界面可选项为准。 Elasticsearch集群仅7.6.2和7.10.2版本自带CSS向量搜索引擎，如果要使用CSS向量数据库功能，则必须选择这两个版本。 |
      
   
5. 基础配置，选择当前区域、可用区和计费模式。
   表3基础配置 
   | 参数   | 示例         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   |:---|:---|:---|
   | 当前区域 | **华北-北京四** | 选择集群的所在区域。区域指集群的物理数据中心所在的位置，不同区域的云服务产品之间内网互不相通。建议就近选择靠近您业务的区域，可减少网络时延，提高访问速度。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | 可用区  | **可用区1**   | 选择集群工作区域下关联的可用区。可用区指在同一区域下，电力、网络隔离的物理区域，可用区之间内网互通，不同可用区之间物理隔离。 最多支持配置3个可用区。                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | 计费模式 | **按需计费**   | 选择集群的计费模式，集群支持包年/包月和按需计费两种模式。 - **包年/包月**：预付费模式，按照订单的购买周期结算。  - **按需计费**：后付费模式，按照集群实际使用时长计费，计费周期为一小时，不足一小时按一小时计费。   |
      
   
6. 配置数据节点。
   数据节点用于存储集群数据，当集群未启用Master节点和Client节点时，数据节点将同时承担集群管理、存储数据、提供接入集群和分析数据的职责。
   图2配置数据节点   
   ![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002328380009.png "点击放大")
   表4数据节点配置 
   | 参数        | 示例                                                                                                                                                                                                                                                                                                                                                                                                                   | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   |:---|:---|:---|
   | CPU架构     | **X86计算**                                                                                                                                                                                                                                                                                                                                                                                                            | 选择数据节点的CPU架构。支持"X86计算"和"鲲鹏计算"，具体支持的类型由实际区域环境决定。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | 节点规格      | **ess.spec-4u8g**                                                                                                                                                                                                                                                                                                                                                                                                    | 选择数据节点的规格。单击"选择节点规格"，在弹框中选择合适的规格。 规格列表的"vCPUs \| 内存"呈现了规格的CPU核数和内存，"建议存储范围"呈现了该规格支持的存储容量。 不同区域支持的节点规格不同，请以实际环境为准。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | 节点存储类型和容量 | - **高I/O**  - **100GB**   | 选择数据节点的存储类型和容量。 - 当"节点规格"选择的是云硬盘时，需要选择云硬盘类型，并根据业务需要配置存储容量。 - 不同区域支持的云硬盘类型不同，请以实际环境为准。  - 节点存储容量的取值范围由所选的"节点规格"决定，且必须是20的倍数。  - 节点存储容量不支持就地缩容，请评估好业务量，合理选择。    - 当"节点规格"选择的是本地盘时，无需配置节点存储类型，节点存储容量是固定值，由选择的本地盘规格决定。   |
   | 节点数量      | **1**                                                                                                                                                                                                                                                                                                                                                                                                                | 设置集群中的数据节点个数。 - 当集群配置了Master节点，则数据节点的节点数量支持1\~200。  - 当集群未配置Master节点，则数据节点的节点数量支持1\~32。  - 建议数据节点的节点数量大于或等于3，以提升集群可用性。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
      
   
7. Master节点、Client节点和冷数据节点均保持默认值，不启用即可。
   - Master节点负责管理集群中所有节点任务，如集群元数据、索引及分片分配，保障大规模集群稳定运行，适用于需高可用性与集中管控的场景。
   
   - Client节点负责接收并协调外部请求（如搜索和写入），优化高负载查询和集群扩展性，适用于处理复杂查询和大规模分片场景。
   
   - 冷数据节点用于存储查询时延要求不高且数据量大的历史数据，适用于大规模数据集存储，有利于优化存储成本和查询性能。
    
8. 网络配置，设置集群的VPC、IP地址和安全组。
   图3网络配置   
   ![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002328404261.png "点击放大")
   表5网络配置 
   | 参数     | 示例                 | 说明                                                                                                                                                                        |
   |:---|:---|:---|
   | 虚拟私有云  | **vpc-default**    | 指定集群使用的虚拟专用网络，可以对不同业务进行网络隔离                                                                                                                                               |
   | 子网     | **subnet-default** | 指定集群使用的子网，通过子网提供与其他网络隔离的、可以独享的网络资源，以提高网络安全。 选择当前虚拟私有云下的子网。                                       |
   | IPv4地址 | **自动分配IPv4地址**     | 分配集群节点的IPv4地址。                                                                                                                                                            |
   | 安全组    | **default**        | 指定集群使用的安全组，安全组起着虚拟防火墙的作用，为集群提供安全的网络访问控制策略。 所选安全组的入方向规则中，"协议端口"必须为"全部"或包含9200的端口范围，否则外部业务访问可能会异常。 |
      
   
9. 安全模式配置。关闭安全模式，本集群仅做入门指导使用，无需启用安全模式。
   - 安全模式的集群会对集群进行通讯加密和安全认证。
   
   - 非安全模式的集群无需安全认证即可访问，并且采用HTTP明文传输数据。建议确认访问环境的安全性，勿将访问接口暴露到公网环境上。
    
10. 集群管理配置，设置集群名称、企业项目等信息。
    表6集群管理 
    | 参数   | 示例                   | 说明                                                                                                                                                                                                                                                                     |
    |:---|:---|:---|
    | 集群名称 | **Sample-ESCluster** | 自定义集群名称。                                                                                                                                                                                                                                                               |
    | 添加描述 | **不添加**              | 为集群添加描述，方便用户识别。                                                                                                                                                                                                                                                        |
    | 企业项目 | **default**          | 给集群绑定一个企业项目。 企业项目是一种云资源管理方式，企业项目管理服务提供统一的云资源按项目管理，以及项目内的资源管理、成员管理，默认项目为"default"。 如果开通了"企业项目"，请从下拉列表中选择所在的企业项目。 |
    | 标签   | **不添加**              | 为集群添加标签，方便用户识别和管理拥有的集群资源。 每个集群最多可以设置20个标签。                                                                                                                                                  |
       
    
11. 更多配置，单击![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002385381466.png)展开更多集群高级配置，根据业务需要设置自动创建集群快照、终端节点服务等功能。本集群仅做入门指导使用，无需更多配置，保持默认不启用即可。
12. 单击"立即创建"，开始创建集群。
13. 返回集群列表，查看新建的集群。当集群创建成功后，"集群状态"会变为"可用"。
    图4查看集群状态   
    ![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002294363734.png "点击放大") 
 
 #### 步骤二：登录Kibana
集群创建成功后，通过Kibana访问Elasticsearch集群。
1. 在Elasticsearch集群列表，选择已创建的"Sample-ESCluster"集群，单击操作列中的"Kibana"进入Kibana控制台。
2. 在Kibana的左侧导航中选择"Dev Tools"，进入Console界面。
   控制台左侧是命令输入框，其右侧的三角形图标为执行按钮，右侧区域则显示执行结果。
   图5Console界面   
   ![](https://support.huaweicloud.com/qs-css/figure/zh-cn_image_0000002295063054.png "点击放大") 
 
 #### 步骤三：创建向量索引
在Elasticsearch集群中创建向量索引，用于存储向量数据。
在Kibana中执行如下命令，创建向量索引"my_store"。
```
PUT /my_store 
{
  "settings": {       // 索引级别的配置
    "index": {
      "vector": true  // 启用向量检索功能
    }
  },
  "mappings": {       // 定义文档字段结构和类型
    "properties": {
      "productName": {    // 商品名称字段（文本类型）
        "type": "text",   // 标准文本类型，支持全文搜索
        "analyzer": "ik_smart"  // 使用ik_smart中文分词器进行智能分词
      },
      "image_vector": {   // 图像特征向量字段
        "type": "vector", // 声明为向量类型
        "dimension": 2,   // 向量维度（示例简化使用2维，实际应匹配模型输出维度，常用512/768等高维向量）
        "indexing": true, // 启用向量索引以支持相似度搜索
        "algorithm": "GRAPH",  // 使用图算法构建近似最近邻(ANN)索引
        "metric": "euclidean"  // 使用欧氏距离作为相似度度量标准
      },
      "price": {                // 商品价格字段
        "type": "float"         // 浮点数类型，支持范围查询和数值计算
      }
    }
  }
}
```
返回结果如下所示：
```
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_store"
}
```
 #### 步骤四：导入向量数据
Elasticsearch集群支持通过多种方式导入数据，本示例选择在Kibana使用开源Elasticsearch API导入数据。
在Kibana中执行如下命令，将向量数据导入到"my_store"索引中。
```
POST /my_store/_bulk
{"index":{}}
{"productName":"2017秋装新款文艺衬衫女装","image_vector":[1.0, 1.0],"price":100.0}
{"index":{}}
{"productName":"2017秋装新款文艺衬衫女装","image_vector":[1.0, 2.0],"price":200.0}
{"index":{}}
{"productName":"2017秋装新款文艺衬衫女装","image_vector":[1.0, 3.0],"price":300.0}
{"index":{}}
{"productName":"2018春装新款牛仔裤女装","image_vector":[10.0, 20.0],"price":100.0}
{"index":{}}
{"productName":"2018春装新款牛仔裤女装","image_vector":[10.0, 30.0],"price":200.0}
{"index":{}}
{"productName":"2017春装新款休闲裤女装","image_vector":[100.0, 200.0],"price":100.0}
{"index":{}}
{"productName":"2017春装新款休闲裤女装","image_vector":[100.0, 300.0],"price":200.0}
```
当返回结果信息中"errors"字段的值为"false"时，表示导入数据成功。
 #### 步骤五：向量检索
在Elasticsearch集群中对数据进行纯向量检索和组合查询。
- **纯向量检索**
  假设用户提供了一张商品图片，想要查找相似商品。首先，集群通过向量化模型获得查询图片的特征向量，然后使用向量查询语法进行相似度查询。
  在Kibana中执行如下搜索命令：
  ```
  GET /my_store/_search
  {
    "size": 3,  // 要求返回前3个最相关的结果
    "_source": { 
      "excludes": "image_vector"  // 排除返回结果中的image_vector字段
    }, 
    "query": {
      "vector": {  // 启用向量搜索功能
        "image_vector": {  // 指定目标向量字段名称（需与索引映射一致）
          "vector": [1.0, 2.0],  // 待查询的特征向量（此处为简化示例，实际维度应与模型输出一致）
          "topk": 3          // 返回最相似的3个候选结果
        }
      }
    }
  }
  ```
  返回结果如下所示，Elasticsearch根据查询向量与存储的向量数据之间的相似度得分进行结果的排序。
  ```
  {
    "took" : 1,  // 查询耗时1毫秒
    "timed_out" : false,  // 未发生查询超时
    "_shards" : {  // 分片执行情况
      "total" : 1,  // 总分片数
      "successful" : 1,  // 成功执行分片数
      "skipped" : 0,  // 跳过分片数
      "failed" : 0  // 失败分片数
    },
    "hits" : {
      "total" : {  // 匹配文档总数
        "value" : 3,  // 精确匹配3条（eq表示精确计数）
        "relation" : "eq"
      },
      "max_score" : 1.0,  // 最高相似度得分（取决于向量空间的距离算法）
      "hits" : [  // 命中文档列表（按相似度得分降序排列）
        {
          "_index" : "my_store",          // 文档所属索引
          "_type" : "_doc",  // 文档类型，固定取值
          "_id" : "JPL5r5YBWkpNKdSUkRc9",  // 文档唯一标识符
          "_score" : 1.0,  // 当前文档与查询向量的相似度得分
          "_source" : {  // 存储的原始文档数据（已过滤image_vector）
            "price" : 200.0,
            "productName" : "2017秋装新款文艺衬衫女装"
          }
        },
        // ...（其他相似结果结构相同，分数递减）
      ]
    }
  }
  ```
  

- **混合搜索**
  假设用户提供了一张商品图片，想要查找相似商品，并且限定了价格范围。可以通过混合查询的语法实现向量检索+范围过滤。
  在Kibana中执行如下搜索命令：
  ```
  GET /my_store/_search
  {
    "size": 3,                     // 要求返回前3个最相关的结果
    "_source": { 
      "excludes": "image_vector"   // 排除返回结果中的image_vector字段
    }, 
    "query": {
      "vector": {                  // 启用向量搜索功能
        "image_vector": {          // 指定目标向量字段名称（需与索引映射一致）
          "vector": [1.0, 2.0],    // 待查询的特征向量（此处为简化示例，实际维度应与模型输出一致）
          "topk": 3,               // 返回最相似的3个候选结果
          "filter": {              // 混合过滤条件（先执行过滤再计算相似度）
            "range": {             // 价格范围过滤
              "price": {
                "lte": 300         // 仅保留价格小于或等于300的商品
              }
            }
          }
        }
      }
    }
  }
  ```
  查询流程：在索引中筛选出所有价格小于或等于300的商品，计算过滤后商品的image_vector字段与待查询向量的相似度，按相似度分数降序排列（score字段），取top3相似度最高的商品，移除image_vector字段返回，保留商品价格和名称等核心信息。
  返回结果如下所示：
  ```
  {
    "took" : 1,// 查询耗时1毫秒
    "timed_out" : false,// 查未发生查询超时
    "_shards" : {// 分片执行情况
      "total" : 1,        // 总分片数
      "successful" : 1,   // 成功执行分片数
      "skipped" : 0,      // 跳过分片数
      "failed" : 0        // 失败分片数
    },
    "hits" : {
      "total" : {// 匹配文档总数
        "value" : 3,      // 精确匹配3条（eq表示精确计数）
        "relation" : "eq"
      },
      "max_score" : 1.0,  // 最高相似度得分（取决于向量空间的距离算法）
      "hits" : [    // 命中文档列表（按相似度降序排列）
        {
          "_index" : "my_store",  // 文档所属索引
          "_type" : "_doc",       // 文档类型
          "_id" : "JPL5r5YBWkpNKdSUkRc9", // 文档唯一ID
          "_score" : 1.0,         // 当前文档与查询向量的相似度得分（归一化后）
          "_source" : {           // 存储的原始文档数据（已过滤image_vector）
            "price" : 200.0,
            "productName" : "2017秋装新款文艺衬衫女装"
          }
        },
        // ...（其他相似结果结构相同，分数递减）
      ]
    }
  }
  ```
  
 
 #### 步骤六：删除索引
当不再使用对应的索引数据时，可以在Kibana中执行如下命令删除对应索引，避免造成资源浪费。
```
DELETE /my_store
```
返回结果如下所示。
```
{
  "acknowledged" : true
}
```
#### 后续步骤
已完成数据搜索业务，无需继续使用集群时，可删除集群释放资源。
![](https://support.huaweicloud.com/qs-css/public_sys-resources/warning_3.0-zh-cn.png)
由于集群删除后，数据无法恢复，请谨慎操作。
1. 登录[云搜索服务管理控制台](https://console.huaweicloud.com/elasticsearch/)。
2. 在左侧导航栏选择"集群管理 \> Elasticsearch"。
3. 在集群列表，选择"Sample-ESCluster"集群，在操作列单击"更多"\>"删除"。
4. 在弹出的确认对话框中，输入"DELETE"，单击"确定"完成操作。
 
#### 相关文档
- 详细了解CSS向量数据库的使用，请参见[向量检索特性介绍](https://support.huaweicloud.com/usermanual-css/css_01_0118.html)。
- 了解CSS向量数据库的性能比较，请参见[Elasticsearch向量检索的性能测试和比较](https://support.huaweicloud.com/bestpractice-css/css_07_0050.html)。
- 了解CSS向量数据库和搜索大模型相结合实现AI搜索功能，请参见[Elasticsearch AI搜索介绍](https://support.huaweicloud.com/usermanual-css/css_01_0241.html)。
 
