ClickHouse 是一款实时 OLAP 数据库,具备完整的 SQL 支持和丰富的功能,帮助用户轻松编写分析查询。
其中,某些函数和数据结构可用于在向量之间执行距离运算,使得 ClickHouse 具备了作为向量数据库的能力。
得益于其高度并行化的查询管道,ClickHouse 在进行向量搜索时,尤其是在对所有行进行线性扫描以进行精确匹配时,能够提供媲美专用向量数据库的处理速度。
此外,ClickHouse 具备出色的压缩能力,通过自定义压缩编解码器,能够存储和查询大规模数据集,甚至是包含多 TB 嵌入数据集的查询也不会受到内存限制。
计算向量间距离的功能作为 SQL 函数的一部分,可以与传统的 SQL 过滤和聚合操作相结合。这种灵活性使得用户能够将向量与元数据或富文本一同存储和查询,适用于多种用例和应用场景。
数据(文档、图像或结构化数据)必须转换为嵌入内容。我们建议使用OpenAI Embeddings API 或使用开Python 库 SentenceTransformers 创建嵌入。
生成嵌入后,您需要将它们存储在 ClickHouse 中。每个嵌入都应存储在单独的行中,并且可以包含用于筛选、聚合或分析的元数据。下面是一个可以存储带有标题的图像的表示例:
CREATE TABLE images
(
`_file` LowCardinality(String),
`caption` String,
`image_embedding` Array(Float32)
)
ENGINE = MergeTree;
假设您想在数据集中搜索狗的图片。你可以使用 distance 函数(如 cosineDistance)来嵌入狗图像并搜索相关图像:
SELECT
_file,
caption,
cosineDistance(
-- An embedding of your "input" dog picture
[0.5736801028251648, 0.2516217529773712, ..., -0.6825592517852783],
image_embedding
) AS score
FROM images
ORDER BY score ASC
LIMIT 10
让我们对此数据执行最近邻搜索。
SELECT
Name,
embedding,
L2Distance(embedding, [0.1, 0.2, 0.3, 0.4, 0.5]) AS score
FROM ann_index_example
ORDER BY score ASC
LIMIT 5
Query id: 9de95e7f-79e1-4d02-81ff-43f7ace14072
┌─Name──┬─embedding────────────────────────────────────────────────┬───────────────score─┐
│ anabd │ [0.109578826,0.17093645,0.1863009,0.4694911,0.56862974] │ 0.1529803320145931 │
│ ewzos │ [0.24622843,0.28853804,0.42360082,0.5199647,0.5086616] │ 0.24282803026289437 │
│ avajo │ [0.24545254,0.36559477,0.26052764,0.31315225,0.53613853] │ 0.24286758135453868 │
│ wyayw │ [0.032240078,0.18597832,0.31064722,0.21862713,0.6575932] │ 0.2502660809473027 │
│ adxir │ [0.1420014,0.11847292,0.41707036,0.41038868,0.71311146] │ 0.2600782018429016 │
└───────┴──────────────────────────────────────────────────────────┴─────────────────────┘
5 rows in set. Elapsed: 0.006 sec. Processed 1.01 thousand rows, 42.42 KB (178.20 thousand rows/s., 7.48 MB/s.)
Peak memory usage: 121.19 KiB.
在LangChain 中使用ClickHouse 向量存储集成流程。
首先,确保安装必要的库 langchain_community 和clickhouse-connect。
pip install -qU langchain_community clickhouse-connect
关键初始化参数:索引参数:embedding: 用于生成向量的嵌入函数。客户端参数:config: 可选的 ClickhouseSettings,用于配置 ClickHouse 客户端。
初始化实例:
from langchain_community.vectorstores import Clickhouse, ClickhouseSettings
from langchain_openai import OpenAIEmbeddings
# 配置 ClickHouse 设置
settings = ClickhouseSettings(table="clickhouse_example")
# 实例化 ClickHouse 向量存储
vector_store = Clickhouse(embedding=OpenAIEmbeddings(), config=settings)
添加文档:
from langchain_core.documents import Document
# 定义文档
document_1 = Document(page_content="foo", metadata={"baz": "bar"})
document_2 = Document(page_content="thud", metadata={"bar": "baz"})
document_3 = Document(page_content="i will be deleted :(")
# 添加文档到向量存储
documents = [document_1, document_2, document_3]
ids = ["1", "2", "3"]
vector_store.add_documents(documents=documents, ids=ids)
删除文档:
# 删除指定 ID 的文档
vector_store.delete(ids=["3"])
向量搜索:
# 进行向量搜索
results = vector_store.similarity_search(query="thud", k=1)
# 输出搜索结果
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
带过滤条件的向量搜索:
# 使用过滤条件进行向量搜索
results = vector_store.similarity_search(query="thud", k=1, filter="metadata.baz='bar'")
# 输出搜索结果
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
带分数的向量搜索:
# 进行带分数的向量搜索
results = vector_store.similarity_search_with_score(query="qux", k=1)
# 输出搜索结果和相似度得分
for doc, score in results:
print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
异步操作:
# 异步添加文档
# await vector_store.aadd_documents(documents=documents, ids=ids)
# 异步删除文档
# await vector_store.adelete(ids=["3"])
# 异步向量搜索
# results = await vector_store.asimilarity_search(query="thud", k=1)
# 异步带分数的向量搜索
results = await vector_store.asimilarity_search_with_score(query="qux", k=1)
# 输出搜索结果和相似度得分
for doc, score in results:
print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
ClickHouse 不仅可以使用简单的向量索引进行搜索,还支持具有多个条件、约束甚至子查询的复杂查询。
参考资料:
https://clickhouse.com/blog/vector-search-clickhouse-p1
https://clickhouse.com/blog/vector-search-clickhouse-p2
https://clickhouse.com/docs/knowledgebase/vector-search
https://python.langchain.com/v0.2/docs/integrations/vectorstores/clickhouse/