springspring-bootkotlinredis

How to search both name and code fields simultaneously with Redis OM Spring AutoComplete?


I'm using Redis OM Spring with auto-complete functionality and want to search across multiple fields (both name and code) in a single query, rather than making separate calls to each field's auto-complete method. Current Setup Entity:

@Document
data class AutoSearchStation(
    @Id
    @AutoComplete
    @AutoCompletePayload(fields = ["name", "code"])
    var code: String = "",

    @AutoComplete
    @AutoCompletePayload(fields = ["name", "code"])
    var name: String = "",

    @AutoCompletePayload(fields = ["name", "code"])
    var lat: Double = 0.0,

    @AutoCompletePayload(fields = ["name", "code"])
    var lng: Double = 0.0
)

Repository:

interface StationsRepository : RedisDocumentRepository<AutoSearchStation?, String?> {
    fun autoCompleteName(query: String?): MutableList<Suggestion?>?
    fun autoCompleteName(query: String?, options: AutoCompleteOptions?): MutableList<Suggestion?>?
    fun autoCompleteCode(query: String?): MutableList<Suggestion?>?
    fun autoCompleteCode(query: String?, options: AutoCompleteOptions?): MutableList<Suggestion?>?
}

Controller:

@RestController
@RequestMapping("/stations")
class AirportsController(
    private val repository: StationsRepository
) {
    @GetMapping("/search")
    fun query(@RequestParam("q") query: String?): MutableList<Suggestion?>? {
        // Currently only searches in code field
        return repository.autoCompleteCode(query, AutoCompleteOptions.get().withPayload())
    }
}

What I've Tried

Generic search method - Added fun search(query: String?, options: AutoCompleteOptions?): MutableList<Suggestion?>? to repository, but got:

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at com.redis.om.spring.util.ObjectUtils.firstToLowercase(ObjectUtils.java:123)

Question

Is there a way to create a single auto-complete method that searches across both name and code fields simultaneously in Redis OM Spring?


Solution

  • @AutoComplete in Redis OM Spring maps to Redis Query Engine suggestion dictionaries (backed by FT.SUGADD/FT.SUGGET).

    Each @AutoComplete field = one dictionary.

    So in your entity, code and name create two separate dictionaries.

    Redis Query Engine itself can’t query two suggestion dictionaries in one call — you either:

    For merging at query time:

    @GetMapping("/search")
    fun query(@RequestParam("q") query: String): List<Suggestion> {
        val codeResults = repository.autoCompleteCode(query, AutoCompleteOptions.get().withPayload())
        val nameResults = repository.autoCompleteName(query, AutoCompleteOptions.get().withPayload())
    
        return (codeResults + nameResults).distinctBy { it.string } // removes duplicates
    }
    

    If you want only one dictionary, store the values of name and code in a single @AutoComplete field instead.