redis / redis-om-spring

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

Is there a way to text search collections inside object? #180

Closed rjdkolb closed 1 year ago

rjdkolb commented 1 year ago

Based on the examples I would like to search for values inside CompanyMeta and not just on Company. I am unsure if this is a bug or a limitation on RediSearch. I am testing on the main branch.

CompanyMeta stringValue is ZZZZZZZZZZZ in my example.

Company redis = Company.of("Redis", Set.of(MySearchable.of("AAA","BBB")), "https://redis.com", new Point(-122.066540, 37.377690), 526, 2011, Set.of(CompanyMeta.of("Redis", 100, Set.of("RedisTag"))));

Company microsoft = Company.of("Microsoft", Set.of(MySearchable.of("CCC","DDD")), "https://microsoft.com", new Point(-122.124500, 47.640160), 182268, 1975, Set.of(CompanyMeta.of("ZZZZZZZZZZZ", 50, Set.of("MsTag"))));

I have added @Searchable to metaList in Company in the example.

  @NonNull
  @Searchable
  @Indexed
  private Set<CompanyMeta> metaList;

and in CompanyMeta

public class CompanyMeta {
  @NonNull
  @Searchable
  @Indexed
  private String stringValue;
var result = entityStream.of(Company.class)
        .filter("*ZZZZZZ*")
        .collect(Collectors.toList());
System.out.println("Search:");
result.forEach(System.out::println);//result is size of 0

from redis-cli MONITOR

"FT.CREATE" "com.redis.om.documents.domain.CompanyIdx" "ON" "JSON" "PREFIX" "1" "com.redis.om.documents.domain.Company:" "LANGUAGE" "english" "SCHEMA" "$.name" "AS" "name" "TEXT" "$.tags[*]" "AS" "tags" "TAG" "SEPARATOR" "|" "$.location" "AS" "location" "GEO" "$.numberOfEmployees" "AS" "numberOfEmployees" "NUMERIC" "$.yearFounded" "AS" "yearFounded" "NUMERIC" "$.metaList[0:].stringValue" "AS" "metaList_stringValue" "TAG" "SEPARATOR" "|" "$.metaList[0:].numberValue" "AS" "metaList_numberValue" "NUMERIC" "$.metaList[0:].tagValues" "AS" "metaList_tagValues" "TAG" "SEPARATOR" "|" "$.id" "AS" "id" "TAG" "SEPARATOR" "|"

"JSON.SET" "com.redis.om.documents.domain.Company:01GRNP7ERRV6QT7B6HVHW87A21" "." "{\"id\":\"01GRNP7ERRV6QT7B6HVHW87A21\",\"name\":\"Microsoft\",\"tags\":[\"innovative\",\"reliable\"],\"url\":\"https://microsoft.com\",\"location\":\"-122.1245,47.64016\",\"numberOfEmployees\":182268,\"yearFounded\":1975,\"metaList\":[{\"stringValue\":\"ZZZZZZZZZZZ\",\"numberValue\":50,\"tagValues\":[\"MsTag\"]}],\"publiclyListed\":false,\"createdDate\":1675765201691}"

FT.SEARCH" "com.redis.om.documents.domain.CompanyIdx" "*ZZZZZZ*" "LIMIT" "0" "10000"
bsbodden commented 1 year ago

See the example in https://github.com/redis/redis-om-spring/blob/main/redis-om-spring/src/test/java/com/redis/om/spring/search/stream/EntityStreamsIssuesTest.java#L46

rjdkolb commented 1 year ago

thanks @bsbodden , this unit test works, but it does not use a List or a Set.

So what I am looking for is a:

  @Test
  void testFilterEntityStreamsByNestedField3() {
    var results = entityStream.of(DeepNest.class) //
            .filter("*Spartacus*")
            .map(DeepNest$.NAME) //
            .collect(Collectors.toList());
    assertThat(results).containsOnly("dn-3");
  }
@Document
public class DeepNest {
  @Id
  private String id;

  @Indexed
  @NonNull
  private String name;

  @Indexed
  @NonNull
  private List<NestLevel1> nestLevels;
}

Maybe this is a limitation or even a bad idea to search this deep.

bsbodden commented 1 year ago

Let me add that test since there have been some changes to RediSearch that might allow for that.