本文主要研究一下Spring AI的RedisVectorStore
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-redis</artifactId>
</dependency>
spring:
ai:
vectorstore:
type: redis
redis:
initialize-schema: true
indexName: default-idx
prefix: "default:"
@Test
public void testAddAndSearch() {
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
new Document("The World is Big and Salvation Lurks Around the Corner"),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));
// Add the documents to Milvus Vector Store
redisVectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = this.redisVectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
log.info("results:{}", JSON.toJSONString(results));
}
输出如下:
results:[{"contentFormatter":{"excludedEmbedMetadataKeys":[],"excludedInferenceMetadataKeys":[],"metadataSeparator":"\n","metadataTemplate":"{key}: {value}","textTemplate":"{metadata_string}\n\n{content}"},"formattedContent":"distance: 0.21754569\nvector_score: 0.21754569\n\nSpring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!","id":"8edf4d98-6730-4b19-8681-67bbd7aa002d","metadata":{"distance":0.21754569,"vector_score":0.21754569},"score":0.7824543118476868,"text":"Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!"},{"contentFormatter":{"$ref":"$[0].contentFormatter"},"formattedContent":"distance: 0.21754569\nvector_score: 0.21754569\n\nSpring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!","id":"dbdcc61f-7f7c-4c61-9491-aaf3ddb15ae9","metadata":{"distance":0.21754569,"vector_score":0.21754569},"score":0.7824543118476868,"text":"Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!"},{"contentFormatter":{"$ref":"$[0].contentFormatter"},"formattedContent":"distance: 0.2854656\nvector_score: 0.2854656\n\nThe World is Big and Salvation Lurks Around the Corner","id":"a28f2344-3389-427a-9a3d-69e3a1000a05","metadata":{"distance":0.2854656,"vector_score":0.2854656},"score":0.7145344018936157,"text":"The World is Big and Salvation Lurks Around the Corner"},{"contentFormatter":{"$ref":"$[0].contentFormatter"},"formattedContent":"distance: 0.2854656\nvector_score: 0.2854656\n\nThe World is Big and Salvation Lurks Around the Corner","id":"874aff9b-cd3d-41d9-9114-47157f3e4ccc","metadata":{"distance":0.2854656,"vector_score":0.2854656},"score":0.7145344018936157,"text":"The World is Big and Salvation Lurks Around the Corner"},{"contentFormatter":{"$ref":"$[0].contentFormatter"},"formattedContent":"distance: 0.2968012\nvector_score: 0.2968012\n\nYou walk forward facing the past and you turn back toward the future.","id":"c90a7824-dcdb-4855-ab07-0ac3629fba83","metadata":{"distance":0.2968012,"vector_score":0.2968012},"score":0.7031987905502319,"text":"You walk forward facing the past and you turn back toward the future."}]
org/springframework/ai/vectorstore/redis/autoconfigure/RedisVectorStoreAutoConfiguration.java
@AutoConfiguration(after = RedisAutoConfiguration.class)
@ConditionalOnClass({ JedisPooled.class, JedisConnectionFactory.class, RedisVectorStore.class, EmbeddingModel.class })
@ConditionalOnBean(JedisConnectionFactory.class)
@EnableConfigurationProperties(RedisVectorStoreProperties.class)
@ConditionalOnProperty(name = SpringAIVectorStoreTypes.TYPE, havingValue = SpringAIVectorStoreTypes.REDIS,
matchIfMissing = true)
public class RedisVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean(BatchingStrategy.class)
BatchingStrategy batchingStrategy() {
return new TokenCountBatchingStrategy();
}
@Bean
@ConditionalOnMissingBean
public RedisVectorStore vectorStore(EmbeddingModel embeddingModel, RedisVectorStoreProperties properties,
JedisConnectionFactory jedisConnectionFactory, ObjectProvider<ObservationRegistry> observationRegistry,
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
BatchingStrategy batchingStrategy) {
JedisPooled jedisPooled = this.jedisPooled(jedisConnectionFactory);
return RedisVectorStore.builder(jedisPooled, embeddingModel)
.initializeSchema(properties.isInitializeSchema())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(batchingStrategy)
.indexName(properties.getIndexName())
.prefix(properties.getPrefix())
.build();
}
private JedisPooled jedisPooled(JedisConnectionFactory jedisConnectionFactory) {
String host = jedisConnectionFactory.getHostName();
int port = jedisConnectionFactory.getPort();
JedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
.ssl(jedisConnectionFactory.isUseSsl())
.clientName(jedisConnectionFactory.getClientName())
.timeoutMillis(jedisConnectionFactory.getTimeout())
.password(jedisConnectionFactory.getPassword())
.build();
return new JedisPooled(new HostAndPort(host, port), clientConfig);
}
}
RedisVectorStoreAutoConfiguration在
spring.ai.vectorstore.type
为redis
时启用,它在RedisAutoConfiguration之后自动配置,它依赖EmbeddingModel及RedisVectorStoreProperties来创建RedisVectorStore
org/springframework/ai/vectorstore/redis/autoconfigure/RedisVectorStoreProperties.java
@ConfigurationProperties(RedisVectorStoreProperties.CONFIG_PREFIX)
public class RedisVectorStoreProperties extends CommonVectorStoreProperties {
public static final String CONFIG_PREFIX = "spring.ai.vectorstore.redis";
private String indexName = "default-index";
private String prefix = "default:";
public String getIndexName() {
return this.indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}
RedisVectorStoreProperties主要是配置
spring.ai.vectorstore.redis
配置,它从CommonVectorStoreProperties继承了initializeSchema属性,自己提供了indexName、prefix属性
org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(RedisConnectionDetails.class)
PropertiesRedisConnectionDetails redisConnectionDetails(RedisProperties properties) {
return new PropertiesRedisConnectionDetails(properties);
}
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
RedisAutoConfiguration依赖RedisProperties以及LettuceConnectionConfiguration或者JedisConnectionConfiguration
org/springframework/boot/autoconfigure/data/redis/RedisProperties.java
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedisProperties {
/**
* Database index used by the connection factory.
*/
private int database = 0;
/**
* Connection URL. Overrides host, port, username, and password. Example:
* redis://user:password@example.com:6379
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
/**
* Login username of the redis server.
*/
private String username;
/**
* Login password of the redis server.
*/
private String password;
/**
* Redis server port.
*/
private int port = 6379;
/**
* Read timeout.
*/
private Duration timeout;
/**
* Connection timeout.
*/
private Duration connectTimeout;
/**
* Client name to be set on connections with CLIENT SETNAME.
*/
private String clientName;
/**
* Type of client to use. By default, auto-detected according to the classpath.
*/
private ClientType clientType;
private Sentinel sentinel;
private Cluster cluster;
private final Ssl ssl = new Ssl();
private final Jedis jedis = new Jedis();
private final Lettuce lettuce = new Lettuce();
//......
}
RedisProperties主要是配置
spring.data.redis
,它提供了database、url、host、username、password、port、timeout、connectTimeout、clientName、clientType、sentinel、cluster、ssl、jedis、lettuce属性
Spring AI提供了spring-ai-starter-vector-store-redis用于自动装配RedisVectorStore。可以使用redis/redis-stack:latest
这个docker镜像来验证。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有