springspring-bootredisspring-projectionsredis-om-spring

How to fetch only specific fields from Redis JSON using projections in Spring Boot ? Current approach return nulls


I’m using Redis OM Spring with Kotlin to store documents in Redis as JSON.

Here’s a simplified version of my document:

@Document(value = "Marker", indexName = "MarkerIdx")
data class RedisMarker(

    @Indexed
    var number: String,                

    @Indexed
    var startDate: LocalDate,            

    @Indexed
    var delay: Int,                    

    @Indexed
    var location: Point,               

    @Indexed
    var type: String = "",

    @TimeToLive
    var ttl: Long = 1.days.inWholeSeconds              
) {
    @Id
    var id: String = "${number}:${startDate}"
        private set
}

I want to query Redis by a number(e.g., ["120"]) but only return number and location, not the whole document.

I have tried this-

interface Stat  {
    val number: String
    val location: Point
}

interface MarkerRepo : RedisDocumentRepository<RedisMarker, String> {
    fun findByNumber(number: String): List<Stat>
}

It generates this query in Redis, and the query returns data in Redis CLI -

    "FT.SEARCH" "MarkerIdx" "@number:{120}" "LIMIT" "0" "10000" "RETURN" "6" "$.number" "AS" "number" "$.location" "AS" "location" "DIALECT" "2"
1) "3"
2) "Marker:120:2025-08-24"
3) 1) "number"
   2) "120"
   3) "location"
   4) "86.38667,24.77267"
4) "Marker:120:2025-08-23"
5) 1) "number"
   2) "120"
   3) "location"
   4) "78.01978,29.75273"
6) "Marker:120:2025-08-22"
7) 1) "number"
   2) "120"
   3) "location"
   4) "74.8671,31.633"

and in the controller -

@GetMapping("/get")
    suspend fun getDetails() =
         markerRepo.findByNumber("120")

But it returns a list of nulls. When I use the RedisMarker data class, it returns the whole data class

 fun findByNumber(code: String): List<RedisMarker> 

What am I doing wrong?


Solution

  • You found a weird bug. I was able to reproduce it.

    A workaround is annotating the location (Point) in the projection with the Spel annotation:

    interface Stat  {
        val number: String
    
        @Value("#{target.location}")
        val location: Point
    }
    
    

    Let me know if it works. It worked on my side. In the meantime, I will open an issue on GitHub.

    Thank you!