Redis OM Spring中findByTypeNotIn生成与findByTypeIn相同RediSearch查询的问题及NOT IN过滤实现咨询
Redis OM Spring中findByTypeNotIn生成与findByTypeIn相同RediSearch查询的问题及NOT IN过滤实现咨询
我完全能理解你遇到的这个糟心情况——明明调用的是findByTypeNotIn方法,结果生成的RediSearch查询却和findByTypeIn一模一样,这显然和预期不符。咱们一步步来拆解解决这个问题:
1. Redis OM Spring是否支持NotIn查询?
其实Redis OM Spring是支持NotIn查询的,但在部分旧版本中,自动查询推导的逻辑存在bug,导致NotIn这个后缀没有被正确解析成RediSearch的否定语法(也就是前缀-),你遇到的就是这个典型的版本兼容问题。
2. 实现NOT IN过滤的正确方式
如果自动推导的逻辑没生效,你可以用下面这些可靠的方法来实现需求:
方法一:使用自定义@Query注解
这是最直接的解决方案,手动指定符合预期的RediSearch查询语句,完全绕开自动推导的坑:
interface MarkerRepository : RedisDocumentRepository<RedisMarker, String> { fun findByTypeIn(types: List<String>): List<RedisMarker>? @Query("FT.SEARCH MarkerIdx \"-@type:({0})\" LIMIT 0 10000 DIALECT 2") fun findByTypeNotIn(types: List<String>): List<RedisMarker>? }
这里的{0}会自动替换成传入的types列表,框架会帮你把列表元素拼接成1|2|3的格式,再加上前缀-就完美实现了NOT IN的效果。
方法二:升级Redis OM Spring版本
如果你的框架版本比较老旧,建议直接升级到最新的稳定版——后续版本已经修复了不少自动查询推导的bug,升级后findByTypeNotIn大概率能自动生成带-前缀的正确查询,不用再手动写注解。
方法三:使用Criteria API构建查询
如果你更偏好类型安全的编码方式,也可以用Redis OM的Criteria API手动构建带否定条件的查询:
@Service class MarkerService(private val markerRepository: RedisDocumentRepository<RedisMarker, String>) { fun findByTypeNotIn(types: List<String>): List<RedisMarker>? { val criteria = RedisQuery<RedisMarker>(RedisMarker::class.java) .add( Criteria.where("type").notIn(types) ) return markerRepository.findBy(criteria) } }
这种方式完全由你掌控查询逻辑,能确保生成的RediSearch语句带有正确的否定前缀,也更灵活。
内容来源于stack exchange
相关产品推荐
相关产品推荐

