跳到主要内容

二级索引

DeepSeek V3 中英对照 Secondary Indexes

二级索引 用于基于原生 Redis 结构的查找操作。每次保存时,值会被写入相应的索引中,并且在对象被删除或过期时会被移除。

简单属性索引

给定之前展示的 Person 实体示例,我们可以通过使用 @Indexed 注解 firstname 属性来为其创建索引,如下例所示:

示例 1. 注解驱动索引

@RedisHash("people")
public class Person {

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

索引是基于实际属性值构建的。保存两个 Person(例如 "rand" 和 "aviendha")会导致建立类似于以下内容的索引:

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

还可以在嵌套元素上创建索引。假设 Address 有一个 city 属性,并且该属性被标注为 @Indexed。在这种情况下,一旦 person.address.city 不为 null,我们就会为每个城市创建集合,如下例所示:

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

此外,通过编程方式设置,您可以在地图键和列表属性上定义索引,如下例所示:

@RedisHash("people")
public class Person {

// ... other properties omitted

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

  • SADD people:relatives.map-key.firstname:tam e2c7dcee-b8cd-4424-883e-736ce564363e

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

警告

无法在 References 上解析索引。

与键空间(keyspaces)类似,您可以在不需要对实际域类型进行注解的情况下配置索引,如下例所示:

示例 2. 使用 @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"));
}
}
}
java

同样地,与键空间(keyspaces)一样,你可以通过编程方式配置索引,如下例所示:

示例 3:编程式索引设置

@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"));
}
}
}
java

地理空间索引

假设 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
java
  • 在嵌套属性上声明查询方法,使用 PointDistance

  • 在嵌套属性上声明查询方法,使用 Circle 进行搜索。

  • GEOADD people:address:location 13.361389 38.115556 e2c7dcee-b8cd-4424-883e-736ce564363e

  • GEORADIUS people:address:location 15.0 37.0 200.0 km

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

备注

无法nearwithin 与其他条件结合使用。