Skip to content

QueryByExample<T> with RedisEnhancedRepository<T, ID> #439

@dasivon021

Description

@dasivon021

Hi @bsbodden and @sazzad16,

When I'm trying to execute query using QueryByExampleExecutor<T> interface special characters are not escaped which causes query to fail. Reproducible example is here

Context:

I'm using Spring Boot 3.2.3 and redis-om-spring (0.9.1). redis-om-spring transitively uses spring-data-redis. The model looks like this:

@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@org.springframework.data.redis.core.RedisHash
public class Student {

    @Id
    private Long id;

    @com.redis.om.spring.annotations.Indexed(alias = "User-Name")
    private String userName;

    @com.redis.om.spring.annotations.Indexed(alias = "Event-Timestamp")
    private LocalDateTime eventTimestamp;
    
}

Hash records are stored in this format:

com.example.demo.entity.Student:123214

  "First-Name": "UWucCgR+GAiakfbSpzuLBQ==",
  "Event-Timestamp": "182952385124",
  "User-Name": "marc.mk"

My application will only be executing search queries.

On the application start up, index is created like this:

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" "Event-Timestamp" "NUMERIC" "id" "AS" "id" "NUMERIC" "SORTABLE"

Repository:

@Repository
@Transactional(readOnly = true)
public interface StudentRepository extends RedisEnhancedRepository<Student, Long>, QueryByExampleExecutor<Student> {

    List<Student> findByUserNameAndEventTimestampBetweenOrderByEventTimestampAsc(String userName, String fromDate, String toDate);

    List<Student> findByUserName(String userName);

    default Student findFirstByPropertyOrderByEventTimestamp(
            Student student,
            ExampleMatcher exampleMatcher,
            Function<FluentQuery.FetchableFluentQuery<Student>, Student> queryFunction) {
        return findBy(Example.of(student, exampleMatcher), queryFunction);
    }
}

If I try to invoke findFirstByPropertyOrderByEventTimestamp, I get an exception:

redis.clients.jedis.exceptions.JedisDataException: Syntax error at offset 7 near User
	at redis.clients.jedis.Protocol.processError(Protocol.java:105) ~[jedis-5.0.2.jar:na]

By looking at the queries on monitor, I can see this is actually executed:

"FT.SEARCH" "com.example.demo.entity.StudentIdx" "( @User-Name:{pera})" "SORTBY" "Event-Timestamp" "DESC" "LIMIT" "0" "1" "DIALECT" "1"

What in fact should be executed is:

"FT.SEARCH" "com.example.demo.entity.StudentIdx" "( @User\\-Name:{pera})" "SORTBY" "Event-Timestamp" "DESC" "LIMIT" "0" "1" "DIALECT" "1"

This is the code which invokes the query:

Function<FluentQuery.FetchableFluentQuery<Student>, Student> sortFunction =
				query -> query.sortBy(Sort.by("Event-Timestamp").descending()).firstValue();

var matcher =ExampleMatcher.matching().withMatcher("userName", ExampleMatcher.GenericPropertyMatcher::exact);

var student = Student.builder().userName("pera").build();

Student result = studentRepository.findFirstByPropertyOrderByEventTimestamp(student, matcher, sortFunction);

This same problem was present in redis-om-spring lib, but with 433 it was quickly resolved.

Hopefully, similar changes are can be done here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions