Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
82
82%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
This file provides comprehensive code examples for integrating Qdrant with Java and Spring Boot applications.
This example demonstrates a full Spring Boot application with Qdrant integration for vector search.
/src/main/java/com/example/qdrantdemo/
├── QdrantDemoApplication.java
├── config/
│ ├── QdrantConfig.java
│ └── Langchain4jConfig.java
├── controller/
│ ├── SearchController.java
│ └── RagController.java
├── service/
│ ├── VectorSearchService.java
│ └── RagService.java
└── Application.properties<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Qdrant Java Client -->
<dependency>
<groupId>io.qdrant</groupId>
<artifactId>client</artifactId>
<version>1.15.0</version>
</dependency>
<!-- LangChain4j -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-all-minilm-l6-v2</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies># Qdrant Configuration
qdrant.host=localhost
qdrant.port=6334
qdrant.api-key=
# OpenAI Configuration (for RAG)
openai.api-key=YOUR_OPENAI_API_KEYpackage com.example.qdrantdemo.config;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QdrantConfig {
@Value("${qdrant.host:localhost}")
private String host;
@Value("${qdrant.port:6334}")
private int port;
@Value("${qdrant.api-key:}")
private String apiKey;
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient grpcClient = QdrantGrpcClient.newBuilder(host, port, false)
.withApiKey(apiKey)
.build();
return new QdrantClient(grpcClient);
}
}package com.example.qdrantdemo.service;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Points.PointStruct;
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.ScoredPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static io.qdrant.client.PointIdFactory.id;
import static io.qdrant.client.ValueFactory.value;
import static io.qdrant.client.VectorsFactory.vectors;
import static io.qdrant.client.QueryFactory.nearest;
@Service
public class VectorSearchService {
private final QdrantClient client;
@Autowired
private EmbeddingService embeddingService; // Helper service for embeddings
public static final String COLLECTION_NAME = "document-search";
public static final int VECTOR_SIZE = 384; // For AllMiniLM-L6-v2
public VectorSearchService(QdrantClient client) {
this.client = client;
}
@PostConstruct
public void initializeCollection() throws ExecutionException, InterruptedException {
// Create collection if it doesn't exist
client.createCollectionAsync(COLLECTION_NAME,
VectorParams.newBuilder()
.setDistance(Distance.Cosine)
.setSize(VECTOR_SIZE)
.build()
).get();
}
public List<ScoredPoint> search(String query, int limit) {
try {
List<Float> queryVector = embeddingService.embedQuery(query);
return client.queryAsync(
QueryPoints.newBuilder()
.setCollectionName(COLLECTION_NAME)
.setLimit(limit)
.setQuery(nearest(queryVector))
.setWithPayload(true)
.build()
).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant search failed", e);
}
}
public void addDocument(String documentId, String title, String content) {
try {
List<Float> contentVector = embeddingService.embedText(content);
PointStruct point = PointStruct.newBuilder()
.setId(id(documentId))
.setVectors(vectors(contentVector))
.putAllPayload(Map.of(
"title", value(title),
"content", value(content),
"created_at", value(System.currentTimeMillis())
))
.build();
client.upsertAsync(COLLECTION_NAME, List.of(point)).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant document insertion failed", e);
}
}
}package com.example.qdrantdemo.controller;
import com.example.qdrantdemo.service.VectorSearchService;
import io.qdrant.client.grpc.Points.ScoredPoint;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/search")
public class SearchController {
private final VectorSearchService searchService;
public SearchController(VectorSearchService searchService) {
this.searchService = searchService;
}
@GetMapping
public List<ScoredPoint> search(@RequestParam String query,
@RequestParam(defaultValue = "5") int limit) {
return searchService.search(query, limit);
}
@PostMapping("/document")
public String addDocument(@RequestBody AddDocumentRequest request) {
searchService.addDocument(request.getDocumentId(), request.getTitle(), request.getContent());
return "Document added successfully";
}
public static class AddDocumentRequest {
private String documentId;
private String title;
private String content;
// Getters and setters
public String getDocumentId() { return documentId; }
public void setDocumentId(String documentId) { this.documentId = documentId; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
}
}This example demonstrates a complete RAG system with Qdrant and LLM integration.
package com.example.qdrantdemo.config;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.embedding.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Langchain4jConfig {
@Value("${qdrant.host:localhost}")
private String host;
@Value("${qdrant.port:6334}")
private int port;
@Value("${qdrant.api-key:}")
private String apiKey;
@Value("${openai.api-key}")
private String openaiApiKey;
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return QdrantEmbeddingStore.builder()
.collectionName("rag-collection")
.host(host)
.port(port)
.apiKey(apiKey)
.build();
}
@Bean
public EmbeddingModel embeddingModel() {
return new AllMiniLmL6V2EmbeddingModel();
}
@Bean
public ChatLanguageModel chatLanguageModel() {
return OpenAiChatModel.builder()
.apiKey(openaiApiKey)
.modelName("gpt-3.5-turbo")
.build();
}
@Bean
public EmbeddingStoreIngestor embeddingStoreIngestor(
EmbeddingStore<TextSegment> embeddingStore,
EmbeddingModel embeddingModel) {
return EmbeddingStoreIngestor.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.build();
}
}package com.example.qdrantdemo.service;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RagService {
// Define the AI assistant interface
interface Assistant {
String chat(String userMessage);
}
private final EmbeddingStoreIngestor ingestor;
private final Assistant assistant;
public RagService(EmbeddingStore<TextSegment> embeddingStore,
EmbeddingStoreIngestor ingestor,
ChatLanguageModel chatModel) {
this.ingestor = ingestor;
// Create content retriever for RAG
ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.maxResults(3)
.minScore(0.7)
.build();
// Build the AI assistant with RAG capabilities
this.assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(chatModel)
.contentRetriever(contentRetriever)
.build();
}
public void ingestDocument(String text) {
TextSegment segment = TextSegment.from(text);
ingestor.ingest(segment);
}
public String query(String userQuery) {
return assistant.chat(userQuery);
}
public List<TextSegment> findRelevantDocuments(String query, int maxResults) {
EmbeddingStore<TextSegment> embeddingStore = ingestor.getEmbeddingStore();
return embeddingStore.findRelevant(
ingestor.getEmbeddingModel().embed(query).content(),
maxResults,
0.7
).stream()
.map(match -> match.embedded())
.toList();
}
}package com.example.qdrantdemo.controller;
import com.example.qdrantdemo.service.RagService;
import dev.langchain4j.data.segment.TextSegment;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/rag")
public class RagController {
private final RagService ragService;
public RagController(RagService ragService) {
this.ragService = ragService;
}
@PostMapping("/ingest")
public String ingestDocument(@RequestBody String document) {
ragService.ingestDocument(document);
return "Document ingested successfully.";
}
@PostMapping("/query")
public String query(@RequestBody QueryRequest request) {
return ragService.query(request.getQuery());
}
@GetMapping("/documents")
public List<TextSegment> findDocuments(@RequestParam String query,
@RequestParam(defaultValue = "3") int maxResults) {
return ragService.findRelevantDocuments(query, maxResults);
}
public static class QueryRequest {
private String query;
public String getQuery() { return query; }
public void setQuery(String query) { this.query = query; }
}
}This example demonstrates advanced patterns for multi-tenant applications.
package com.example.qdrantdemo.service;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Points.PointStruct;
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.ScoredPoint;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class MultiTenantVectorService {
private final QdrantClient client;
public MultiTenantVectorService(QdrantClient client) {
this.client = client;
}
// Collection-based multi-tenancy
public List<ScoredPoint> searchByTenant(String tenantId, List<Float> queryVector, int limit) {
try {
String collectionName = "tenant_" + tenantId + "_documents";
return client.queryAsync(
QueryPoints.newBuilder()
.setCollectionName(collectionName)
.setLimit(limit)
.addAllVector(queryVector)
.setWithPayload(true)
.build()
).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Multi-tenant search failed", e);
}
}
public void upsertForTenant(String tenantId, List<PointStruct> points) {
try {
String collectionName = "tenant_" + tenantId + "_documents";
client.upsertAsync(collectionName, points).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Multi-tenant upsert failed", e);
}
}
// Hybrid search with tenant-specific filters
public List<ScoredPoint> hybridSearch(String tenantId, List<Float> queryVector,
String category, int limit) {
try {
String collectionName = "tenant_" + tenantId + "_documents";
QueryPoints.Builder queryBuilder = QueryPoints.newBuilder()
.setCollectionName(collectionName)
.setLimit(limit)
.addAllVector(queryVector);
// Add category filter if provided
if (category != null && !category.isEmpty()) {
queryBuilder.setFilter(Filter.newBuilder()
.addMust(exactMatch("category", category))
.build());
}
return client.queryAsync(queryBuilder.build()).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Hybrid search failed", e);
}
}
}version: '3.8'
services:
qdrant:
image: qdrant/qdrant:v1.7.0
ports:
- "6333:6333"
- "6334:6334"
volumes:
- qdrant_storage:/qdrant/storage
environment:
- QDRANT__SERVICE__HTTP_PORT=6333
- QDRANT__SERVICE__GRPC_PORT=6334
volumes:
qdrant_storage:# application-prod.properties
qdrant.host=qdrant-service
qdrant.port=6334
qdrant.api-key=${QDRANT_API_KEY}
# Enable HTTPS for production
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=${SSL_KEYSTORE_PASSWORD}
# OpenAI Configuration
openai.api-key=${OPENAI_API_KEY}
# Logging
logging.level.com.example.qdrantdemo=INFO
logging.level.io.qdrant=INFOimport org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
public class VectorSearchServiceTest {
@Autowired
private VectorSearchService vectorSearchService;
@Test
public void testCollectionInitialization() {
// Test that collection is created properly
// This could involve checking collection metadata
}
@Test
public void testDocumentUpsert() {
// Test document insertion and retrieval
}
@Test
public void testSearchFunctionality() {
// Test vector search functionality
}
}This comprehensive example provides a complete foundation for building Qdrant-powered applications with Spring Boot and LangChain4j.
plugins
developer-kit-ai
skills
chunking-strategy
prompt-engineering
developer-kit-aws
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
references
aws-cloudformation-bedrock
references
aws-cloudformation-cloudfront
references
aws-cloudformation-cloudwatch
references
aws-cloudformation-dynamodb
references
aws-cloudformation-ec2
aws-cloudformation-ecs
references
aws-cloudformation-elasticache
aws-cloudformation-iam
references
aws-cloudformation-lambda
references
aws-cloudformation-rds
aws-cloudformation-s3
references
aws-cloudformation-security
references
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
developer-kit-core
skills
developer-kit-java
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
graalvm-native-image
langchain4j
langchain4j-mcp-server-patterns
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
references
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
unit-test-controller-layer
unit-test-exception-handler
unit-test-json-serialization
unit-test-mapper-converter
unit-test-parameterized
unit-test-scheduled-async
unit-test-service-layer
unit-test-utility-methods
unit-test-wiremock-rest-api
developer-kit-php
skills
aws-lambda-php-integration
developer-kit-python
skills
aws-lambda-python-integration
developer-kit-tools
developer-kit-typescript
skills
aws-lambda-typescript-integration
better-auth
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
scripts
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
references
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
references
shadcn-ui
tailwind-css-patterns
references
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities