redis / redis-om-spring

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

entity search order for text effects underlying query. #176

Closed rjdkolb closed 1 year ago

rjdkolb commented 1 year ago

maven version: 0.6.4

If you search for on a field first and on then on free text, the field part of the query is dropped.

So this does not work as it returns data not for Microsoft:

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

This works:

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

I found this when I was looking in JRediSearch io.redisearch.client.Client

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);

Stackoverflow question.

bsbodden commented 1 year ago

Thanks @rjdkolb! Currently investigating. Can you do me a favor and capture the commands that are being sent to Redis by running the Redis CLI is monitor mode? redis-cli MONITOR?

rjdkolb commented 1 year ago

Pleasure :)

For Search3 I get:

1675437670.689313 [0 172.17.0.1:60888] "FT.SEARCH" "com.redis.om.documents.domain.CompanyIdx" "*co*" "LIMIT" "0" "10000"

For Search 4 I get:

1675437762.647725 [0 172.17.0.1:60890] "FT.SEARCH" "com.redis.om.documents.domain.CompanyIdx" "(*co* @name:{Microsoft})" "LIMIT" "0" "10000"

bsbodden commented 1 year ago

Looks like a bug!

setu9760 commented 1 year ago

@bsbodden If you haven't already found the fix; may I contribute for this one please?

rjdkolb commented 1 year ago

@setu9760 , I am happy to verify the fix. :)

bsbodden commented 1 year ago

@setu9760 and @rjdkolb please! It was on my current list but haven't gotten to it yet! Thank you!

bsbodden commented 1 year ago

@rjdkolb FYI the chaining of filters implies and "AND" so on the search above you should get no results based on the sample data. For an "OR" you can do:

    List<Company> companies = stream //
        .filter( //
            Company$.NAME.eq("RedisInc") //
                .or(Company$.NAME.eq("Microsoft")) //
        ) //
        .collect(Collectors.toList());

@setu9760 if you haven't figure out a fix, I have simple one.

rjdkolb commented 1 year ago

thanks @bsbodden , I saw there was a copy and paste error with my example. I updated search4.

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

Both Search3 and Search4 examples work correctly now.