Spring AI with Pinecone Vector Database: Spring Boot Integration Guide

Explanation of the Component Diagram

  1. User & Postman

    • The user interacts with the Spring Boot API using Postman to test API requests.
  2. Spring Boot API Layer

    • The request first hits the VectorController, which handles API endpoints for storing and searching vectors.
    • The VectorService processes the request, embedding text into vectors using Spring AI.
  3. AI & Vector Processing

    • Spring AI generates embeddings (vector representations of text).
    • It then interacts with Pinecone Vector Database to store or retrieve vectorized data.
  4. Response Flow

    • Pinecone returns search results to Spring AI.
    • The response propagates back through VectorService → VectorController → Postman, where the user sees the JSON response.


Here's a Spring Boot guide that integrates Spring AI with Pinecone Vector Database, covering:

Spring Boot setup
Spring AI & Pinecone integration
Storing text embeddings with metadata
Advanced retrieval using filtering
Complete REST API for insertion & retrieval


1. Create a Spring Boot Project

Use Spring Initializr (start.spring.io) and select:
Spring Boot Starter Web
Pinecone Vector Database (Spring AI vector database support for Pinecone.)


2. Complete pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<properties>
		<java.version>17</java.version>
		<spring-ai.version>1.0.0-M5</spring-ai.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-pinecone-store-spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.ai</groupId>
				<artifactId>spring-ai-bom</artifactId>
				<version>${spring-ai.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

</project>

3. Configure Pinecone in application.yml

Create an account at Pinecone and get your API key.

spring:
  ai:
    vectorstore:
      pinecone:
        api-key: YOUR_PINECONE_API_KEY
        environment: us-west4-gcp  # Change as per your region
        project: YOUR_PROJECT_NAME
        index: YOUR_INDEX_NAME

4. Implement Vector Store Service

This service will:
Store embeddings in Pinecone with metadata
Perform semantic searches with filtering

import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.VectorStore.SearchResult;
import org.springframework.ai.vectorstore.metadata.FilterExpression;
import org.springframework.ai.vectorstore.metadata.Metadata;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class VectorService {

    private final VectorStore vectorStore;
    private final EmbeddingClient embeddingClient;

    public VectorService(VectorStore vectorStore, EmbeddingClient embeddingClient) {
        this.vectorStore = vectorStore;
        this.embeddingClient = embeddingClient;
    }

    /**
     * Stores text embeddings along with metadata in Pinecone.
     */
    public void storeText(String id, String text, Map<String, Object> metadata) {
        List<Double> embedding = embeddingClient.embed(text).get(0);
        Metadata meta = Metadata.from(metadata);
        vectorStore.add(id, embedding, text, meta);
    }

    /**
     * Searches for similar vectors using embeddings and metadata filtering.
     */
    public List<SearchResult> search(String query, Map<String, Object> filters) {
        List<Double> queryEmbedding = embeddingClient.embed(query).get(0);
        FilterExpression filterExpression = FilterExpression.from(filters);
        return vectorStore.similaritySearch(queryEmbedding, 5, filterExpression);
    }
}

5. Create REST API Controller

This controller:
Accepts JSON payloads for insertion & retrieval
Supports metadata-based search filtering

import com.example.springai.service.VectorService;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/vectors")
public class VectorController {

    private final VectorService vectorService;

    public VectorController(VectorService vectorService) {
        this.vectorService = vectorService;
    }

    /**
     * Stores a document in Pinecone with metadata.
     */
    @PostMapping("/store")
    public String store(@RequestBody Map<String, Object> payload) {
        String id = (String) payload.get("id");
        String text = (String) payload.get("text");
        Map<String, Object> metadata = (Map<String, Object>) payload.get("metadata");

        if (id == null || text == null) {
            return "Error: 'id' and 'text' are required fields.";
        }

        vectorService.storeText(id, text, metadata);
        return "Document stored successfully!";
    }

    /**
     * Searches for similar vectors with optional metadata filtering.
     */
    @PostMapping("/search")
    public List<VectorStore.SearchResult> search(@RequestBody Map<String, Object> payload) {
        String query = (String) payload.get("query");
        Map<String, Object> filters = (Map<String, Object>) payload.get("filters");

        if (query == null) {
            throw new IllegalArgumentException("Query parameter is required");
        }

        return vectorService.search(query, filters);
    }
}

6. Run the Spring Boot Application

mvn spring-boot:run

7. Test the APIs Using Postman or cURL

Store a document with metadata

curl -X POST "http://localhost:8080/api/vectors/store" \
     -H "Content-Type: application/json" \
     -d '{
          "id": "doc_1",
          "text": "Spring Boot is a powerful Java framework.",
          "metadata": {
              "author": "John Doe",
              "category": "Java",
              "year": 2024
          }
        }'

Search with metadata filtering

curl -X POST "http://localhost:8080/api/vectors/search" \
     -H "Content-Type: application/json" \
     -d '{
          "query": "Java frameworks",
          "filters": {
              "category": "Java",
              "year": 2024
          }
        }'

8. Expected API Response

[
    {
        "id": "doc_1",
        "score": 0.98,
        "text": "Spring Boot is a powerful Java framework.",
        "metadata": {
            "author": "John Doe",
            "category": "Java",
            "year": 2024
        }
    }
]

9. Bonus: Enhancements for Production

Exception Handling: Add global exception handling using @ControllerAdvice
Logging: Use @Slf4j for logging requests & responses
Security: Protect endpoints with API keys or OAuth
Pagination: Add pagination for large-scale retrieval


🎯 Conclusion

You've built a Spring Boot AI-powered app with:
Pinecone Vector Database integration
Spring AI-powered text embeddings
Advanced metadata-based search 🚀


To access the source code or download the project, visit the GitHub repository:

🔗 GitHub - Spring AI Demo Project

Feel free to clone or fork the repository to get started quickly!

Comments

Popular posts from this blog

Spring Boot OpenAI Integration: Step-by-Step Guide

Orchestration-Based Saga Architecture and Spring Boot Microservices Implementation Guide

Spring Boot 3 + Angular 15 + Material - Full Stack CRUD Application Example