Jackie
Jackie

Reputation: 23477

How do I delete and recreate an index when using a Redis Vector Store with spring AI

I have a redis index that stores embeddings for a cache. I want to delete the index and recreate it to remove all of the existing embeddings. I try this like

@Service
public class CacheService {
    private final Logger logger = LoggerFactory.getLogger(CacheService.class);
    private final RedisVectorStore redisVectorStore;
    private final JedisPooled jedis;

    public CacheService(
            @Qualifier("customRedisVectorStore") VectorStore redisVectorStore
    ) {
        this.redisVectorStore = (RedisVectorStore) redisVectorStore;
        this.jedis = this.redisVectorStore.getJedis(); // RedisVectorStore provides access to JedisPooled
    }
    /**
     * Delete all documents from the vector store
     */
    public void deleteAll() {
        // Optionally drop and recreate the index
        try (Connection connection = jedis.getPool().getResource()) {
            if (connection.isConnected()) {
                connection.sendCommand(() -> SafeEncoder.encode("FT.DROPINDEX"), SafeEncoder.encode("spring-ai-example"), SafeEncoder.encode("DD"));
            } else{
                logger.warn("Connection is not connected");
            }
        } catch (Exception e) {
            // Index might not exist, that's okay
            logger.warn("Failed to drop index", e);
        }
    }

    public void createIndex() {
        IndexDefinition indexDefinition = new IndexDefinition()
                .setPrefixes("prefix:");
        Schema schema = new Schema()
                .addTextField("content", 1.0)
                .addVectorField("embedding", Schema.VectorField.VectorAlgo.HNSW, new HashMap<>() {{
                    put("TYPE", "FLOAT32");
                    put("DIM", 128); // Set the dimension of your vectors
                    put("DISTANCE_METRIC", "COSINE");
                }});
        jedis.ftCreate("spring-ai-example", IndexOptions.defaultOptions().setDefinition(indexDefinition), schema);
        logger.debug("Index created");
    }

    /**
     * Delete all documents and recreate the index
     */
    public void deleteAllAndRecreateIndex() {
        deleteAll();
        createIndex();
        try {
            redisVectorStore.afterPropertiesSet();
        }
        catch (Exception e) {
            throw new RuntimeException("Failed to recreate index", e);
        }
    }
}

However, when it gets to redisVectorStore.afterPropertiesSet(); it fails with

java.lang.ClassCastException: class [B cannot be cast to class java.util.List ([B and java.util.List are in module java.base of loader 'bootstrap')
    at redis.clients.jedis.BuilderFactory$19.build(BuilderFactory.java:284) ~[jedis-5.0.2.jar:na]
    at redis.clients.jedis.BuilderFactory$19.build(BuilderFactory.java:279) ~[jedis-5.0.2.jar:na]
    at redis.clients.jedis.Connection.executeCommand(Connection.java:138) ~[jedis-5.0.2.jar:na]
    at redis.clients.jedis.executors.DefaultCommandExecutor.executeCommand(DefaultCommandExecutor.java:24) ~[jedis-5.0.2.jar:na]
    at redis.clients.jedis.UnifiedJedis.executeCommand(UnifiedJedis.java:244) ~[jedis-5.0.2.jar:na]
    at redis.clients.jedis.UnifiedJedis.ftList(UnifiedJedis.java:3883) ~[jedis-5.0.2.jar:na]
    at org.springframework.ai.vectorstore.RedisVectorStore.afterPropertiesSet(RedisVectorStore.java:428) ~[spring-ai-redis-store-1.0.0-M3.jar:1.0.0-M3]
    at org.example.service.CacheService.deleteAllAndRecreateIndex(CacheService.java:79) ~[main/:na]
    at org.example.controller.CacheController.deleteAll(CacheController.java:21) ~[main/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.13.jar:6.1.13]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:936) ~[spring-webmvc-6.1.13.jar:6.1.13]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:596) ~[tomcat-embed-core-10.1.30.jar:6.0]

I think it is because the VectorStore is out of sync is there a better way to do this?

Upvotes: 0

Views: 62

Answers (0)

Related Questions