Skip to content

Commit

Permalink
feature: RedisHash secondary indices override w/ RediSearch
Browse files Browse the repository at this point in the history
  • Loading branch information
bsbodden committed Nov 16, 2021
1 parent f991f59 commit 7aa0822
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.redis.hashes;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
Expand All @@ -9,6 +11,7 @@

import com.redis.hashes.domain.Role;
import com.redis.hashes.domain.User;
import com.redis.hashes.repositories.RoleRepository;
import com.redis.hashes.repositories.UserRepository;
import com.redis.om.spring.annotations.EnableRedisEnhancedRepositories;

Expand All @@ -18,7 +21,11 @@
public class RdsHashesApplication {

@Autowired
private UserRepository repository;
private UserRepository userRepo;

@SuppressWarnings("unused")
@Autowired
private RoleRepository roleRepo;

@Bean
CommandLineRunner loadTestData() {
Expand All @@ -28,15 +35,15 @@ CommandLineRunner loadTestData() {
Role guitar = Role.of("GUITAR");
Role drums = Role.of("DRUMS");

//TODO: handle @Reference deserialization
//roleRepo.saveAll(List.of(bass, vocals, guitar, drums));

User john = User.of("Zack", "de la Rocha", bass);
User tim = User.of("Tim", "Commerford", vocals);
User tom = User.of("Tom", "Morello", guitar);
User brad = User.of("Brad", "Wilk", drums);

repository.save(john);
repository.save(tim);
repository.save(tom);
repository.save(brad);
userRepo.saveAll(List.of(john, tim, tom, brad));
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.redis.hashes.repositories;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.redis.hashes.domain.Role;

@Repository
public interface RoleRepository extends CrudRepository<Role, String> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,4 @@ public interface UserRepository extends CrudRepository<User, String> {
Optional<User> findOneByLastName(String lastName);

List<User> findByFirstNameAndLastName(String firstName, String lastName);

List<User> findByMiddleNameContains(String middleName);

List<User> findByRole_RoleName(String roleName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void createIndicesFor(Class<?> cls, ApplicationContext ac) {
try {
Class<?> cl = Class.forName(beanDef.getBeanClassName());
indexName = cl.getSimpleName() + "Idx";
logger.debug(String.format("Found @Document/@RedisHash annotated class: %s", cl.getSimpleName()));
logger.debug(String.format("Found @%s annotated class: %s", cls.getSimpleName(), cl.getSimpleName()));

List<Field> fields = new ArrayList<Field>();
for (java.lang.reflect.Field field : cl.getDeclaredFields()) {
Expand All @@ -176,53 +176,52 @@ private void createIndicesFor(Class<?> cls, ApplicationContext ac) {
// Any Character class -> Tag Search Field
//
if (CharSequence.class.isAssignableFrom(field.getType())) {
fields.add(indexAsTagFieldFor(field));
fields.add(indexAsTagFieldFor(cls, field));
}
//
// Any Numeric class -> Numeric Search Field
//
if (Number.class.isAssignableFrom(field.getType())) {
fields.add(indexAsNumericFieldFor(field));
fields.add(indexAsNumericFieldFor(cls, field));
}
//
// Set
//
if (Set.class.isAssignableFrom(field.getType())) {
fields.add(indexAsTagFieldFor(field));
fields.add(indexAsTagFieldFor(cls, field));
}
//
// Point
//
if (field.getType() == Point.class) {
fields.add(indexAsGeoFieldFor(field));
fields.add(indexAsGeoFieldFor(cls, field));
}

}

// Searchable - behaves like Text indexed
if (field.isAnnotationPresent(Searchable.class)) {
Searchable ti = field.getAnnotation(Searchable.class);
fields.add(indexAsTextFieldFor(field, ti));
fields.add(indexAsTextFieldFor(cls, field, ti));
}
// Text
if (field.isAnnotationPresent(TextIndexed.class)) {
TextIndexed ti = field.getAnnotation(TextIndexed.class);
fields.add(indexAsTextFieldFor(field, ti));
fields.add(indexAsTextFieldFor(cls, field, ti));
}
// Tag
if (field.isAnnotationPresent(TagIndexed.class)) {
TagIndexed ti = field.getAnnotation(TagIndexed.class);
fields.add(indexAsTagFieldFor(field, ti));
fields.add(indexAsTagFieldFor(cls, field, ti));
}
// Geo
if (field.isAnnotationPresent(GeoIndexed.class)) {
GeoIndexed gi = field.getAnnotation(GeoIndexed.class);
fields.add(indexAsGeoFieldFor(field, gi));
fields.add(indexAsGeoFieldFor(cls, field, gi));
}
// Numeric
if (field.isAnnotationPresent(NumericIndexed.class)) {
NumericIndexed ni = field.getAnnotation(NumericIndexed.class);
fields.add(indexAsNumericFieldFor(field, ni));
fields.add(indexAsNumericFieldFor(cls, field, ni));
}
}

Expand Down Expand Up @@ -275,8 +274,10 @@ private Set<BeanDefinition> getBeanDefinitionsFor(ApplicationContext ac, Class..
return beanDefs;
}

private Field indexAsTagFieldFor(java.lang.reflect.Field field, TagIndexed ti) {
FieldName fieldName = FieldName.of("$." + field.getName() + "[*]");
private Field indexAsTagFieldFor(Class<?> cls, java.lang.reflect.Field field, TagIndexed ti) {
String fieldPrefix = cls == Document.class ? "$." : "";
String fieldPostfix = cls == Document.class ? "[*]" : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName() + fieldPostfix);

if (!ObjectUtils.isEmpty(ti.alias())) {
fieldName = fieldName.as(ti.alias());
Expand All @@ -287,15 +288,20 @@ private Field indexAsTagFieldFor(java.lang.reflect.Field field, TagIndexed ti) {
return new Field(fieldName, FieldType.Tag, false, ti.noindex());
}

private Field indexAsTagFieldFor(java.lang.reflect.Field field) {
FieldName fieldName = FieldName.of("$." + field.getName() + "[*]");
private Field indexAsTagFieldFor(Class<?> cls, java.lang.reflect.Field field) {
String fieldPrefix = cls == Document.class ? "$." : "";
String fieldPostfix = cls == Document.class ? "[*]" : ""; // the [*] is only for arrays BTW
FieldName fieldName = FieldName.of(fieldPrefix + field.getName() + fieldPostfix);

fieldName = fieldName.as(field.getName());


return new Field(fieldName, FieldType.Tag, false, false);
}

private Field indexAsTextFieldFor(java.lang.reflect.Field field, TextIndexed ti) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsTextFieldFor(Class<?> cls, java.lang.reflect.Field field, TextIndexed ti) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

if (!ObjectUtils.isEmpty(ti.alias())) {
fieldName = fieldName.as(ti.alias());
Expand All @@ -307,8 +313,9 @@ private Field indexAsTextFieldFor(java.lang.reflect.Field field, TextIndexed ti)
return new TextField(fieldName, ti.weight(), ti.sortable(), ti.nostem(), ti.noindex(), phonetic);
}

private Field indexAsTextFieldFor(java.lang.reflect.Field field, Searchable ti) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsTextFieldFor(Class<?> cls, java.lang.reflect.Field field, Searchable ti) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

if (!ObjectUtils.isEmpty(ti.alias())) {
fieldName = fieldName.as(ti.alias());
Expand All @@ -320,8 +327,10 @@ private Field indexAsTextFieldFor(java.lang.reflect.Field field, Searchable ti)
return new TextField(fieldName, ti.weight(), ti.sortable(), ti.nostem(), ti.noindex(), phonetic);
}

private Field indexAsGeoFieldFor(java.lang.reflect.Field field, GeoIndexed gi) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsGeoFieldFor(Class<?> cls, java.lang.reflect.Field field, GeoIndexed gi) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

if (!ObjectUtils.isEmpty(gi.alias())) {
fieldName = fieldName.as(gi.alias());
} else {
Expand All @@ -331,8 +340,10 @@ private Field indexAsGeoFieldFor(java.lang.reflect.Field field, GeoIndexed gi) {
return new Field(fieldName, FieldType.Geo);
}

private Field indexAsNumericFieldFor(java.lang.reflect.Field field, NumericIndexed ni) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsNumericFieldFor(Class<?> cls, java.lang.reflect.Field field, NumericIndexed ni) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

if (!ObjectUtils.isEmpty(ni.alias())) {
fieldName = fieldName.as(ni.alias());
} else {
Expand All @@ -342,15 +353,19 @@ private Field indexAsNumericFieldFor(java.lang.reflect.Field field, NumericIndex
return new Field(fieldName, FieldType.Numeric);
}

private Field indexAsNumericFieldFor(java.lang.reflect.Field field) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsNumericFieldFor(Class<?> cls, java.lang.reflect.Field field) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

fieldName = fieldName.as(field.getName());

return new Field(fieldName, FieldType.Numeric);
}

private Field indexAsGeoFieldFor(java.lang.reflect.Field field) {
FieldName fieldName = FieldName.of("$." + field.getName());
private Field indexAsGeoFieldFor(Class<?> cls, java.lang.reflect.Field field) {
String fieldPrefix = cls == Document.class ? "$." : "";
FieldName fieldName = FieldName.of(fieldPrefix + field.getName());

fieldName = fieldName.as(field.getName());

return new Field(fieldName, FieldType.Geo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public RediSearchQuery(QueryMethod queryMethod, RepositoryMetadata metadata,
this.returnFields = new String[] {};
}
} catch (NoSuchMethodException | SecurityException e) {
logger.warn(String.format("Did not find query method %s(%s)", queryMethod.getName(), Arrays.toString(params)), e);
logger.debug(String.format("Did not find query method %s(%s): %s", queryMethod.getName(), Arrays.toString(params), e.getMessage()));
}
}

Expand Down
Loading

0 comments on commit 7aa0822

Please sign in to comment.