RedisVL查询时如何获取正确的原始向量嵌入字节串
问题描述
我在项目中使用RedisVL存储数据,索引的schema.yaml配置如下:
version: '0.1.0' index: name: "event-index" prefix: event fields: - name: "lp" type: "tag" - name: "customer_token" type: "tag" - name: "event_type" type: "tag" - name: "corrected_lp" type: "tag" - name: "embedding" type: "vector" attrs: algorithm: "flat" dims: 59 distance_metric: "L2" datatype: "float32"
加载数据时,我将向量通过vec.tobytes()转为字节串存入索引,代码如下:
# event是包含lp、customer_token、event_type、corrected_lp字段的Pydantic模型 # 使用嵌入模型处理图片得到向量 vec = to_embedding(image) index = await search_index() info = { 'lp': event.lp, 'embedding': vec.tobytes(), 'customer_token': event.customer_token, 'event_type': event.event_type } if event.corrected_lp: info['corrected_lp'] = event.corrected_lp await index.load([info], keys=[f'event:{identifier}'], ttl=config['index']['ttl'].get(int))
数据可正常存入,但使用FilterQuery查询后,返回结果中的embedding为普通字符串而非预期的字节串,查询代码如下:
index = await search_index() filter_exp = ((Tag("customer_token") == filters.customer_token) & (Tag("event_type") == filters.event_type)) filter_query = FilterQuery( return_fields=["event_type", "lp", "corrected_lp", "customer_token", "embedding"], filter_expression=filter_exp) res = await index.query(filter_query) if not res: return None # 将字典列表转为Event对象列表 events = [ Event(event_type=event['event_type'], lp=event['lp'], corrected_lp=event.get('corrected_lp'), customer_token=event['customer_token'], vector=list(np.frombuffer(event['embedding'],dtype=np.float32)), ) for event in res ]
使用string.encode()无法还原为正确格式的字节串,请问如何从该字符串获取原始编码的字节串?
解决方法
RedisVL在存储向量字段时,会自动将字节串形式的向量做Base64编码存储,查询返回时则会将Base64编码转为普通字符串返回。要还原原始字节串,需要对返回的字符串做Base64解码:
- 导入
base64模块 - 对返回的
event['embedding']字符串执行base64.b64decode()解码得到原始字节串 - 再用
np.frombuffer()转为numpy数组
修改后的转换代码如下:
import base64 import numpy as np events = [ Event(event_type=event['event_type'], lp=event['lp'], corrected_lp=event.get('corrected_lp'), customer_token=event['customer_token'], vector=list(np.frombuffer(base64.b64decode(event['embedding']), dtype=np.float32)), ) for event in res ]
验证逻辑:存入时的字节串vec.tobytes()经过Base64编码后存储,查询返回的是编码后的字符串,解码后就能得到原始字节串,再转成numpy数组就和存入前的向量一致了。
内容的提问来源于stack exchange,提问作者Saurabh Gupta
相关产品推荐
相关产品推荐

