C#实现Redis向量相似度搜索时,HSET转义异常致搜索失败
解决C#中Redis向量存储的转义问题
问题核心是你把float数组转成了带转义符的十六进制字符串,Redis客户端将其作为普通文本存储,而向量索引需要的是原始二进制字节流,不是编码后的字符串。直接传递字节数组就能解决转义问题。
解决方案步骤
将float数组转为原始字节数组
用Buffer.BlockCopy直接把float数组转换成对应字节流(每个float占4字节,对应FLOAT32类型):private static byte[] FloatArrayToByteArray(float[] floats) { byte[] bytes = new byte[floats.Length * 4]; Buffer.BlockCopy(floats, 0, bytes, 0, bytes.Length); return bytes; }修改AddAsync方法,直接存储字节数组
替换原来的十六进制字符串传递,改用字节数组存入Hash:public static async Task AddAsync(string docId, string prefix, float[] vector) { byte[] vectorBytes = FloatArrayToByteArray(vector); // 用强类型HashSetAsync更安全 await mux.GetDatabase().HashSetAsync($"{prefix}{docId}", new HashEntry[] { new HashEntry("vector", vectorBytes) }); }如果坚持用
Execute方法,也可以直接传字节数组参数:public static async Task AddAsync(string docId, string prefix, float[] vector) { byte[] vectorBytes = FloatArrayToByteArray(vector); await mux.GetDatabase().ExecuteAsync("HSET", $"{prefix}{docId}", "vector", vectorBytes); }
原因说明
Redis的VECTOR字段要求存储的是原始二进制数据(比如FLOAT32类型的字节流),而你之前传递的是十六进制编码后的字符串,客户端会把字符串中的转义符\也当成内容存储,导致Redis无法识别为有效向量。直接传递字节数组时,StackExchange.Redis会把数据以二进制形式发送给Redis,完全避免转义问题。
内容的提问来源于stack exchange,提问作者Khalil Baydoun
相关产品推荐
相关产品推荐

