RedisVL 不仅支持基本的向量相似性搜索,还提供了多种高级查询类型,帮助您构建更智能、更精准的检索应用。本指南将深入讲解三种核心高级查询------TextQuery (全文搜索)、HybridQuery (混合搜索)和 MultiVectorQuery(多向量搜索)。
📌 前提条件
在开始之前,请确保您已具备以下环境:
- 安装 RedisVL:
pip install redisvl - 一个运行中的 Redis 实例(推荐 Redis 8+ 或 Redis Cloud)
- 如需使用
HybridQuery,需要 Redis >= 8.4.0 且redis-py >= 7.1.0
🎯 该要
- 使用
TextQuery进行全文搜索,并灵活调整评分算法 - 利用
HybridQuery和AggregateHybridQuery将文本搜索与向量搜索相结合,获得"语义 + 关键词"的双重优势 - 通过
MultiVectorQuery跨多个向量字段(如文本向量、图像向量)进行联合检索 - 配置索引级或查询级停用词,优化文本搜索效果
📦 数据准备与索引定义
首先准备一组商品数据,包含文本描述、类别、价格、评分以及两种向量(文本嵌入和图像嵌入)。这些数据将贯穿全文示例。
python
import numpy as np
from jupyterutils import result_print
data = [
{
'product_id': 'prod_1',
'brief_description': 'comfortable running shoes for athletes',
'full_description': 'Engineered with a dual-layer EVA foam midsole...',
'category': 'footwear',
'price': 89.99,
'rating': 4.5,
'text_embedding': np.array([0.1, 0.2, 0.1], dtype=np.float32).tobytes(),
'image_embedding': np.array([0.8, 0.1], dtype=np.float32).tobytes(),
},
# ... 更多商品(省略具体内容,与原文一致)
]
定义索引模式(Schema)
索引模式决定了 Redis 如何存储和索引字段。本例中我们定义了:
| 字段名 | 类型 | 用途 |
|---|---|---|
product_id, category |
Tag | 精确过滤 |
brief_description, full_description |
Text | 全文搜索 |
price, rating |
Numeric | 数值范围过滤 |
text_embedding (3维) |
Vector | 文本语义向量 |
image_embedding (2维) |
Vector | 图像语义向量 |
python
schema = {
"index": {
"name": "advanced_queries",
"prefix": "products",
"storage_type": "hash",
},
"fields": [
{"name": "product_id", "type": "tag"},
{"name": "category", "type": "tag"},
{"name": "brief_description", "type": "text"},
{"name": "full_description", "type": "text"},
{"name": "price", "type": "numeric"},
{"name": "rating", "type": "numeric"},
{
"name": "text_embedding",
"type": "vector",
"attrs": {"dims": 3, "distance_metric": "cosine", "algorithm": "flat", "datatype": "float32"}
},
{
"name": "image_embedding",
"type": "vector",
"attrs": {"dims": 2, "distance_metric": "cosine", "algorithm": "flat", "datatype": "float32"}
}
],
}
创建索引并加载数据:
python
from redisvl.index import SearchIndex
index = SearchIndex.from_dict(schema, redis_url="redis://localhost:6379")
index.create(overwrite=True)
keys = index.load(data)
print(f"已加载 {len(keys)} 个产品")
1️⃣ TextQuery:全文搜索
TextQuery 是面向关键词的搜索工具,支持多种相关性评分算法(BM25、TF‑IDF),并可结合过滤器、多字段权重及停用词优化。
基本原理
全文搜索的核心是倒排索引。Redis 将文本字段分词后构建索引,查询时根据词项匹配情况计算文档与查询的相关性分数。评分算法直接影响排序效果:
- BM25(BM25STD):一种基于概率检索模型的成熟算法,考虑词频、文档长度等因素,通常比 TF‑IDF 更精准。
- TF‑IDF:经典算法,计算简单,适合快速原型。
基本用法
python
from redisvl.query import TextQuery
text_query = TextQuery(
text="running shoes",
text_field_name="brief_description",
return_fields=["product_id", "brief_description", "category", "price"],
num_results=5
)
results = index.query(text_query)
result_print(results)
输出显示匹配到的商品,并按相关性分数降序排列。
评分算法对比
您可以显式指定 text_scorer 参数:
python
# BM25 标准评分(默认)
bm25_query = TextQuery(..., text_scorer="BM25STD")
# TF‑IDF 评分
tfidf_query = TextQuery(..., text_scorer="TFIDF")
💡 建议:对于一般应用,BM25 通常表现更佳;若需快速实现或简单场景,TF‑IDF 也可胜任。
结合过滤器
使用 filter_expression 可以缩小搜索范围,例如只搜索某类别或价格区间的商品:
python
from redisvl.query.filter import Tag, Num
# 只查找 footwear 类别中的 "shoes"
filtered = TextQuery(
text="shoes",
text_field_name="brief_description",
filter_expression=Tag("category") == "footwear",
...
)
# 价格小于 100
price_filtered = TextQuery(
text="comfortable",
filter_expression=Num("price") < 100,
...
)
多字段加权搜索
有时不同字段的重要性不同,例如 brief_description 比 full_description 更能代表商品核心信息。您可以给每个字段分配权重:
python
weighted_query = TextQuery(
text="shoes",
text_field_name={"brief_description": 1.0, "full_description": 0.5},
...
)
这样,命中 brief_description 的文档会比仅命中 full_description 的获得更高分数。
停用词(Stopwords)详解
停用词是指那些出现频率极高但对语义贡献很小的词(如 "the", "for")。Redis 允许在查询级别 和索引级别配置停用词,两者作用机制不同:
| 配置层级 | 作用时机 | 影响范围 |
|---|---|---|
查询级 (TextQuery.stopwords) |
查询时,客户端过滤查询词 | 仅影响当前查询 |
索引级 (Index.stopwords) |
索引创建时,服务器决定哪些词被收录 | 影响整个索引,所有查询 |
查询级停用词示例
python
# 使用英语默认停用词(过滤 "the", "for" 等)
query_english = TextQuery(text="the best shoes for running", stopwords="english", ...)
# 自定义停用词列表(只过滤 "for", "with")
query_custom = TextQuery(text="professional equipment for athletes", stopwords=["for", "with"], ...)
# 完全不禁用停用词(保留所有词)
query_none = TextQuery(text="the best shoes for running", stopwords=None, ...)
索引级停用词
在创建索引时,可通过 index.stopwords 字段控制哪些词不被索引。默认 Redis 会使用内置停用词列表。若要禁用所有停用词(即索引所有词),可设置为空列表 [](即 STOPWORDS 0)。这在搜索专有名词(如 "Bank of America")时非常有用,因为 "of" 不会被过滤掉。
python
stopwords_schema = {
"index": {
"name": "company_index",
"stopwords": [] # 禁用所有停用词
},
"fields": [...]
}
⚠️ 注意:索引级停用词在索引创建时生效,且修改后需重建索引。查询级停用词则更灵活,可按需调整。
2️⃣ HybridQuery:混合搜索
混合搜索将全文检索 与向量语义检索 相结合,既利用关键词精准匹配,又借助向量捕获深层语义,显著提升检索质量。Redis 从 8.4.0 开始原生支持 FT.HYBRID 命令,RedisVL 提供了 HybridQuery 类(新)和 AggregateHybridQuery(旧)两种实现。
版本说明
- HybridQuery:需要 Redis >= 8.4.0 且 redis-py >= 7.1.0,支持更丰富的功能(如 RRF、运行时参数)。
- AggregateHybridQuery :兼容旧版 Redis,基于
FT.AGGREGATE实现,功能略少(不支持 RRF,且不支持运行时参数)。
以下示例默认使用 HybridQuery,若环境不满足则会降级使用 AggregateHybridQuery。
混合搜索的工作原理
混合搜索并行执行文本查询和向量查询,分别得到两个分数(文本相关度和向量相似度),然后通过组合方法将二者融合为一个最终得分。下图展示了这一流程:
#mermaid-svg-JOCFE4bgpkSgEpjL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JOCFE4bgpkSgEpjL .error-icon{fill:#552222;}#mermaid-svg-JOCFE4bgpkSgEpjL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JOCFE4bgpkSgEpjL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JOCFE4bgpkSgEpjL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JOCFE4bgpkSgEpjL .marker.cross{stroke:#333333;}#mermaid-svg-JOCFE4bgpkSgEpjL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JOCFE4bgpkSgEpjL p{margin:0;}#mermaid-svg-JOCFE4bgpkSgEpjL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster-label text{fill:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster-label span{color:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster-label span p{background-color:transparent;}#mermaid-svg-JOCFE4bgpkSgEpjL .label text,#mermaid-svg-JOCFE4bgpkSgEpjL span{fill:#333;color:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL .node rect,#mermaid-svg-JOCFE4bgpkSgEpjL .node circle,#mermaid-svg-JOCFE4bgpkSgEpjL .node ellipse,#mermaid-svg-JOCFE4bgpkSgEpjL .node polygon,#mermaid-svg-JOCFE4bgpkSgEpjL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JOCFE4bgpkSgEpjL .rough-node .label text,#mermaid-svg-JOCFE4bgpkSgEpjL .node .label text,#mermaid-svg-JOCFE4bgpkSgEpjL .image-shape .label,#mermaid-svg-JOCFE4bgpkSgEpjL .icon-shape .label{text-anchor:middle;}#mermaid-svg-JOCFE4bgpkSgEpjL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JOCFE4bgpkSgEpjL .rough-node .label,#mermaid-svg-JOCFE4bgpkSgEpjL .node .label,#mermaid-svg-JOCFE4bgpkSgEpjL .image-shape .label,#mermaid-svg-JOCFE4bgpkSgEpjL .icon-shape .label{text-align:center;}#mermaid-svg-JOCFE4bgpkSgEpjL .node.clickable{cursor:pointer;}#mermaid-svg-JOCFE4bgpkSgEpjL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JOCFE4bgpkSgEpjL .arrowheadPath{fill:#333333;}#mermaid-svg-JOCFE4bgpkSgEpjL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JOCFE4bgpkSgEpjL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JOCFE4bgpkSgEpjL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JOCFE4bgpkSgEpjL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JOCFE4bgpkSgEpjL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JOCFE4bgpkSgEpjL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster text{fill:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL .cluster span{color:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JOCFE4bgpkSgEpjL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JOCFE4bgpkSgEpjL rect.text{fill:none;stroke-width:0;}#mermaid-svg-JOCFE4bgpkSgEpjL .icon-shape,#mermaid-svg-JOCFE4bgpkSgEpjL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JOCFE4bgpkSgEpjL .icon-shape p,#mermaid-svg-JOCFE4bgpkSgEpjL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JOCFE4bgpkSgEpjL .icon-shape .label rect,#mermaid-svg-JOCFE4bgpkSgEpjL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JOCFE4bgpkSgEpjL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JOCFE4bgpkSgEpjL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JOCFE4bgpkSgEpjL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 文本分数
向量相似度
最终得分
用户查询
文本检索
向量检索
得分融合
排序结果
组合方法
RedisVL 支持两种融合策略:
- 线性组合(LINEAR) :
final_score = α * text_score + (1 - α) * vector_score,其中α控制文本与向量的权重。默认α = 0.3(即向量占 70%)。 - 倒数排名融合(RRF) :不直接使用分数,而是基于各自排名进行融合,公式为
RRF = Σ 1/(k + rank)。这种方法对排名靠前的文档给予更高权重,能有效缓解分数尺度不一致的问题。
基本用法
python
from redisvl.query import HybridQuery
hybrid_query = HybridQuery(
text="running shoes",
text_field_name="brief_description",
vector=[0.1, 0.2, 0.1], # 查询向量
vector_field_name="text_embedding",
return_fields=["product_id", "brief_description", "category", "price"],
num_results=5,
yield_text_score_as="text_score",
yield_vsim_score_as="vector_similarity",
combination_method="LINEAR",
yield_combined_score_as="hybrid_score",
)
results = index.query(hybrid_query)
输出中会包含文本分数、向量相似度以及融合后的混合分数。
调整 alpha 参数
通过调整 linear_alpha(HybridQuery)或 alpha(AggregateHybridQuery)可以控制文本和向量的权重:
alpha=1.0:纯文本搜索alpha=0.0:纯向量搜索alpha=0.1:文本占 10%,向量占 90%(向量优先)
python
# 向量优先查询
vector_heavy = HybridQuery(..., linear_alpha=0.1, combination_method="LINEAR")
🔄 注意 :
AggregateHybridQuery中的alpha含义相反------它表示向量权重,所以alpha=0.9表示向量占 90%,文本占 10%。
使用 RRF(仅 HybridQuery)
python
rrf_query = HybridQuery(
...,
combination_method="RRF",
rrf_window=60, # 可选,默认 60
rrf_constant=1, # 可选,默认 1
)
混合搜索 + 过滤器
与 TextQuery 类似,您也可以添加过滤条件:
python
filtered_hybrid = HybridQuery(
...,
filter_expression=Num("price") > 100,
)
运行时参数(仅 HybridQuery)
对于 HNSW 索引,可以通过 ef_runtime 参数在查询时动态调整搜索范围,以平衡精度与速度。HybridQuery 支持此参数,而 AggregateHybridQuery 不支持(因为它使用 FT.AGGREGATE)。
python
hybrid_with_runtime = HybridQuery(
...,
ef_runtime=200, # 针对 HNSW 索引
)
3️⃣ MultiVectorQuery:多向量搜索
当您的数据包含多种模态的向量(如文本向量、图像向量、音频向量)时,MultiVectorQuery 允许您同时对这些向量字段进行检索,并按权重综合排序。
原理
每个查询向量都带有一个权重,最终得分为所有向量相似度的加权和:
combined_score = w1 * sim1 + w2 * sim2 + ... + wn * simn
其中 wi 为第 i 个向量的权重,simi 为其与查询向量的相似度(余弦距离转换为相似度,1 - 距离)。
基本用法
python
from redisvl.query import MultiVectorQuery, Vector
# 定义每个向量查询
text_vector = Vector(
vector=[0.1, 0.2, 0.1],
field_name="text_embedding",
dtype="float32",
weight=0.7
)
image_vector = Vector(
vector=[0.8, 0.1],
field_name="image_embedding",
dtype="float32",
weight=0.3
)
multi_query = MultiVectorQuery(
vectors=[text_vector, image_vector],
return_fields=["product_id", "brief_description"],
num_results=5
)
results = index.query(multi_query)
结果中会显示每个向量的单独得分和组合得分。
调整权重
您可以通过修改 weight 来突出某个模态的重要性,例如更侧重图像相似性:
python
text_vec.weight = 0.2
image_vec.weight = 0.8
结合过滤器
同样支持过滤:
python
filtered_multi = MultiVectorQuery(
...,
filter_expression=Tag("category") == "footwear",
)
📊 三种查询类型对比
为了让您更直观地选择合适的方法,下表对比了各自特点:
| 查询类型 | 核心能力 | 适用场景 | 关键参数 |
|---|---|---|---|
| TextQuery | 纯关键词全文搜索 | 精准匹配、传统搜索引擎 | 文本评分器、多字段权重、停用词 |
| HybridQuery | 文本 + 向量融合 | 兼顾精确与语义,适用于大多数搜索场景 | 组合方法(LINEAR/RRF)、alpha、运行时参数 |
| MultiVectorQuery | 多模态向量联合检索 | 多模态搜索(图文、音视频等) | 向量权重、多向量组合 |
下图为决策流程图,帮助您快速定位:
#mermaid-svg-begzwnvD5XaI7vWh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-begzwnvD5XaI7vWh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-begzwnvD5XaI7vWh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-begzwnvD5XaI7vWh .error-icon{fill:#552222;}#mermaid-svg-begzwnvD5XaI7vWh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-begzwnvD5XaI7vWh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-begzwnvD5XaI7vWh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-begzwnvD5XaI7vWh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-begzwnvD5XaI7vWh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-begzwnvD5XaI7vWh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-begzwnvD5XaI7vWh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-begzwnvD5XaI7vWh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-begzwnvD5XaI7vWh .marker.cross{stroke:#333333;}#mermaid-svg-begzwnvD5XaI7vWh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-begzwnvD5XaI7vWh p{margin:0;}#mermaid-svg-begzwnvD5XaI7vWh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-begzwnvD5XaI7vWh .cluster-label text{fill:#333;}#mermaid-svg-begzwnvD5XaI7vWh .cluster-label span{color:#333;}#mermaid-svg-begzwnvD5XaI7vWh .cluster-label span p{background-color:transparent;}#mermaid-svg-begzwnvD5XaI7vWh .label text,#mermaid-svg-begzwnvD5XaI7vWh span{fill:#333;color:#333;}#mermaid-svg-begzwnvD5XaI7vWh .node rect,#mermaid-svg-begzwnvD5XaI7vWh .node circle,#mermaid-svg-begzwnvD5XaI7vWh .node ellipse,#mermaid-svg-begzwnvD5XaI7vWh .node polygon,#mermaid-svg-begzwnvD5XaI7vWh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-begzwnvD5XaI7vWh .rough-node .label text,#mermaid-svg-begzwnvD5XaI7vWh .node .label text,#mermaid-svg-begzwnvD5XaI7vWh .image-shape .label,#mermaid-svg-begzwnvD5XaI7vWh .icon-shape .label{text-anchor:middle;}#mermaid-svg-begzwnvD5XaI7vWh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-begzwnvD5XaI7vWh .rough-node .label,#mermaid-svg-begzwnvD5XaI7vWh .node .label,#mermaid-svg-begzwnvD5XaI7vWh .image-shape .label,#mermaid-svg-begzwnvD5XaI7vWh .icon-shape .label{text-align:center;}#mermaid-svg-begzwnvD5XaI7vWh .node.clickable{cursor:pointer;}#mermaid-svg-begzwnvD5XaI7vWh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-begzwnvD5XaI7vWh .arrowheadPath{fill:#333333;}#mermaid-svg-begzwnvD5XaI7vWh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-begzwnvD5XaI7vWh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-begzwnvD5XaI7vWh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-begzwnvD5XaI7vWh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-begzwnvD5XaI7vWh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-begzwnvD5XaI7vWh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-begzwnvD5XaI7vWh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-begzwnvD5XaI7vWh .cluster text{fill:#333;}#mermaid-svg-begzwnvD5XaI7vWh .cluster span{color:#333;}#mermaid-svg-begzwnvD5XaI7vWh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-begzwnvD5XaI7vWh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-begzwnvD5XaI7vWh rect.text{fill:none;stroke-width:0;}#mermaid-svg-begzwnvD5XaI7vWh .icon-shape,#mermaid-svg-begzwnvD5XaI7vWh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-begzwnvD5XaI7vWh .icon-shape p,#mermaid-svg-begzwnvD5XaI7vWh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-begzwnvD5XaI7vWh .icon-shape .label rect,#mermaid-svg-begzwnvD5XaI7vWh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-begzwnvD5XaI7vWh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-begzwnvD5XaI7vWh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-begzwnvD5XaI7vWh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
是
否
否
是
否
开始
需要关键词匹配?
是否需要语义理解?
TextQuery
是否有多个向量字段?
MultiVectorQuery
HybridQuery
是否有多个向量字段?
纯向量搜索(VectorQuery,不在本指南)
🧠 最佳实践
- TextQuery 适用场景:当查询词明确、需要精确匹配时(如产品型号、专有名词)。若数据量不大且实时性要求高,文本搜索性能优越。
- HybridQuery 推荐:对于电商、内容推荐等混合场景,混合搜索能同时捕获用户意图(向量)和关键词(文本),效果更好。建议先用默认 alpha(0.3)测试,再根据业务调整。
- MultiVectorQuery 多模态利器:如果您的数据有图像、音频等多种向量,多向量查询可以让您统一打分排序,避免分别检索再合并的繁琐。
- 停用词策略:如果您的数据包含常见的停用词且这些词具有业务含义(如公司名称中的 "of"),请在索引级别禁用停用词;如果只是查询时想忽略某些词,使用查询级停用词更灵活。
- 版本兼容 :生产环境务必检查 Redis 和 redis-py 版本,以决定使用
HybridQuery还是AggregateHybridQuery。建议升级到 Redis 8.4+ 以享受完整功能。
🧹 清理资源
示例结束后,可以删除测试索引以释放资源:
python
index.delete(drop=True)