mcpField
Q
qdrant-vector-database-integration

qdrant-vector-database-integration

github.com/giuseppe-trisciuoglioデータ・データベース36568 回インストール7 週間前に更新
リポジトリ

qdrant-vector-database-integration について

Java アプリケーションに Qdrant のベクトル検索を統合するためのスキルガイドです。Spring Boot と LangChain4j のパターンを示し、コレクション管理、ベクトル操作、フィルター検索、RAG を扱います。

主な機能

  1. 01Java クライアントの設定
  2. 02コレクション管理
  3. 03ベクトル登録と類似検索
  4. 04Spring Boot 連携
  5. 05LangChain4j 埋め込みストア
  6. 06フィルター検索とマルチテナント検索

活用シーン

  1. 01Spring Boot へのセマンティック検索追加
  2. 02Java RAG パイプラインの構築
  3. 03フィルター付きベクトル検索の実装

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill qdrant-vector-database-integration

インストール後、Claude Code で/qdrant-vector-database-integrationを入力して読み込まれたか確認します。

同梱ファイルreferences/examples.mdreferences/references.md

詳細

Qdrant ベクトルデータベースの統合

概要

Qdrant は、セマンティック検索と類似検索のための AI ネイティブなベクトルデータベースです。このスキルでは、Java アプリケーションに Qdrant を統合するためのパターンを紹介し、Spring Boot との統合と LangChain4j フレームワークのサポートに重点を置いています。RAG システム、レコメンデーションエンジン、セマンティック検索アプリケーションで、効率的なベクトル検索機能を利用できます。

使用するタイミング

次の実装時にこのスキルを使用します:

  • Spring Boot アプリケーションでのセマンティック検索システムやレコメンデーションシステム
  • Java と LangChain4j を使用した検索拡張生成(RAG)パイプライン
  • AI および機械学習アプリケーション向けのベクトルデータベース統合
  • フィルター付きクエリによる高性能な類似検索
  • コンテキストを考慮したアプリケーション向けの埋め込みの保存と取得

はじめに:Qdrant のセットアップ

統合を始めるには、まず Qdrant インスタンスをデプロイします。

Docker を使用したローカル開発
# Pull the latest Qdrant image
docker pull qdrant/qdrant

# Run the Qdrant container
docker run -p 6333:6333 -p 6334:6334 \
    -v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
    qdrant/qdrant

次の方法で Qdrant にアクセスできます:

  • REST API:http://localhost:6333
  • gRPC API:http://localhost:6334(Java クライアントで使用)

Java クライアントの基本的な統合

ビルド設定に依存関係を追加し、プログラムからアクセスできるようにクライアントを初期化します。

依存関係の設定

Maven:

<dependency>
    <groupId>io.qdrant</groupId>
    <artifactId>client</artifactId>
    <version>1.15.0</version>
</dependency>

Gradle:

implementation 'io.qdrant:client:1.15.0'
クライアントの初期化

アプリケーションで使用する Qdrant クライアントを作成して設定します:

import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

// Basic local connection
QdrantClient client = new QdrantClient(
    QdrantGrpcClient.newBuilder("localhost").build());

// Secure connection with API key
QdrantClient secureClient = new QdrantClient(
    QdrantGrpcClient.newBuilder("localhost", 6334, false)
        .withApiKey("YOUR_API_KEY")
        .build());

// Managed connection with TLS
QdrantClient tlsClient = new QdrantClient(
    QdrantGrpcClient.newBuilder(channel)
        .withApiKey("YOUR_API_KEY")
        .build());

コレクション管理

適切な距離指標と次元数を指定して、ベクトルコレクションを作成、設定します。

コレクションの作成
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import java.util.concurrent.ExecutionException;

// Create a collection with cosine distance
client.createCollectionAsync("search-collection",
    VectorParams.newBuilder()
        .setDistance(Distance.Cosine)
        .setSize(384)
        .build()).get();

// Create collection with configuration
client.createCollectionAsync("recommendation-engine",
    VectorParams.newBuilder()
        .setDistance(Distance.Euclidean)
        .setSize(512)
        .build()).get();

ベクトル操作

アップサート、検索、フィルタリングなど、一般的なベクトル操作を実行します。

ポイントのアップサート
import io.qdrant.client.grpc.Points.PointStruct;
import java.util.List;
import java.util.Map;
import static io.qdrant.client.PointIdFactory.id;
import static io.qdrant.client.ValueFactory.value;
import static io.qdrant.client.VectorsFactory.vectors;

// Batch upsert vector points
List<PointStruct> points = List.of(
    PointStruct.newBuilder()
        .setId(id(1))
        .setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
        .putAllPayload(Map.of(
            "title", value("Spring Boot Documentation"),
            "content", value("Spring Boot framework documentation")
        ))
        .build(),
    PointStruct.newBuilder()
        .setId(id(2))
        .setVectors(vectors(0.19f, 0.81f, 0.75f, 0.11f))
        .putAllPayload(Map.of(
            "title", value("Qdrant Vector Database"),
            "content", value("Vector database for AI applications")
        ))
        .build()
);

client.upsertAsync("search-collection", points).get();
ベクトル検索
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.ScoredPoint;
import static io.qdrant.client.QueryFactory.nearest;
import java.util.List;

// Basic similarity search
List<ScoredPoint> results = client.queryAsync(
    QueryPoints.newBuilder()
        .setCollectionName("search-collection")
        .setLimit(5)
        .setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
        .build()
).get();

// Search with filters
List<ScoredPoint> filteredResults = client.searchAsync(
    SearchPoints.newBuilder()
        .setCollectionName("search-collection")
        .addAllVector(List.of(0.6235f, 0.123f, 0.532f, 0.123f))
        .setFilter(Filter.newBuilder()
            .addMust(range("rand_number",
                Range.newBuilder().setGte(3).build()))
            .build())
        .setLimit(5)
        .build()).get();

Spring Boot との統合

依存性注入と適切な設定を使用して、Qdrant を Spring Boot に統合します。

設定クラス
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);
    }
}
サービス層の実装
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.ExecutionException;

@Service
public class VectorSearchService {

    private final QdrantClient qdrantClient;

    public VectorSearchService(QdrantClient qdrantClient) {
        this.qdrantClient = qdrantClient;
    }

    public List<ScoredPoint> search(String collectionName, List<Float> queryVector) {
        try {
            return qdrantClient.queryAsync(
                QueryPoints.newBuilder()
                    .setCollectionName(collectionName)
                    .setLimit(5)
                    .setQuery(nearest(queryVector))
                    .build()
            ).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Qdrant search failed", e);
        }
    }

    public void upsertPoints(String collectionName, List<PointStruct> points) {
        try {
            qdrantClient.upsertAsync(collectionName, points).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Qdrant upsert failed", e);
        }
    }
}

LangChain4j との統合

LangChain4j を活用して、高水準のベクトルストア抽象化と RAG 実装を利用します。

依存関係の設定

Maven:

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-qdrant</artifactId>
    <version>1.7.0</version>
</dependency>
QdrantEmbeddingStore の設定
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.embedding.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Langchain4jConfig {

    @Bean
    public EmbeddingStore<TextSegment> embeddingStore() {
        return QdrantEmbeddingStore.builder()
            .collectionName("rag-collection")
            .host("localhost")
            .port(6334)
            .apiKey("YOUR_API_KEY")
            .build();
    }

    @Bean
    public EmbeddingModel embeddingModel() {
        return new AllMiniLmL6V2EmbeddingModel();
    }

    @Bean
    public EmbeddingStoreIngestor embeddingStoreIngestor(
            EmbeddingStore<TextSegment> embeddingStore,
            EmbeddingModel embeddingModel) {
        return EmbeddingStoreIngestor.builder()
            .embeddingStore(embeddingStore)
            .embeddingModel(embeddingModel)
            .build();
    }
}
RAG サービスの実装
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
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 {

    private final EmbeddingStoreIngestor ingestor;

    public RagService(EmbeddingStoreIngestor ingestor) {
        this.ingestor = ingestor;
    }

    public void ingestDocument(String text) {
        TextSegment segment = TextSegment.from(text);
        ingestor.ingest(segment);
    }

    public List<TextSegment> findRelevant(String query) {
        EmbeddingStore<TextSegment> embeddingStore = ingestor.getEmbeddingStore();
        return embeddingStore.findRelevant(
            ingestor.getEmbeddingModel().embed(query).content(),
            5,
            0.7
        ).stream()
            .map(match -> match.embedded())
            .toList();
    }
}

例

基本的な検索の実装
// Create simple search endpoint
@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) {
        // Convert query to embedding (requires embedding model)
        List<Float> queryVector = embeddingModel.embed(query).content().vectorAsList();
        return searchService.search("documents", queryVector);
    }
}

ベストプラクティス

ベクトルデータベースの設定
  • 適切な距離指標を使用します。テキストにはコサイン距離、数値データにはユークリッド距離を使用します
  • 埋め込みモデルの仕様に基づいて、ベクトルの次元数を最適化します
  • 適切なコレクション命名規則を設定します
  • パフォーマンスを監視し、検索パラメーターを最適化します
Spring Boot との統合
  • 依存性注入には常にコンストラクター注入を使用します
  • 適切な例外処理を行って非同期操作を処理します
  • 接続タイムアウトと再試行ポリシーを設定します
  • 本番環境向けに適切な Bean 設定を使用します
セキュリティに関する考慮事項
  • API キーをコードにハードコードしないでください
  • 環境変数または Spring の設定プロパティを使用します
  • 適切な認証と認可を実装します
  • 本番環境の接続には TLS を使用します
パフォーマンスの最適化
  • 大量のアップサートにはバッチ操作を使用します
  • 適切な上限値とフィルターを使用します
  • メモリー使用量と接続プーリングを監視します
  • 大規模なデータセットではシャーディングを検討します

高度なパターン

マルチテナントのベクトルストレージ
// Implement collection-based multi-tenancy
public class MultiTenantVectorService {
    private final QdrantClient client;

    public void upsertForTenant(String tenantId, List<PointStruct> points) {
        String collectionName = "tenant_" + tenantId + "_documents";
        client.upsertAsync(collectionName, points).get();
    }
}
フィルターを使用したハイブリッド検索
// Combine vector similarity with metadata filtering
public List<ScoredPoint> hybridSearch(String collectionName, List<Float> queryVector,
                                     String category, Date dateRange) {
    Filter filter = Filter.newBuilder()
        .addMust(range("created_at",
            Range.newBuilder().setGte(dateRange.getTime()).build()))
        .addMust(exactMatch("category", category))
        .build();

    return client.searchAsync(
        SearchPoints.newBuilder()
            .setCollectionName(collectionName)
            .addAllVector(queryVector)
            .setFilter(filter)
            .build()
    ).get();
}

参考資料

包括的な技術詳細と高度なパターンについては、次を参照してください:

コメント