后端开发

なぜベクトルデータベースが注目されているのか

2026年、キーワード検索からセマンティック検索へのパラダイムシフトが、検索技術スタック全体を再構築しています。

キーワード検索:「りんご」で検索 → 「りんご」を含む文書のみマッチ セマンティック検索:「りんご」で検索 → 「iPhone」「MacBook」「果物の栄養」も理解

この能力の飛躍は**Embedding(ベクトル埋め込み)**に由来します。


Embeddingモデルの選択

モデル 次元 最大Token 多言語 オープンソース MTEB順位
OpenAI text-embedding-3-large 3072 8191 Top 5
OpenAI text-embedding-3-small 1536 8191 Top 15
BGE-M3 1024 8192 Top 10
Cohere embed-v4 1024 128000 Top 8
GTE-Qwen2 1536 32768 Top 3

選択ガイド

精度重視 + GPU利用可能 → GTE-Qwen2 / E5-Mistral-7B
コスパ重視 + 迅速なローンチ → OpenAI text-embedding-3-small
中国語中心 + オープンソース → BGE-M3 / GTE-Qwen2
長文書 → Cohere embed-v4
多言語 + ハイブリッド検索 → BGE-M3

ベクトルデータベース比較

特徴 Milvus pgvector Qdrant Weaviate Chroma
タイプ 専用 PG拡張 専用 専用 組み込み
インデックス HNSW, IVF_PQ, Flat, SCANN HNSW, IVFFlat HNSW HNSW HNSW
水平スケール ✅ ネイティブ
ハイブリッド検索 ✅ (SQL)
ACIDトランザクション

選び方

PostgreSQL既存 → pgvector 1億ベクトル以上 → Milvus 中規模 + Rust性能 → Qdrant プロトタイプ → Chroma


Spring Boot + pgvector実装

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    title VARCHAR(500) NOT NULL,
    content TEXT NOT NULL,
    source VARCHAR(200),
    embedding vector(1536),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_documents_embedding ON documents
    USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 64);

ベクトル検索リポジトリ

@Repository
public class DocumentVectorRepository {

    private final JdbcTemplate jdbcTemplate;

    public List<DocumentSearchResult> searchSimilar(float[] queryEmbedding, int limit) {
        String vectorStr = Arrays.stream(queryEmbedding)
            .mapToObj(f -> String.format("%.6f", f))
            .collect(Collectors.joining(",", "[", "]"));

        String sql = """
            SELECT id, title, content, source,
                   1 - (embedding <=> ?::vector) AS similarity
            FROM documents
            WHERE embedding IS NOT NULL
            ORDER BY embedding <=> ?::vector
            LIMIT ?
            """;

        return jdbcTemplate.query(sql,
            (rs, rowNum) -> new DocumentSearchResult(
                rs.getLong("id"), rs.getString("title"),
                rs.getString("content"), rs.getString("source"),
                rs.getDouble("similarity")
            ),
            vectorStr, vectorStr, limit
        );
    }
}

インデックスタイプ:HNSW、IVF_PQ、Flat

タイプ 検索速度 リコール メモリ ユースケース
Flat 遅い 100% <10万、精度優先
HNSW 速い 高(>95%) 10万-1000万、汎用
IVF_PQ 速い 中(85-95%) 1億+、メモリ制約
SCANN 最速 Milvus専用

ハイブリッド検索:ベクトル + BM25

ユーザークエリ
    ├──→ Embedding → ベクトル検索 → セマンティック結果
    ├──→ トークン化 → BM25検索 → キーワード結果
    └──→ RRF融合 → 最終ランキング

RRF(Reciprocal Rank Fusion)

public List<DocumentSearchResult> hybridSearch(String query, int limit) {
    float[] embedding = embeddingService.generateEmbedding(query);

    List<DocumentSearchResult> vectorResults = vectorRepository.searchSimilar(embedding, 50);
    List<DocumentSearchResult> keywordResults = fulltextRepository.search(query, 50);

    Map<Long, Double> rrfScores = new HashMap<>();
    int k = 60;

    for (int i = 0; i < vectorResults.size(); i++) {
        rrfScores.merge(vectorResults.get(i).getId(), 1.0 / (k + i + 1), Double::sum);
    }

    for (int i = 0; i < keywordResults.size(); i++) {
        rrfScores.merge(keywordResults.get(i).getId(), 1.0 / (k + i + 1), Double::sum);
    }

    return rrfScores.entrySet().stream()
        .sorted(Map.Entry.<Long, Double>comparingByValue().reversed())
        .limit(limit)
        .collect(Collectors.toList());
}

リランク

モデル レイテンシ 精度向上 オープンソース
Cohere Rerank ~100ms +15-25%
bge-reranker-v2-m3 ~50ms +10-20%
Jina Reranker ~80ms +10-15%

典型的な流れ:ベクトル検索 Top 50 → リランク → Top 10を返却。精度15-25%向上。


コスト分析:自構築 vs クラウド

規模 自構築Milvus Zilliz Cloud Pinecone pgvector
100万×1536d ~$50/月 ~$65/月 ~$70/月 ~$30/月
1000万×1536d ~$200/月 ~$300/月 ~$350/月 ~$150/月
運用コスト なし なし

推奨:PostgreSQL既存ならpgvectorで開始、日次ベクトル追加が10万を超えたらMilvusまたはZilliz Cloudを検討。


まとめ

キーワードからセマンティクスへのパラダイムシフトは、「文字列のマッチング」から「意図の理解」へのアップグレードである。

ブラウザローカルツールを無料で試す →

#向量数据库#语义搜索#Embedding#Milvus#pgvector