redis / redis-om-spring

Spring Data Redis extensions for better search, documents models, and more
MIT License
609 stars 94 forks source link

Handle search aliased fields with special characters #433

Closed dasivon021 closed 6 months ago

dasivon021 commented 6 months ago

I have Spring Boot 3.2.3 and Spring Redis OM 0.9.0. Simple entity is defined as: Reproducible example is here

import com.redis.om.spring.annotations.Indexed;
import com.redis.om.spring.annotations.SchemaFieldType;
import com.redis.om.spring.annotations.SerializationHint;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;

import java.time.LocalDateTime;

@Data
@Builder
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@RedisHash
public class Student {

    @Id
    private Long id;

    @Indexed(alias = "User-Name")//  fieldName = "User-Name", schemaFieldType = SchemaFieldType.TAG
    private String userName;

    @Indexed
    private LocalDateTime eventTimestamp;

}

My application will only be querying for data in Redis, so no inserts/deletes. Indexes are created properly I would say:

"FT.CREATE" "com.example.demo.entity.StudentIdx" "ON" "HASH" "PREFIX" "1" "com.example.demo.entity.Student:" "SCHEMA" "userName" "AS" "User-Name" "TAG" "SEPARATOR" "|" "eventTimestamp" "AS" "eventTimestamp" "NUMERIC" "id" "AS" "id" "NUMERIC" "SORTABLE"

So let say that some other app executed this query:

"hset" "com.example.demo.entity.Student:-3247060323725991617" "User-Name" "pera"

Then my search query by username throws exception:

@GetMapping("/get")
public String getEntity(){
    System.out.println(studentRepository.findByUserName("pera"));
   return "a";
}
redis.clients.jedis.exceptions.JedisDataException: Syntax error at offset 5 near User
    at redis.clients.jedis.Protocol.processError(Protocol.java:105) ~[jedis-5.0.2.jar:na]

On monitor, dash (-) within User-Name is not escaped, this is what the library is executing:

"FT.SEARCH" "com.example.demo.entity.StudentIdx" "@User-Name:{pera}" "LIMIT" "0" "10000"

it should be executed as:

"FT.SEARCH" "com.example.demo.entity.StudentIdx" "@User\\-Name:{pera}" "LIMIT" "0" "10000"

Am I missing something or this is a bug?

dasivon021 commented 6 months ago

@bsbodden Hi Brian, your assistance is very much needed. Sorry for disturbance.

bsbodden commented 6 months ago

No problem at all. Until now the expectation was for aliases to be well-formed JavaBean names, I assume that whatever is writing to that cache forces that User-name format so you have no way to change the name? So this is in the realms of perhaps a bug but likely a feature enhancement. I'll do a bit of experimentation and I'll let you know.

dasivon021 commented 6 months ago

Thanks for a prompt response. Yes, in my case, some other application(s) will be writing to Redis (cache), I have no influence on the format on how will end up, but for now it is User-Name or with multiple dashes Acct-Multi-Session-Id.

dasivon021 commented 6 months ago

Hi, thanks for a quick fix/enhancement! So we can expect 0.9.1 version on Maven Central any time soon?

bsbodden commented 6 months ago

0.9.1 coming out today!

bsbodden commented 6 months ago

@dasivon021 See :

For Hashes:

For Documents: