给机器人装上"联想记忆":MoteDB v0.12 混合检索实战(附完整代码)
前几篇我们聊了 MoteDB 的定位和架构(见文末系列链接),这篇讲干货:v0.12 带来的混合检索、Arrow/pandas 互操作、时序查询 680× 加速,全部带可运行代码。全文基于已发布的 v0.12.1,
pip install motedb-python即可复现。
一、先说一个真实场景
巡检机器人在厂区跑一天,落库的数据长这样:
- 30 万条时序读数(温度、振动、电流,每秒 10 点)
- 2 万张异常快照 + 各自的 CLIP embedding(384 维)
- 几千条维修工单文本
- 每个读数带空间坐标
现在工程师想问的问题是:“上次在 3 号车间东北角,振动异常伴随轴承异响的那些时刻,都拍到了什么?”
这个问题同时打到四种数据形态:时间范围 + 空间区域 + 文本关键词 + 向量近邻。传统方案的答案是拼三个系统:
SQLite/时序库(时序) + FAISS/Milvus(向量) + ES(全文) + PostGIS(空间)四个进程、四套持久化、四种查询语言,跨系统的一致性自己扛——机器人断电重启后哪边有数据哪边没有,都是隐患。
MoteDB 的答案是把四种索引长在同一个列存引擎上,共享同一套 MVCC、ACID 和崩溃恢复,单个嵌入式库文件解决。v0.12 补上了最后一块拼图:混合检索——让文本和向量在一条查询里融合排序。
二、v0.12 核心新能力
1. hybrid_search:BM25 × 向量的 RRF 融合检索
行业里做两路检索融合,最头疼的是分数标定——BM25 分数和余弦距离根本不在一个量纲。v0.12 用的是信息检索领域标准的Reciprocal Rank Fusion:只看排名不看分数,rrf(d) = Σ 1/(rrf_k + rank),两路都命中的文档自然浮顶。
importmotedbimportnumpyasnp db=motedb.Database("robot.mote")# 建表:时序 + 向量 + 文本,一个表全装下db.execute(""" CREATE TABLE events ( id INT PRIMARY KEY, ts TIMESTAMP, zone TEXT, emb VECTOR(384), note TEXT """)db.execute("CREATE TEXT INDEX idx_note ON events (note)")db.execute("CREATE VECTOR INDEX idx_emb ON events (emb)")# ── 混合检索:文本"轴承 异响" + 查询向量的近邻,RRF 融合 ──rows=db.hybrid_search("idx_note",# 文本索引"轴承 异响",# 文本查询"idx_emb",# 向量索引query_emb.tolist(),# 384 维查询向量k=10,)forrinrows:print(r["id"],r["note"],r["__rrf__"],r["__bm25__"],r["__distance__"])每行结果带三个透明字段:__rrf__(融合分)、__bm25__(文本相关性)、__distance__(向量距离),排序逻辑完全可解释——这对事后审计"机器人为什么召回这条记录"很重要。
2. Arrow / pandas 互操作: embedding 列不再变形
以前从数据库取向量列,Python 侧拿到的是嵌套 list,转 numpy 要自己 reshape。v0.12 的query_arrow()直接产出规范的pyarrow.Table,VECTOR 列映射为 Arrow 标准的fixed_size_list<float32>[384],pandas 一步到位:
# 列式直出,向量列直接是 2D float32 语义tbl=db.query_arrow("SELECT ts, zone, emb FROM events WHERE ts > ?",params=[t0])df=db.query_pandas("SELECT ts, zone, emb FROM events WHERE ts > ?",params=[t0])embs=tbl.column("emb").combine_chunks()# → fixed_size_list<float32>反向也通:insert_arrays吃 numpy 批量装载,384 维 embedding 二维数组直插,耐久档实测 19.7 万行/秒;INSERT ... SELECT走同一批量管线,实测 160 万行/秒。给机器人做"白天采集、晚上回灌训练集"的管线,这条是主通路。
3. 时序 top-k:1.2s → 1.76ms(680×)
这是 v0.12 最狠的一个修复。ts INT(整数时间列)的 TIMESERIES 表上执行:
SELECT*FROMsensorORDERBYtsDESCLIMIT10v0.11 及之前要 1.2 秒——三个 bug 叠加:解码器只认 TIMESTAMP 编码、段元数据恒为 (0,0) 导致所有段被 zone-map 误剪、未提交行对 top-k 不可见。v0.12 三处根治 + 段级剪枝后只解码 top-k 所在段,1M 行实测1.76ms,比 DuckDB 全扫(2.1ms)还快。
对机器人意味着什么:"最近 10 条异常"这类最高频的查询,从"卡一下"变成 2ms 内。
4. 其余性能与正确性
- DiskANN 尾部延迟:p99 30ms →1.5ms(根因是冷缺页斜坡,madvise 预热解决;同 recall 档位对 FAISS Flat 快 9×)
- scan-UPDATE/DELETE 谓词下推:11.26 万行/秒,同耐久口径反超 SQLite
- 过滤向量检索修复:
WHERE zone='3号车间' ORDER BY emb <-> ? LIMIT 10在高选择性谓词下不再漏结果(迭代加深候选池) - 事务内 FTS 读己之写:事务里插入的文本,
MATCH立即可见
这四个正确性 bug 全部由SQLite 作 oracle 的差分对拍实抓——这套差分测试是常驻回归门禁,当前全量 239 个测试二进制、3957 个用例,clippy 全目标 0 告警。做底层的都懂这几个数字的分量。
三、5 分钟跑通全流程
pipinstallmotedb-python numpyimportmotedb,numpyasnp db=motedb.Database("demo.mote")db.execute("""CREATE TABLE ev ( id INT PRIMARY KEY, ts TIMESTAMP, zone TEXT, emb VECTOR(8), note TEXT)""")db.execute("CREATE TEXT INDEX ev_note ON ev (note)")db.execute("CREATE VECTOR INDEX ev_emb ON ev (emb)")# numpy 批量装载 1000 行n=1000db.insert_arrays("ev",{"id":np.arange(n),"ts":1700000000_000_000+np.arange(n)*1000,# i64 微秒"zone":[f"zone_{i%4}"foriinrange(n)],"emb":np.random.rand(n,8).astype(np.float32),# (N, 8) 直插"note":[f"event{i}"foriinrange(n)],})# 混合检索(位置参数:文本索引, 文本查询, 向量索引, 查询向量, k)rows=db.hybrid_search("ev_note","event 5","ev_emb",np.random.rand(8).astype(np.float32).tolist(),k=5)print(db.query_pandas("SELECT zone, COUNT(*) FROM ev GROUP BY zone"))Rust 侧cargo add motedb,API 同形(Database::hybrid_search)。
四、升级注意(破坏性变更)
MATCH多词默认语义从 OR 改为 AND(对齐 SQLite FTS5):
-- v0.11: 命中含任一词的文档-- v0.12: 命中同时含两词的文档(AND)SELECT*FROMdocsWHEREMATCH(body,'轴承 异响');-- 需要 OR 语义请显式写:SELECT*FROMdocsWHEREMATCH(body,'轴承 OR 异响');五、已知限制(不藏着)
- 事务内未提交 INSERT 对
MATCH快路径暂不可见(扫描/聚合/点查的读己之写已覆盖) - LATEST BY 在 >1M 行大表上性能待优化(0.12.x 计划)
executemany慢 SQLite 2.4-2.7×(Python 过桥开销,用insert_arrays批量 API 可达 19-45 万行/秒)- pre-1.0,SQL 面和多语言 FFI 仍在演进,API 未冻结
系列文章
- 全球首款!MoteDB:面向具身智能的AI原生嵌入式数据库
- 重新定义具身智能数据库,AI原生多模态数据管理的破局者
- 机器人本地"喊饿":具身智能正在撕裂的数据版图
- 让AI拥有持久记忆:moteDB如何解决具身AI的多模态存储难题
链接
- GitHub:https://github.com/motedb/motedb (MIT,欢迎 Star/Issue/PR)
- crates.io:https://crates.io/crates/motedb
- PyPI:https://pypi.org/project/motedb-python/
- 性能档案:https://github.com/motedb/motedb/blob/main/BENCHMARK.md
如果这篇对你有帮助,去 GitHub 点个 Star 就是最大的支持。下一篇计划写**“rosbag → MoteDB:把机器人数据变成可查询的数据库”**,感兴趣的评论区扣 1。