Secondary Indexes

Secondary indexes 用于启用基于原始 Redis 结构的查找操作。每次保存时,都会将值写入相应的索引,并且在删除或 expire 对象后都会将其移除。

Simple Property Index

给定前面显示的示例 Person 实体,我们可以通过用 @Indexed 注释该属性为 firstname 创建一个索引,如下面的示例所示:

Example 1. Annotation driven indexing
@RedisHash("people")
public class Person {

  @Id String id;
  @Indexed String firstname;
  String lastname;
  Address address;
}

索引针对实际属性值建立。保存两个人(例如,“rand”和“aviendha”)将导致建立类似于以下内容的索引:

SADD people:firstname:rand e2c7dcee-b8cd-4424-883e-736ce564363e
SADD people:firstname:aviendha a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56

还可以对嵌套元素建立索引。假设 Address 有一个用 @Indexed 注释的 city 属性。在这种情况下,只要 person.address.city 不为 null,我们就会为每个城市拥有集合,如下面的示例所示:

SADD people:address.city:tear e2c7dcee-b8cd-4424-883e-736ce564363e

此外,通过编程设置,你可以定义对映射键和列表属性的索引,如下面的示例所示:

@RedisHash("people")
public class Person {

  // ... other properties omitted

  Map<String, String> attributes;     1
  Map<String, Person> relatives;      2
  List<Address> addresses;            3
}
1 SADD people:attributes.map-key:map-value e2c7dcee-b8cd-4424-883e-736ce564363e
2 SADD people:relatives.map-key.firstname:tam e2c7dcee-b8cd-4424-883e-736ce564363e
3 SADD people:addresses.city:tear e2c7dcee-b8cd-4424-883e-736ce564363e

无法在“ References”上解析索引。

与键空间一样,你可以配置索引,而不必注释实际域类型,如下面的示例所示:

Example 2. Index Setup with @EnableRedisRepositories
@Configuration
@EnableRedisRepositories(indexConfiguration = MyIndexConfiguration.class)
public class ApplicationConfig {

  //... RedisConnectionFactory and RedisTemplate Bean definitions omitted

  public static class MyIndexConfiguration extends IndexConfiguration {

    @Override
    protected Iterable<IndexDefinition> initialConfiguration() {
      return Collections.singleton(new SimpleIndexDefinition("people", "firstname"));
    }
  }
}

同样,与键空间一样,你可以通过编程配置索引,如下面的示例所示:

Example 3. Programmatic Index setup
@Configuration
@EnableRedisRepositories
public class ApplicationConfig {

  //... RedisConnectionFactory and RedisTemplate Bean definitions omitted

  @Bean
  public RedisMappingContext keyValueMappingContext() {
    return new RedisMappingContext(
      new MappingConfiguration(
        new KeyspaceConfiguration(), new MyIndexConfiguration()));
  }

  public static class MyIndexConfiguration extends IndexConfiguration {

    @Override
    protected Iterable<IndexDefinition> initialConfiguration() {
      return Collections.singleton(new SimpleIndexDefinition("people", "firstname"));
    }
  }
}

Geospatial Index

假设 Address 类型包含一个 location 属性,该属性属于 Point 类型,并且保存特定地址的地理坐标。通过用 @GeoIndexed 注释该属性,Spring Data Redis 会使用 Redis GEO 命令添加这些值,如下面的示例所示:

@RedisHash("people")
public class Person {

  Address address;

  // ... other properties omitted
}

public class Address {

  @GeoIndexed Point location;

  // ... other properties omitted
}

public interface PersonRepository extends CrudRepository<Person, String> {

  List<Person> findByAddressLocationNear(Point point, Distance distance);     1
  List<Person> findByAddressLocationWithin(Circle circle);                    2
}

Person rand = new Person("rand", "al'thor");
rand.setAddress(new Address(new Point(13.361389D, 38.115556D)));

repository.save(rand);                                                        3

repository.findByAddressLocationNear(new Point(15D, 37D), new Distance(200, Metrics.KILOMETERS)); 4
1 使用 PointDistance 在嵌套属性上声明查询方法。
2 使用 Circle 在嵌套属性上声明查询方法以在其中搜索。
3 GEOADD people:address:location 13.361389 38.115556 e2c7dcee-b8cd-4424-883e-736ce564363e
4 GEORADIUS people:address:location 15.0 37.0 200.0 km

在前一个示例中,使用将对象的 id 作为成员名称的 GEOADD 存储经度和纬度值。查找器方法允许使用 CirclePoint, Distance 组合来查询那些值。

not 可以将 nearwithin 与其他条件相结合。