介绍
LanceDB 是一个开源的高性能向量数据库,专为 AI 应用设计,专注于提供高效的向量相似性搜索能力。它基于 Lance 数据格式构建,结合了列存数据库的优势和向量搜索的特性,适用于处理大规模嵌入向量数据。
适用场景
- 语义搜索:根据文本含义而非关键词进行搜索
- 推荐系统:查找相似物品或内容进行推荐
- 计算机视觉:图像检索、特征匹配、目标识别
- 自然语言处理:文本聚类、相似句子查找、问答系统
- 异常检测:识别与正常模式差异较大的向量
- 多模态应用:跨文本、图像、音频的相似性搜索
特点
高性能向量搜索
- 支持多种距离度量(欧氏距离、余弦相似度、曼哈顿距离等)
- 实现了近似最近邻(ANN)搜索算法,平衡搜索速度和精度
- 针对大规模数据集优化,可处理数十亿级向量
灵活的数据模型
- 支持混合类型数据存储(向量+结构化数据)
- 基于表结构组织数据,支持类 SQL 的查询语法
- 允许添加、删除和更新数据,支持事务操作
高效存储与索引
- 基于 Lance 格式的列存存储,提供高效压缩
- 支持多种索引类型(IVF、PQ 等)加速查询
- 增量构建索引,无需重新处理整个数据集
多语言支持
- 原生支持 Python、Rust 接口
- 通过 HTTP 接口支持跨语言访问
- 可轻松集成到各类 AI 应用栈中
与生态系统集成
- 无缝对接 Pandas、PyArrow 等数据处理库
- 支持与 LangChain、LLamaIndex 等 LLM 框架集成
- 可与 TensorFlow、PyTorch 等深度学习框架协作
架构设计
LanceDB 采用客户端-服务器架构,主要包含以下组件:
- 存储层:基于 Lance 格式,提供高效的列存存储和版本控制
- 索引层:管理向量索引,优化相似性搜索性能
- 查询层:处理用户查询,支持过滤、排序和聚合操作
- API 层:提供多语言接口,方便应用集成
典型使用流程
- 数据准备:将非结构化数据(文本、图像等)转换为向量表示
- 创建数据库:初始化 LanceDB 实例,指定存储路径
- 创建表:定义表结构,包含向量列和其他属性列
- 插入数据:将向量及关联数据插入表中
- 创建索引:为向量列创建索引以加速查询
- 执行查询:进行相似性搜索,可结合过滤条件
例子
导入依赖
import lancedb
import pandas as pd
import numpy as np
from lancedb.pydantic import LanceModel, Vector
连接数据库
db = lancedb.connect("vector_db")
建表
# 1. 使用 Pydantic 模型定义表结构
class Document(LanceModel):
id: int
text: str
embedding: Vector(768) # 768维向量
category: str
timestamp: int
# 2. 创建表(如果存在,就删除表)
table_name = "docs"
if table_name in db.table_names():
db.drop_table(table_name)
table = db.create_table(table_name, schema=Document)
添加数据
import lancedb
import numpy as np
import pandas as pd
db = lancedb.connect("vector_db")
table_name = "docs"
table = db.open_table(table_name)
# 生成示例数据(模拟从文本生成的嵌入向量)
num_samples = 1000
data = {
"id": range(num_samples),
"text": [f"这是第 {i} 个示例文档" for i in range(num_samples)],
"embedding": [np.random.rand(768).astype(np.float32) for _ in range(num_samples)],
"category": [ ["技术", "教育", "娱乐", "新闻"][i % 4] for i in range(num_samples) ],
"timestamp": [1620000000 + i * 3600 for i in range(num_samples)]
}
df = pd.DataFrame(data)
# 插入数据
table.add(df)
查询
db = lancedb.connect("vector_db")
table_name = "docs"
table = db.open_table(table_name)
# 准备查询向量
query_embedding = np.random.rand(768).astype(np.float32)
# a. 基础相似性搜索
results = table.search(query_embedding).limit(5).to_pandas()
print("基础搜索结果:")
print(results[["id", "text", "category", "_distance"]])
# b. 带过滤条件的搜索
results = table.search(query_embedding)\
.where("category = '技术' AND timestamp > 1620003600")\
.limit(5)\
.to_pandas()
print("\n带过滤条件的搜索结果:")
print(results[["id", "text", "category", "timestamp", "_distance"]])
# c. 按距离排序并返回分数
# 使用余弦相似度
results = table.search(query_embedding)\
.metric("cosine")\
.limit(5)\
.to_pandas()
print("\n余弦相似度搜索结果:")
print(results[["id", "text", "_distance"]])