
# 基于DWS的向量计算功能实现简单的商品搜索推荐系统
在AI与大模型技术快速发展的背景下，数据处理需求从传统的"**精确匹配** "转向了更复杂的"**语义理解**"。例如，在电商平台上，用户可能希望通过上传一张图片来搜索相似的商品，或者通过一段文字描述来找到最相关的商品。然而，传统的数据库系统在处理结构化数据时表现良好，但在处理非结构化数据时，如文本、图像、音视频等，由于缺乏对数据背后"含义"的理解，导致搜索结果不准确。
具体来说，传统数据库依赖于精确匹配或字段索引查询，无法满足AI应用中对模糊相似搜索的需求，如**以文搜图** 、**智能问答** 和**推荐系统** 等。如何解决这一问题，提高数据处理的效率和准确性？DWS集成**pgvector（0.8.0）** 插件，可插拔式加载，实现**库内向量计算检索** 能力。用户无需迁移数据或重构应用架构，即可在现有数据仓库中实现**向量检索**功能，从而有效解决上述问题。
**典型场景**如下：
- **以文搜图/以图搜图**：找到与输入图片最相似的图片。
- **智能问答/RAG**：在知识库中找到与用户问题最相关的文档片段。
- **推荐系统**：找到与用户兴趣向量最相似的商品。
本文以一个**商品搜索推荐系统**为例，介绍如何使用DWS向量计算功能实现语义搜索和商品推荐。
**业务背景**：
- 商品本身有标题、描述、分类、价格等字段。
- 借助大模型[Embedding]能力，将商品描述编码为10维向量（仅用于演示，实际常用768维向量）。
- 将用户的搜索关键字同样转化为10维向量。
- **目标**：通过相似性搜索找出最符合用户搜索意图的商品。
#### 基本概念
在阅读本文之前，建议先了解以下概念：
 表1基本概念 
| 概念                         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|:---|:---|
| **向量**                     | 将文本、图像等非结构化数据通过数学方式映射为固定维度的数值数组（如\[0.12, 0.34, -0.21, ...\]），使计算机能够通过数值计算来衡量数据之间的语义相似度。例如描述一个人的年龄、身高、体重，可以用\[30, 175, 70\]这个三维向量表示，让计算机可以理解其语义特征。                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Embedding** **（向量化/嵌入）** | 将非结构化数据（如商品描述文本）转换为向量的过程，通常借助大语言模型（如BERT、GPT等）完成。Embedding后的向量能够保留原始数据的语义信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **相似度度量**                  | 衡量两个向量之间"接近程度"的数学方法。常用度量包括**欧氏距离（L2距离）** 、**内积** 和**余弦相似度**。距离越小或相似度越高，表示两个向量在语义上越接近。 - **欧氏距离（L2距离）**：计算两个向量在空间中的"直线距离"。  - **内积（Inner Product）**：两个向量在方向和大小上的"投影"乘积，结果是一个标量。  - **余弦相似度（Cosine）**：比较两个向量的"方向"是否一致。   |
| **召回率**                    | 检索结果中相关结果占全部相关结果的比例。举例：数据库中与查询相关的内容有100条，系统检索后返回了80条相关的，那召回率就是 80/100 = 80%。 召回率与查询速度往往是此消彼长的关系，精确搜索的召回率为100%，近似搜索会牺牲部分召回率以换取更快的查询速度。                                                                                                                                                                                                                                                                                                                                                                                                                       |
   
#### 向量计算功能介绍
DWS的向量计算的详细语法介绍请参见[向量计算](https://support.huaweicloud.com/devg-911-dws/dws_04_1462.html)章节。
#### 向量数据类型
表2向量数据类型 
| 数据类型      | 精度                       | 支持维度         | 典型用途                          |
|:---|:---|:---|:---|
| vector    | 单精度浮点，4 字节。              | \<=16000     | 传统 embedding。                 |
| halfvec   | 半精度浮点（16 位浮点数，每元素 2 字节）。 | \<=16000     | 高维 embedding、内存敏感场景。          |
| bit       | 二进制向量类型（bit 向量）。         | \<= 64000    | 二进制哈希、图像／特征布尔表示。              |
| sparsevec | 稀疏向量类型。                  | \<=16000非0维度 | 文本TF-IDF稀疏特征、超高维稀疏 embedding。 |
   
#### 向量距离/相似度操作符
表3向量距离/相似度操作符 
| 操作符    | 距离／相似度类型              | 说明                         |
|:---|:---|:---|
| \<-\>  | Euclidean距离 (L2)      | 欧氏距离。                      |
| \<#\>  | （负）内积 (Inner Product) | 内积。                        |
| \<=\>  | 余弦（Cosine）相似度         | 向量方向差异。                    |
| \<+\>  | L1距离 (Taxicab)        | 向量坐标绝对差之和。                 |
| \<\~\> | Hamming距离             | 用于二进制bit向量，计算位不同数目。        |
| \<%\>  | Jaccard距离             | 用于二进制bit向量/集合表示，衡量交集/并集差异。 |
   
#### 向量索引类型
表4向量索引类型 
| 索引类型    | 原理                                  | 构建成本         | 查询速度 / 召回 (speed‑recall)        | 主要调优参数                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:---|:---|:---|:---|:---|
| IVFFlat | 将向量分成若干"lists"（簇/桶），查询时只扫描部分 lists。 | 构建快、内存使用低。   | 查询速度中等；召回率略低。扫描范围受"probes"参数影响。 | - lists（簇数）  - probes（扫描簇数）  - maxProbes（最大扫描簇数）                                                                                                                                                                                                                                                                |
| HNSW    | 基于图结构（多层可导航小世界图），通过跳跃访问近邻点。         | 构建较慢、内存占用较高。 | 查询速度快、召回率高；尤其适合高维、低延迟场景。        | - m（每层最大连接数）  - ef_construction（构建候选数）  - ef_search（查询候选数）  - max_scan_tuples（最大扫描节点数）  - mem_scan_multiplier（内存动态扩张率）   |
   
#### pgvector扩展里的操作符类
在pgvector（PostgreSQL的向量扩展）中，针对不同的距离度量方式，提供了三种主要的操作符类。该操作符，通常在创建索引的语句中指定。例如，
```
CREATE INDEX ON products USING hnsw (embedding vector_l2_ops) 
WITH (m = 16, ef_construction = 200);
```
 表5操作符 
| 操作符类              | 距离度量方式                 | 运算符   | 数学含义           | 适用场景                |
|:---|:---|:---|:---|:---|
| vector_l2_ops     | **欧氏距离** (L2)          | \<-\> | 两点间的直线距离。      | 通用场景，推荐系统、聚类分析。     |
| vector_ip_ops     | **内积 (Inner Product)** | \<#\> | 向量点积，衡量方向一致性。  | 语义搜索、信息检索（尤其是文本匹配）。 |
| vector_cosine_ops | **余弦相似度 (Cosine)**     | \<=\> | 向量夹角的余弦值，忽略长度。 | 文本相似度、句子匹配（最常用）。    |
   
#### 前提条件
- DWS集群版本须为**9.1.1.200及以上**。
- 使用向量计算功能前，需**联系技术支持** 修改集群参数**feature_support_options** ，开启**enable_pgvector**选项。
- 已通过大语言模型（如BERT、GPT等）获得商品描述的Embedding向量。**本文不涉及向量生成过程，假设向量已就绪**。
 
#### 步骤一：安装pgvector扩展
1. 确认GUC参数**feature_support_options** 已设置为**enable_pgvector**。请联系技术支持进行设置。
2. 在数据库中启用向量计算功能。 
   ```
   CREATE EXTENSION pgvector;
   ```
   
   
3. 执行以下查询，若返回pgvector则表示安装成功。 
   ```
   SELECT extname FROM pg_extension WHERE extname = 'pgvector';
   ```
   ![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002686394350.png "点击放大")
   
   
#### 步骤二：创建商品表及插入数据
1. 创建存储商品信息及向量数据的表。 
   业界常用768或1024维向量，涉及数据太大不便演示。为便于示例演示，本实践取10维向量数据用于模拟。
   其中，vector(10)表示该字段存储10维的向量。向量维度需与Embedding模型输出维度一致。
   ```
   DROP TABLE IF EXISTS products;
   CREATE TABLE products (
       id bigserial PRIMARY KEY,
       title text,
       description text,
       price numeric,
       embedding vector(10)   -- 10维向量，由商品描述(description)通过大模型Embedding生成
   );
   ```
   
   
2. 向商品表中插入商品信息及对应的向量数据。 
   ```
   INSERT INTO products (title, description, price, embedding) VALUES
   ('Wireless Earbuds', 'Bluetooth wireless earbuds with charging case', 59.9, '[0.12, 0.34, -0.21, 0.15, -0.08, 0.33, 0.02, -0.41, 0.19, 0.07]'),
   ('Noise Cancelling Headphones', 'Over-ear headphones with active noise cancellation', 129.9, '[0.11, 0.36, -0.19, 0.17, -0.06, 0.31, 0.04, -0.39, 0.21, 0.05]'),
   ('Gaming Headset', 'Wired gaming headset with microphone', 79.9, '[0.10, 0.33, -0.25, 0.14, -0.03, 0.29, 0.01, -0.37, 0.18, 0.09]'),
   ('Smartphone Stand', 'Adjustable phone stand for desk use', 12.9, '[0.45, -0.12, 0.08, 0.48, -0.20, 0.11, 0.37, -0.05, 0.44, -0.15]'),
   ('USB-C Charger', 'Fast charging USB-C power adapter', 19.9, '[0.42, -0.15, 0.05, 0.46, -0.18, 0.08, 0.34, -0.07, 0.41, -0.12]'),
   ('Mechanical Keyboard', 'Mechanical keyboard with blue switches', 89.9, '[0.55, 0.02, -0.31, 0.50, 0.06, -0.28, 0.22, -0.44, 0.53, -0.09]'),
   ('Wireless Mouse', 'Ergonomic wireless mouse', 29.9, '[0.53, 0.01, -0.28, 0.51, 0.04, -0.25, 0.20, -0.42, 0.49, -0.07]'),
   ('Laptop Backpack', 'Water-resistant laptop backpack', 49.9, '[0.60, -0.05, -0.10, 0.58, -0.08, -0.15, 0.42, -0.02, 0.56, -0.13]'),
   ('4K Monitor', '27-inch 4K UHD computer monitor', 299.9, '[0.58, 0.04, -0.35, 0.55, 0.07, -0.32, 0.39, -0.10, 0.61, -0.18]'),
   ('Webcam', 'HD webcam for video conferencing', 39.9, '[0.52, -0.01, -0.20, 0.49, -0.03, 0.15, 0.36, -0.08, 0.47, -0.11]'),
   ('Bluetooth Speaker', 'Portable Bluetooth speaker with deep bass', 45.9, '[0.14, 0.30, -0.18, 0.13, -0.09, 0.28, 0.03, -0.35, 0.16, 0.01]'),
   ('Smart Watch', 'Fitness tracking smart watch', 99.9, '[0.20, 0.40, -0.22, 0.18, -0.05, 0.37, 0.09, -0.41, 0.23, 0.06]'),
   ('Fitness Tracker', 'Lightweight activity and sleep tracker', 49.9, '[0.22, 0.38, -0.24, 0.19, -0.07, 0.35, 0.07, -0.39, 0.25, 0.04]'),
   ('Tablet Stylus', 'Stylus pen for tablets', 25.9, '[0.48, -0.10, 0.12, 0.45, -0.17, 0.14, 0.40, -0.06, 0.50, -0.16]'),
   ('Laptop Cooling Pad', 'Cooling pad with dual fans', 34.9, '[0.57, -0.02, -0.15, 0.54, -0.04, -0.12, 0.46, -0.01, 0.59, -0.14]');
   ```
   
   
#### 步骤三：查询数据
1. **语义相似度查询** 。根据用户搜索词的向量，查找语义最相似的商品。\<-\>为L2距离操作符，值越小表示越相似。LIMIT 10表示返回相似度最高的Top-10商品。
   
   ```
   SELECT id, title, price
   FROM products
   ORDER BY embedding <=> '[0.09, -0.05, 0.92, 0.11, -0.03, 0.85, 0.30, -0.50, 0.15, 0.02]'   -- 用户搜索词的Embedding向量（10维）
   LIMIT 10;
   ```
   ![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002689757854.png "点击放大")
   
   
2. **混合查询。** 在语义相似度查询的基础上，叠加传统结构化过滤条件，实现更精准的搜索。先按价格过滤（price \< 2000），再按语义相似度排序，适用于"预算范围内找最相似商品"的场景。
   
   ```
   SELECT id, title, price
   FROM products
   WHERE price < 2000                          -- 先按价格过滤
   ORDER BY embedding <=> '[0.09, -0.05, 0.92, 0.11, -0.03, 0.85, 0.30, -0.50, 0.15, 0.02]'  -- 再按语义相似度排序
   LIMIT 10;
   ```
   ![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002719480937.png "点击放大")
   
   
3. **创建向量索引加速查询。** 在大数据量场景下，通过创建**近似近邻搜索索引** 提升向量查询性能。
   
   DWS向量计算默认使用**精确近邻**搜索，提供100%召回率但查询速度较慢。当数据量较大时，建议创建HNSW或IVFFlat索引，以牺牲少量召回率为代价大幅提升查询速度。
   索引参数说明参见[表6]。vector_l2_ops表示**欧氏距离** (L2)所用的操作符类，更多请参见[表5]。
   ![](https://support.huaweicloud.com/bestpractice-dws/public_sys-resources/caution_3.0-zh-cn.png)
   索引创建时指定的操作符类（如vector_l2_ops）必须与查询中使用的距离操作符（如\<-\>）一致。若查询使用\<=\>（余弦相似度），则需创建索引时使用vector_cosine_ops。
   ```
   -- 方式一：创建HNSW索引（查询性能更优，适合查询频繁的场景）
   CREATE INDEX ON products USING hnsw (embedding vector_l2_ops) 
   WITH (m = 16, ef_construction = 200);
   -- 方式二：创建IVFFlat索引（构建速度更快，适合数据量大的场景）
   CREATE INDEX ON products USING ivfflat (embedding vector_l2_ops) 
   WITH (lists = 100);
   ```
    表6**索引参数说明** 
   | 索引类型    | 参数              | 说明                          | 建议值                |
   |:---|:---|:---|:---|
   | HNSW    | m               | 每层图中每个节点的最大连接数，影响索引质量和内存占用。 | 16（默认），数据量大时可增大至48 |
   | HNSW    | ef_construction | 构建索引时的搜索宽度，值越大索引质量越高但构建越慢。  | 200（默认）            |
   | IVFFlat | lists           | 倒排列表数量，值越大查询越快但召回率可能降低。     | 建议设为sqrt(行数)左右     |
      
   
   
 
#### 查询结果解读
#### 场景一：商品搜索
用户搜索词为wireless audio headset，将其转为向量后查询：
```
SELECT id, title
FROM products
ORDER BY embedding <=> '[0.13, 0.35, -0.20, 0.16, -0.07, 0.32, 0.03, -0.38, 0.20, 0.04]'   -- 用户搜索词的Embedding向量（10维）
LIMIT 10;
```
耳机、音响类商品相较于表中其他商品类别，与用户搜索词在语义上更为接近。即使商品标题中没有精确包含headset这个词，仍然会在结果中排序靠前，体现了语义搜索的优势。
![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002690028608.png)
#### 场景二：商品推荐
用户正在浏览Noise Cancelling Headphones商品，根据商品向量相似性进行关联推荐：
```
SELECT p2.title, p2.price
FROM products p1
JOIN products p2 ON p1.id <> p2.id          -- 排除自身
WHERE p1.title = 'Noise Cancelling Headphones'
ORDER BY p2.embedding <=> p1.embedding      -- 计算两个商品向量的L2距离，越小越相似
LIMIT 10;
```
耳机、音响类商品与用户正在浏览的Noise Cancelling Headphones产品相关性更高，因此排在推荐列表前列。
![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002719872211.png)
#### 总结
通过DWS向量计算扩展能力，我们将传统以结构化查询为核心的数据库系统升级为能够具备语义理解与相似度计算能力的统一数据底座。系统不仅支持向量数据的存储与高效相似度检索，还允许业务方直接通过标准SQL完成语义搜索、推荐与相似内容匹配，无需引入额外的向量引擎或复杂的数据同步链路。
依托HNSW、IVFFlat近似最近邻索引，向量查询在大规模数据场景下依然具备可控的性能与稳定的响应能力。同时，向量检索能力与传统结构化查询、过滤条件、JOIN逻辑的深度融合，使得搜索推荐、个性化分析以及RAG等AI应用可以自然落地在现有数仓与业务体系之上。
最终，这一能力扩展不仅降低了系统架构复杂度，也显著提升了数据平台对新一代智能应用的支撑能力，实现了从"数据查询"向"语义计算与业务决策支持"的演进。
