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>
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.