当前位置: 首页 > news >正文

Go-Redis × RediSearch 全流程实践

1. 连接 Redis

ctx := context.Background()rdb := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,Protocol: 2,           // 推荐 RESP2// UnstableResp3: true, // 若要体验 RESP3 + Raw*
})

2. 准备示例数据

user1 := map[string]interface{}{"name":  "Paul John","email": "paul.john@example.com","age":   42,"city":  "London",
}
user2 := map[string]interface{}{"name":  "Eden Zamir","email": "eden.zamir@example.com","age":   29,"city":  "Tel Aviv",
}
user3 := map[string]interface{}{"name":  "Paul Zamir","email": "paul.zamir@example.com","age":   35,"city":  "Tel Aviv",
}

3. 为 JSON 数据建索引

_, err := rdb.FTCreate(ctx, "idx:users",&redis.FTCreateOptions{OnJSON: true,                   // 针对 JSONPrefix: []interface{}{"user:"},// 仅索引 user:* 键},// schema&redis.FieldSchema{              // 全文本字段FieldName: "$.name",As:        "name",FieldType: redis.SearchFieldTypeText,},&redis.FieldSchema{              // TAG 用于精确匹配/聚合FieldName: "$.city",As:        "city",FieldType: redis.SearchFieldTypeTag,},&redis.FieldSchema{              // 数值范围查询FieldName: "$.age",As:        "age",FieldType: redis.SearchFieldTypeNumeric,},
).Result()
if err != nil { panic(err) }

写入 JSON 文档

_, _ = rdb.JSONSet(ctx, "user:1", "$", user1)
_, _ = rdb.JSONSet(ctx, "user:2", "$", user2)
_, _ = rdb.JSONSet(ctx, "user:3", "$", user3)

RediSearch 监听 user: 前缀,写入即自动索引。

4. 查询示例

4.1 复合搜索

res, _ := rdb.FTSearch(ctx,"idx:users","Paul @age:[30 40]",
).Result()fmt.Printf("匹配总数:%d\n", res.Total)

4.2 指定返回字段(RETURN

cities, _ := rdb.FTSearchWithArgs(ctx, "idx:users", "Paul",&redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "$.city", As: "city"},},},
).Result()for _, d := range cities.Docs {fmt.Println(d.Fields["city"])
}
// London / Tel Aviv

4.3 仅计数不取文档

cnt, _ := rdb.FTSearchWithArgs(ctx, "idx:users", "Paul",&redis.FTSearchOptions{CountOnly: true},
).Result()
fmt.Println(cnt.Total) // 输出 2

4.4 聚合:统计每个城市的用户数

agg, _ := rdb.FTAggregateWithArgs(ctx, "idx:users", "*",&redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@city"},Reduce: []redis.FTAggregateReducer{{Reducer: redis.SearchCount, As: "count"},},},},},
).Result()for _, row := range agg.Rows {fmt.Printf("%s - %v\n", row.Fields["city"], row.Fields["count"])
}
// London - 1
// Tel Aviv - 2

5. 切换到 Hash 模式的差异

  1. 建索引
_, err := rdb.FTCreate(ctx, "hash-idx:users",&redis.FTCreateOptions{OnHash: true,Prefix: []interface{}{"huser:"},},&redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText},&redis.FieldSchema{FieldName: "city", FieldType: redis.SearchFieldTypeTag},&redis.FieldSchema{FieldName: "age",  FieldType: redis.SearchFieldTypeNumeric},
).Result()

OnHash:true不需要 As 别名——字段名即 Hash 的 key。

  1. 写入数据
rdb.HSet(ctx, "huser:1", user1)
rdb.HSet(ctx, "huser:2", user2)
rdb.HSet(ctx, "huser:3", user3)
  1. 查询语法相同,但结果字段直接展开:
docs, _ := rdb.FTSearch(ctx,"hash-idx:users","Paul @age:[30 40]",
).Result()
fmt.Println(docs.Docs[0].Fields["city"]) // 直接获取 city

6. 常见坑位

问题解决方案
返回 "dialect version not supported"显式升级 RediSearch ≥ 2.4,或在服务器 FT.CONFIG SET DEFAULT_DIALECT 2
Cannot create index while write traffic is on在生产写高峰创建索引时加 FT.CREATE ... ON JSON ... STOPWORDS 0 或使用 FT.ALTER 增量添加字段
RESP3 报 unsupported使用 Protocol:2,或启用 UnstableResp3 并用 RawResult() 解析
查询结果字段在 $ 键下这是 JSON 模式的设计:所有字段存入 Fields["$"] 字符串里,需要二次解析或用 RETURN $.field

7. 结语

通过 FTCreate → FTSearch → FTAggregate 等指令,Redis 在单节点即可完成近实时全文搜索与 OLAP 式聚合。
配合 go-redis,你可以:

  • 统一接口同时操作 JSON 与 Hash;
  • 利用 RETURN / CountOnly / GROUPBY 精确控制返回量;
  • 轻松在 Go 服务中嵌入“搜索引擎 + KV 存储”二合一的能力。

赶快复制示例代码试一把,让你的业务查询飞起来 🚀

http://www.dtcms.com/a/287466.html

相关文章:

  • Node.js:Stream、模块系统
  • KANO模型分类,以扫地机功能为例子
  • 实验-华为综合
  • 论文略读: RASA: RANK-SHARING LOW-RANK ADAPTATION
  • 《Linux系统配置实战:NTP时间同步与SSH免密登录全流程指南》​​
  • 【洛谷】询问学号、寄包柜、移动零、颜色分类(vector相关算法题p1)
  • LVS(Linux virual server)基础概念详解
  • 网络通信原理:分层协作与协议解析
  • Matplotlib 30分钟精通
  • 免费收听广播
  • C++类和对象(一)基础内容讲解
  • 使用uvx运行和安装Python应用程序
  • GEO营销:AI时代的搜索优化新赛道——从DeepSeek爆火看生成式引擎优化的崛起
  • 边界条件汇总
  • 初等数论Ⅱ
  • Spring监听器
  • (LeetCode 面试经典 150 题) 49. 字母异位词分组 (哈希表)
  • 开疆智能Profinet转ModbusTCP网关连接康耐视InSight相机案例
  • [故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型
  • ICT测试原理之shorts(短路)测试原理
  • 【2025最新】 .NET FrameWork微软离线运行库合集,一键安装版
  • 【数据类型与变量】
  • python爬虫之获取渲染代码
  • SAP的数据转换和处理
  • RabbitMQ01——基础概念、docker配置rabbitmq、内部执行流程、五种消息类型、测试第一种消息类型
  • 西门子 S7-1500 PLC 电源选型指南:系统电源与负载电源的核心区别
  • SPARKLE:深度剖析强化学习如何提升语言模型推理能力
  • 商业秘密的法律属性与保护路径探析
  • Vue的路由模式的区别和原理
  • RTSP推流客户端-ffmpeg和live555对比