- 后端
【免费下载链接】soulmate
Unmaintained, use Soulheart!
Soulmate 是一个基于 Redis 的自动补全(autocomplete)服务,它利用 Redis 的 sorted sets 建立"部分单词前缀索引",并内置一个轻量 Sinatra 查询接口,帮你 10 分钟搭建出高性能的搜索提示功能。本文将从安装、数据加载到发起第一次查询,带你完整走通整个流程。
⚠️ 温馨提示:Soulmate 已停止维护,作者推荐了仍在积极开发的替代项目 Soulheart。本文内容适合学习原理或在存量系统中维护使用。
Soulmate 自动补全服务能做什么?
传统自动补全通常依赖数据库的LIKE 'xxx%'查询,数据量大时响应缓慢。Soulmate 的核心思路是把索引提前算好放进 Redis,让查询变成毫秒级的集合运算:
- 🎯多类型统一查询:一次请求可同时补全多种类型的数据(例如 SeatGeek 用它同时补全艺人、演出、场馆)
- 🏆按自定义分数排序:结果由你指定的
score字段决定排名 - 📦携带任意元数据:每个条目可附带 URL、副标题等展示信息
- 🚀极快响应:查询基于 Redis 集合交集,天然支持高并发
数据条目就是一个简单的 JSON 对象:
{ "id": 3, "term": "Citi Field", "score": 81, "data": { "url": "/citi-field-tickets/", "subtitle": "Flushing, NY" } }| 字段 | 说明 |
|---|---|
id | 同类型内唯一的标识符 |
term | 用于补全的短语 |
score | 自定义排序分数(分数相同时按字典序排列) |
aliases | 可选,别名词组数组,同样会被加入索引 |
data | 可选,命中后原样返回的元数据 |
工作原理:Redis 前缀索引是如何建立的
理解原理只需看两个核心类:
- 加载阶段(loader.rb):把每个
term拆词,为每个词生成从短到长的全部前缀(如Dodger Stadium会生成d、do、dod…),写入soulmate-index:{type}下的 sorted set,分数即score,成员是条目id。原始 JSON 则集中存放在 hash 中,节省内存。 - 查询阶段(matcher.rb):把输入词的每个前缀对应的 sorted set 做交集运算(
ZINTERSTORE),结果天然按分数降序排列;交集结果还会缓存 10 分钟,重复查询直接命中缓存。
也就是说,"输入 stad 匹配 Stadium" 在 Redis 里只是一次集合交集操作。
一键安装步骤:准备工作环境
Soulmate 依赖 Ruby 和 Redis,安装非常简单:
# 1. 先确认 Redis 正在本地运行(默认 6379 端口) # 2. 安装 gem(会带上 sinatra、redis 等依赖) gem install soulmate也可以从源码安装:
git clone https://gitcode.com/gh_mirrors/so/soulmate cd soulmate && gem build soulmate.gemspec && gem install ./soulmate-*.gem快速加载数据:导入第一个场馆数据集
仓库自带了示例数据 venues.json(每行一个 JSON 对象),包含 Dodger Stadium、Angel Stadium 等经典球场,甚至还有一条中文条目:
{"id":1,"term":"Dodger Stadium","score":84,"data":{"url":"/dodger-stadium-tickets/","subtitle":"Los Angeles, CA"},"aliases":["Chavez Ravine"]}注意aliases里的 "Chavez Ravine" 同样会进入索引——输入chavez也能补全出 Dodger Stadium,非常适合做别名、昵称检索。
用soulmate load命令把数据灌入 Redis:
$ soulmate load venue --redis=redis://localhost:6379/0 < venues.json参数说明:
venue:数据类型名(type),后续查询会用到--redis:Redis 连接串,省略时默认连接本地redis://127.0.0.1:6379/0(也可通过环境变量REDIS_URL指定,见 config.rb)
⚠️load是全量重建:它会先清空该 type 的全部索引再重新写入(见 loader.rb),期间该类型的缓存查询可能短暂返回空结果,缓存过期后即恢复正常。
启动查询服务:soulmate-web 与 /search 接口
数据加载完成后,启动查询服务:
$ soulmate-web --foreground --no-launch --redis=redis://localhost:6379/0服务默认监听5678 端口,核心是/search接口(实现见 server.rb)。在浏览器访问:
http://localhost:5678/search?types[]=venue&term=stad你会得到按分数排序的结果:
{ "term": "stad", "results": { "venue": [ { "id": 28, "term": "Angel Stadium", "score": 90, "data": { "url": "/angel-stadium-tickets/", "subtitle": "Anaheim, CA" } }, { "id": 1, "term": "Dodger Stadium", "score": 84, "data": { "url": "/dodger-stadium-tickets/", "subtitle": "Los Angeles, CA" } }, { "id": 29, "term": "Sun Life Stadium", "score": 75, "data": { "url": "/sun-life-stadium-tickets/", "subtitle": "Miami, FL" } } ] } }查询参数速查表
| 参数 | 必填 | 说明 |
|---|---|---|
term | ✅ | 用户输入的补全词 |
types[] | ✅ | 类型列表,可传多个,如types[]=event&types[]=venue |
limit | ❌ | 每种类型返回条数,默认 5 |
callback | ❌ | 传入后返回 JSONP,方便前端跨域 |
多类型查询示例:
http://localhost:5678/search?types[]=event&types[]=venue&limit=3&term=yank访问根路径http://localhost:5678/可查看服务版本与健康状态。
进阶配置:自定义停用词与最短补全长度
两个关键配置项都在 config.rb 中定义:
Soulmate.min_complete(默认2):用户至少输入几个字符才返回补全,避免单字符的海量结果Soulmate.stop_words(默认["vs", "at", "the"]):查询时直接忽略的无意义词,可用仓库自带的 stop-words.txt 做参考扩充
在 Rails 应用中还可直接指定 Redis 实例:
# config/initializers/soulmate.rb Soulmate.redis = 'redis://127.0.0.1:6379/0' # 或直接复用已有的连接对象 # Soulmate.redis = $redis如何把 Soulmate 挂载进 Rails 应用
如果不想单独跑一个soulmate-web进程,可以把 Sinatra 应用直接挂进 Rails:
- Gemfile 中添加:
gem 'rack-contrib' gem 'soulmate', :require => 'soulmate/server'routes.rb中挂载(见 server.rb):
mount Soulmate::Server, :at => "/sm"之后即可通过http://localhost:3000/sm/search?types[]=venues&limit=6&term=kitten发起补全请求,无需再启动独立服务。
常见问题与使用技巧
Q:查询结果有缓存吗?有。每次交集结果会缓存 10 分钟(见 matcher.rb),高频词几乎零开销;数据更新后最多 10 分钟生效。
Q:为什么输入的词没被匹配到?查询时会做归一化:转小写、剔除特殊字符(见 helpers.rb),并跳过长度小于min_complete的词和停用词。多词输入按"每个词都要命中"的交集逻辑处理。
Q:中文能补全吗?可以。示例数据里就有"中国佛山 李小龙"这样的中文条目,normalize的正则保留了中日韩字符,可按正常流程使用。
Q:如何更新单条数据?Loader#add会自动删除同id的旧条目再写入(见 loader.rb);remove只需传入id即可清理索引。
写在最后
从gem install soulmate到拿到第一个补全结果,整个过程不到 10 分钟。Soulmate 虽然已停止维护(官方推荐使用 Soulheart),但它用 Redis sorted sets 构建前缀索引的设计思路非常经典,源码只有 lib/soulmate/ 下几个小文件,是学习自动补全服务架构的优质素材。现在就可以动手,搭一个属于自己的 Redis 自动补全服务吧!
- 后端
【免费下载链接】soulmate
Unmaintained, use Soulheart!
相关推荐
10分钟快速上手Guide-RPC-Framework:搭建你的第一个RPC服务
10分钟快速上手Guide RPC Framework:搭建你的第一个RPC服务 想要快速掌握分布式系统核心技术RPC吗?Guide RPC Framework
如何快速上手Covenant:10分钟搭建你的第一个C2服务器
如何快速上手Covenant:10分钟搭建你的第一个C2服务器 Covenant是一个功能强大的.NET命令与控制 C2 框架,专为红队测试人员设计。这个开源项
网络安全应用安全如何快速上手Quinn:10分钟搭建你的第一个QUIC服务器
如何快速上手Quinn:10分钟搭建你的第一个QUIC服务器 想要体验下一代网络传输协议QUIC的强大性能吗?Quinn作为Rust语言实现的异步友好QUIC实
网络通信
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考