Search code examples
redisredisearchredis-om-spring

How to search for text and filter?


UPDATE: This is fixed in 0.8.0

I am trying to search for filter by an indexed field and search for free text inside my objects. It seems that it is searching for the company name or the search term. How do I make this an and for SearchStream.freeText(String freeText)?

I need to use SearchStream.freeText since there are many fields I want to search on.

My data based on the roms-documents, I modified RomsDocumentsApplication

companyRepo.deleteAll();
Company redis1 = Company.of("Redis", "wwwabccom", new Point(-122.066540, 37.377690), 526, 2011, Set.of(CompanyMeta.of("Redis", 100, Set.of("RedisTag"))));
Company redis2 = Company.of("Redis", "wwwxyzcom", new Point(-122.066540, 37.377690), 526, 2011, Set.of(CompanyMeta.of("Redis", 100, Set.of("RedisTag"))));

Company microsoft1 = Company.of("Microsoft", "wwwabcnet", new Point(-122.066540, 37.377690), 526, 2011, Set.of(CompanyMeta.of("Redis", 100, Set.of("RedisTag"))));
Company microsoft2 = Company.of("Microsoft", "wwwxyznet", new Point(-122.066540, 37.377690), 526, 2011, Set.of(CompanyMeta.of("Redis", 100, Set.of("RedisTag"))));


companyRepo.save(redis1);
companyRepo.save(redis2);
companyRepo.save(microsoft1);
companyRepo.save(microsoft2);


@Data
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Document
@ToString
public class Company {
  @Id
  private String id;

  @NonNull
  @Indexed
  private String name;

If I search, my first two searches seem fine, but my third search find values not for the company Microsoft, but for Redis

var result1 = entityStream.of(Company.class)
        .filter(Company$.NAME.eq("Redis"))
        .filter("*abc*")
        .collect(Collectors.toList());
System.out.println("Search1:");
result1.forEach(System.out::println);

var result2 = entityStream.of(Company.class)
        .filter(Company$.NAME.eq("Microsoft"))
        .filter("*xyz*")
        .collect(Collectors.toList());
System.out.println("Search2:");
result2.forEach(System.out::println);

var result3 = entityStream.of(Company.class)
      .filter(Company$.NAME.eq("Microsoft"))
      .filter("*co*")
      .collect(Collectors.toList());
System.out.println("Search3:");
result3.forEach(System.out::println);

The output of the program:

Search1:

Company(id=01GR46XB7BMJXV5WK3AJ3FA4M9, name=Redis, tags=[], url=wwwabccom, Company(id=01GR46XB974C3JJDAW70N20SFV, name=Microsoft, tags=[], url=wwwabcnet,

Search2:

Company(id=01GR46XB9388CRW0P71QM45K43, name=Redis, tags=[], url=wwwxyzcom, Company(id=01GR46XB9ABBV3TN9BTQFP08C1, name=Microsoft, tags=[], url=wwwxyznet,

Search3:

Company(id=01GR46XB7BMJXV5WK3AJ3FA4M9, name=Redis, tags=[], url=wwwabccom, Company(id=01GR46XB9388CRW0P71QM45K43, name=Redis, tags=[], url=wwwxyzcom,

I start redis with

docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:6.2.6-v2

module list

127.0.0.1:6379> module list
1) 1) "name"
   2) "timeseries"
   3) "ver"
   4) (integer) 10805
2) 1) "name"
   2) "graph"
   3) "ver"
   4) (integer) 21005
3) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) (integer) 20403
4) 1) "name"
   2) "search"
   3) "ver"
   4) (integer) 20604
5) 1) "name"
   2) "bf"
   3) "ver"
   4) (integer) 20403

Maven

<dependency>
  <groupId>com.redis.om</groupId>
  <artifactId>redis-om-spring</artifactId>
  <version>0.6.4</version>
</dependency>

Solution

  • The answer is actually quite simple.

    The order of the filter matters. If you search in this order the first filter is ignored.

    var result3 = entityStream.of(Company.class)
          .filter(Company$.NAME.eq("Microsoft"))
          .filter("*co*")
          .collect(Collectors.toList());
    System.out.println("Search3:");
    

    If you switch the filter it works flawlessly

    var result4 = entityStream.of(Company.class)
            .filter("*co*")
            .filter(Company$.NAME.eq("Microsoft"))
            .collect(Collectors.toList());
    System.out.println("Search4:");
    result4.forEach(System.out::println);
    

    I found this out by placing a break point on io.redisearch.client.Client Somehow for Search3 the filter on Company name is missing, but is present for Search4.

    Added a bug report.