使用LettuceMod与Redis Stack能否返回普通Java对象而非Document<K,V>
用LettuceMod搭配Redis Stack返回普通Java对象的方案
可以直接返回普通Java对象(比如SearchResults<UUID, MyObject>),不需要局限于Document<K, V>或String泛型,核心是配置合适的Codec处理自定义类型的序列化/反序列化,以下是具体说明和实现:
1. 纠正对StatefulRedisModulesConnection泛型的理解
StatefulRedisModulesConnection<K, V>的泛型定义:
K:Redis中数据键的类型(比如你存储的哈希键是UUID,则K=UUID)V:Redis中哈希值的类型(比如你的自定义对象MyObject,则V=MyObject)
RedisFT的索引名本质是Redis字符串键,查询语句也是字符串格式,但Lettuce允许你用非String类型作为参数,只要你的Codec能将这些类型序列化成Redis可识别的字符串字节序列。
2. 实现SearchResults<UUID, MyObject>的步骤
步骤1:配置支持自定义类型的Codec
使用GenericJackson2JsonRedisCodec(兼容任意类型)或JacksonJsonRedisCodec(指定具体类型)处理序列化:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.lettuce.core.codec.GenericJackson2JsonRedisCodec; import io.lettuce.core.codec.RedisCodec; // 配置ObjectMapper,支持UUID、Java时间类型等 ObjectMapper objectMapper = new ObjectMapper() .registerModule(new JavaTimeModule()) .configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 创建通用Codec,支持任意类型的键和值 RedisCodec<Object, Object> codec = GenericJackson2JsonRedisCodec.create(objectMapper);
步骤2:初始化带自定义Codec的连接
import io.lettuce.core.RedisModulesClient; import io.lettuce.core.api.StatefulRedisModulesConnection; RedisModulesClient client = RedisModulesClient.create("redis://localhost:6379"); StatefulRedisModulesConnection<Object, Object> connection = client.connect(codec);
步骤3:执行查询并获取自定义类型结果
直接调用ftSearch,返回的结果会自动将Redis数据反序列化为目标类型:
import io.lettuce.core.api.sync.RedisModulesCommands; import io.lettuce.core.modules.search.SearchResults; import io.lettuce.core.modules.search.document.Document; RedisModulesCommands<Object, Object> commands = connection.sync(); // 传入字符串索引名和查询语句,结果自动映射为UUID(数据键)和MyObject(哈希值) SearchResults<UUID, MyObject> results = (SearchResults<UUID, MyObject>) commands.ftSearch("user-index", "@age:[18 30]"); // 遍历结果,直接获取普通Java对象 for (Document<UUID, MyObject> doc : results.getDocuments()) { UUID userId = doc.getId(); MyObject user = doc.getValue(); // 业务逻辑处理 }
3. 关于非String类型调用ftSearch的疑问
Lettuce的API允许K/V为非String类型,原因是:
- Lettuce通过Codec层实现类型与Redis字节序列的转换,只要你的Codec能将自定义类型(如UUID、枚举)序列化成Redis可识别的字符串字节,就可以用这些类型作为索引名或查询语句。
- 比如你用
UUID作为索引名,只要Codec能把UUID转成字符串格式(如"a1b2c3..."),RedisFT就能识别这个索引名。 - 实际使用中,查询语句一般还是字符串格式,建议用兼容字符串的Codec,避免不必要的类型转换麻烦。
内容的提问来源于stack exchange,提问作者adamzrk
相关产品推荐
相关产品推荐

