编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

RedisVL: 将Redis作为矢量数据库(redis将数据存储在哪里)

wxchong 2024-09-19 05:52:41 开源技术 10 ℃ 0 评论

00、背景

晚上看到一个好的项目,目前才63个stars,但非常有潜质。

项目地址:https://github.com/RedisVentures/redisvl

简单来说,RedisVL 提供了一个强大的 Python 客户端库,用于将 Redis 用作矢量数据库。

它充分利用了 Redis 的速度和可靠性以及基于向量的语义搜索功能来增强我们的应用程序。

注意:该库仍在开发中, API 可能随时发生更改。

可以参考之前的文章:《向量数据库》学习笔记


01、什么是 RedisVL?

近年来,矢量数据库因其高效存储和检索矢量的能力而变得越来越流行。

然而,大多数矢量数据库使用起来很复杂,需要花费大量的时间和精力来建立。

RedisVL 旨在通过提供一个简单直观的界面来使用 Redis 作为向量数据库来解决这个问题。

RedisVL 提供了一个客户端库,使您能够利用 Redis 作为矢量数据库的强大功能和灵活性。

该库简化了在 Redis 中存储、检索以及对向量执行复杂语义和混合搜索的过程。

它还提供了强大的索引管理系统,使您可以轻松创建、更新和删除索引。

02、主要功能

RedisVL 具有许多强大的功能,旨在简化矢量数据库操作。

  1. 索引管理:RedisVL 允许轻松创建、更新和删除索引。每个索引的模式可以在 yaml 中定义,也可以直接在 python 代码中定义,并在索引的整个生命周期中使用。
  2. 嵌入创建:RedisVL 与 OpenAI、HuggingFace 和 GCP VertexAI 集成,以简化矢量化非结构化数据的过程。图像支持即将推出。提交新矢量化器的 PR。
  3. 向量搜索:RedisVL 提供强大的搜索功能,使您能够同步和异步查询向量。还支持利用标签、地理、数字和其他过滤器(如全文搜索)的混合查询。
  4. 强大的抽象

语义缓存: LLMCache 是直接内置于RedisVL中的语义缓存接口。它允许缓存 GPT-3 等 LLM 生成的输出。由于语义搜索用于检查缓存,因此可以设置阈值来确定缓存结果是否足够相关以返回。如果没有,则调用模型并缓存结果以供将来使用。这可以提高 QPS 并降低在生产中使用 LLM 模型的成本。

03、快速开始

使用 pip 安装 redisvl

pip install redisvl

在 Docker 中使用 Redis Stack 本地访问 Redis:

docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest

访问 http://localhost:8001 。

04、示例

索引管理

索引可以通过 yaml 规范定义,直接对应于 redis-py 中的 RediSearch 字段名称和参数

index:
  name: user_index
  prefix: users

fields:
  # 定义标记字段
  tag:
  - name: user
  - name: job
  - name: credit_store
  # 定义数字字段
  numeric:
  - name: age
  # 定义矢量字段
  vector:
  - name: user_embedding
    dim: 3
    algorithm: hnsw
    distance_metric: cosine

借助该架构,RedisVL 库可用于创建、加载向量并执行向量搜索。

import numpy as np
from jupyterutils import table_print

data = [
    {'user': 'john', 'age': 1, 'job': 'engineer', 'credit_score': 'high'},
    {'user': 'mary', 'age': 2, 'job': 'doctor', 'credit_score': 'low'},
    {'user': 'joe', 'age': 3, 'job': 'dentist', 'credit_score': 'medium'}
]

# 转换为redis的bytes
vectors = [
    np.array([0.1, 0.1, 0.5], dtype=np.float32).tobytes(),
    np.array([0.1, 0.1, 0.5], dtype=np.float32).tobytes(),
    np.array([0.9, 0.9, 0.1], dtype=np.float32).tobytes(),
]

for record, vector in zip(data, vectors):
    record["user_embedding"] = vector

这对应于一个看起来像这样的数据集

useragejobcredit_scoreuser_embeddingjohn1engineerhigh\x3f\x8c\xcc\x3f\x8c\xcc?@mary2doctorlow\x3f\x8c\xcc\x3f\x8c\xcc?@joe3dentistmedium\x3f\xab\xcc?\xab\xcc?@

from redisvl.index import SearchIndex
from redisvl.query import VectorQuery

# 初始化索引并连接到Redis
index = SearchIndex.from_dict(schema)
index.connect("redis://localhost:6379")

# 在Redis中创建索引
index.create(overwrite=True)

# 将数据加载到Redis中的索引中
index.load(data)

query = VectorQuery(
    vector=[0.1, 0.1, 0.5],
    vector_field_name="user_embedding",
    return_fields=["user", "age", "job", "credit_score"],
    num_results=3,
)
results = index.query(query)

复杂查询

RedisVL 支持多种过滤器类型,包括标签、数字、地理和全文搜索来创建过滤器表达式。

过滤表达式可用于创建混合查询,允许你将多种查询类型(即文本和矢量搜索)组合到单个查询中。

from redisvl.index import SearchIndex
from redisvl.query import VectorQuery
from redisvl.query.filter import Tag, Num, Geo, GeoRadius, Text

# 完全匹配标记
is_sam = Tag("user") == "Sam"

# 数值范围
is_over_10 = Num("age") > 10

# 地理半径
works_in_sf = Geo("location") == GeoRadius(37.7749, -122.4194, 10)

# 模糊匹配的全文搜索
is_engineer = Text("job") % "enginee*"

filter_expression = is_sam & is_over_10 & works_in_sf & is_engineer

query = VectorQuery(
    vector=[0.1, 0.1, 0.5],
    vector_field_name="user_embedding",
    return_fields=["user", "age", "job", "credit_score"],
    num_results=3,
    filter_expression=filter_expression,
)
results = index.query(query)

语义缓存

RedisVL 提供 LLMCache 接口,将具有向量搜索功能的 Redis 转变为语义缓存来存储查询结果,从而减少发送到大型语言模型 (LLM) 服务的请求和令牌数量,这可以通过减少生成响应所需的时间来降低费用并提高性能。

from redisvl.llmcache.semantic import SemanticCache

cache = SemanticCache(
  redis_url="redis://localhost:6379",
  threshold=0.9, # 语义相似度阈值
)

# 检查缓存是否有给定查询的结果
cache.check("What is the capital of France?")
[ ]

# 存储给定查询的结果
cache.store("What is the capital of France?", "Paris")

# Cache will now have the query缓存现在将具有查询
cache.check("What is the capital of France?")
["Paris"]

# 如果查询足够相似,缓存仍将返回结果
cache.check("What really is the capital of France?")
["Paris"]

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表