Skip to content

Commit b3ba302

Browse files
codebase/using-oracle-vector-database-with-spring-ai [BAEL-9369] (#18719)
* add codebase skeleton * add codebase for semantic search * fix: startup failure: add logback configuration * add codebase for RAG * explicitely define embedding model * add environment variable precondition in live tests * explicitely define chat model * rename live test * fix: indentation * centralize testcontainer configuration * rename prompt file * minor grammatical fix
1 parent d9afc0c commit b3ba302

File tree

15 files changed

+485
-0
lines changed

15 files changed

+485
-0
lines changed

spring-ai-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<modules>
1919
<module>spring-ai-mcp</module>
2020
<module>spring-ai-text-to-sql</module>
21+
<module>spring-ai-vector-stores</module>
2122
</modules>
2223

2324
</project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>com.baeldung</groupId>
9+
<artifactId>spring-ai-modules</artifactId>
10+
<version>0.0.1</version>
11+
<relativePath>../pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>spring-ai-vector-stores</artifactId>
15+
<version>0.0.1</version>
16+
<packaging>pom</packaging>
17+
<name>spring-ai-vector-stores</name>
18+
19+
<modules>
20+
<module>spring-ai-oracle</module>
21+
</modules>
22+
23+
</project>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>com.baeldung</groupId>
8+
<artifactId>spring-ai-vector-stores</artifactId>
9+
<version>0.0.1</version>
10+
<relativePath>../pom.xml</relativePath>
11+
</parent>
12+
13+
<groupId>com.baeldung</groupId>
14+
<artifactId>spring-ai-oracle</artifactId>
15+
<version>0.0.1</version>
16+
<name>spring-ai-oracle</name>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-web</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.ai</groupId>
25+
<artifactId>spring-ai-starter-vector-store-oracle</artifactId>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.springframework.ai</groupId>
29+
<artifactId>spring-ai-advisors-vector-store</artifactId>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.springframework.ai</groupId>
33+
<artifactId>spring-ai-starter-model-openai</artifactId>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.springframework.boot</groupId>
37+
<artifactId>spring-boot-starter-test</artifactId>
38+
<scope>test</scope>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.springframework.ai</groupId>
42+
<artifactId>spring-ai-spring-boot-testcontainers</artifactId>
43+
<scope>test</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.testcontainers</groupId>
47+
<artifactId>oracle-free</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
</dependencies>
51+
52+
<properties>
53+
<java.version>21</java.version>
54+
<spring-ai.version>1.0.0</spring-ai.version>
55+
<spring-boot.version>3.5.4</spring-boot.version>
56+
</properties>
57+
58+
<build>
59+
<plugins>
60+
<plugin>
61+
<groupId>org.springframework.boot</groupId>
62+
<artifactId>spring-boot-maven-plugin</artifactId>
63+
</plugin>
64+
</plugins>
65+
</build>
66+
67+
<dependencyManagement>
68+
<dependencies>
69+
<dependency>
70+
<groupId>org.springframework.ai</groupId>
71+
<artifactId>spring-ai-bom</artifactId>
72+
<version>${spring-ai.version}</version>
73+
<type>pom</type>
74+
<scope>import</scope>
75+
</dependency>
76+
</dependencies>
77+
</dependencyManagement>
78+
79+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.baeldung.springai.vectorstore.oracle;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
class Application {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(Application.class, args);
11+
}
12+
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.baeldung.springai.vectorstore.oracle;
2+
3+
record Quote(String quote, String author) {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.baeldung.springai.vectorstore.oracle;
2+
3+
import org.springframework.core.ParameterizedTypeReference;
4+
import org.springframework.web.client.RestClient;
5+
6+
import java.net.URI;
7+
import java.util.List;
8+
9+
class QuoteFetcher {
10+
11+
private static final String BASE_URL = "https://api.breakingbadquotes.xyz/v1/quotes/";
12+
private static final int DEFAULT_COUNT = 150;
13+
14+
static List<Quote> fetch() {
15+
return fetch(DEFAULT_COUNT);
16+
}
17+
18+
static List<Quote> fetch(int count) {
19+
return RestClient
20+
.create()
21+
.get()
22+
.uri(URI.create(BASE_URL + count))
23+
.retrieve()
24+
.body(new ParameterizedTypeReference<>() {});
25+
}
26+
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.baeldung.springai.vectorstore.oracle;
2+
3+
import org.springframework.ai.chat.client.ChatClient;
4+
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
5+
import org.springframework.ai.chat.model.ChatModel;
6+
import org.springframework.ai.chat.prompt.PromptTemplate;
7+
import org.springframework.ai.template.st.StTemplateRenderer;
8+
import org.springframework.ai.vectorstore.SearchRequest;
9+
import org.springframework.ai.vectorstore.VectorStore;
10+
import org.springframework.beans.factory.annotation.Value;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.Configuration;
13+
import org.springframework.core.io.Resource;
14+
15+
import java.io.IOException;
16+
import java.nio.charset.StandardCharsets;
17+
18+
@Configuration
19+
class RAGChatbotConfiguration {
20+
21+
private static final int MAX_RESULTS = 10;
22+
23+
@Bean
24+
PromptTemplate promptTemplate(
25+
@Value("classpath:prompt-template.st") Resource promptTemplate
26+
) throws IOException {
27+
String template = promptTemplate.getContentAsString(StandardCharsets.UTF_8);
28+
return PromptTemplate
29+
.builder()
30+
.renderer(StTemplateRenderer
31+
.builder()
32+
.startDelimiterToken('<')
33+
.endDelimiterToken('>')
34+
.build())
35+
.template(template)
36+
.build();
37+
}
38+
39+
@Bean
40+
ChatClient chatClient(
41+
ChatModel chatModel,
42+
VectorStore vectorStore,
43+
PromptTemplate promptTemplate
44+
) {
45+
return ChatClient
46+
.builder(chatModel)
47+
.defaultAdvisors(
48+
QuestionAnswerAdvisor
49+
.builder(vectorStore)
50+
.promptTemplate(promptTemplate)
51+
.searchRequest(SearchRequest
52+
.builder()
53+
.topK(MAX_RESULTS)
54+
.build())
55+
.build()
56+
)
57+
.build();
58+
}
59+
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.baeldung.springai.vectorstore.oracle;
2+
3+
import org.springframework.ai.document.Document;
4+
import org.springframework.ai.vectorstore.VectorStore;
5+
import org.springframework.boot.ApplicationArguments;
6+
import org.springframework.boot.ApplicationRunner;
7+
import org.springframework.stereotype.Component;
8+
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
@Component
13+
class VectorStoreInitializer implements ApplicationRunner {
14+
15+
private final VectorStore vectorStore;
16+
17+
VectorStoreInitializer(VectorStore vectorStore) {
18+
this.vectorStore = vectorStore;
19+
}
20+
21+
@Override
22+
public void run(ApplicationArguments args) {
23+
List<Document> documents = QuoteFetcher
24+
.fetch()
25+
.stream()
26+
.map(quote -> {
27+
Map<String, Object> metadata = Map.of("author", quote.author());
28+
return new Document(quote.quote(), metadata);
29+
})
30+
.toList();
31+
vectorStore.add(documents);
32+
}
33+
34+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
spring:
2+
ai:
3+
vectorstore:
4+
oracle:
5+
initialize-schema: true
6+
openai:
7+
api-key: ${OPENAI_API_KEY}
8+
embedding:
9+
options:
10+
model: text-embedding-3-large
11+
chat:
12+
options:
13+
model: gpt-4o
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<configuration>
2+
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
3+
<encoder>
4+
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%p] [%c{1}] - %m%n</pattern>
5+
</encoder>
6+
</appender>
7+
8+
<root level="INFO">
9+
<appender-ref ref="CONSOLE" />
10+
</root>
11+
12+
<logger name="org.springframework" level="INFO" additivity="false">
13+
<appender-ref ref="CONSOLE" />
14+
</logger>
15+
</configuration>

0 commit comments

Comments
 (0)