ベクター検索エンジン比較:Qdrant vs Weaviate vs Milvus 2026年版でRAGを構築する
オープンソースラボ編集部 ・ 2026年6月14日
ベクター検索エンジン比較:Qdrant vs Weaviate vs Milvus 2026年版でRAGを構築する
LLMアプリケーションのRAG(Retrieval-Augmented Generation)・セマンティック検索・レコメンデーションシステムでは、テキストや画像をベクター埋め込み(Embedding)に変換して意味的な類似度検索を行うベクターデータベースが中核となります。Qdrant(Rust製・高速)・Weaviate(Go製・スキーマ型・GraphQL)・Milvus(Go/C++・大規模分散)の3つが2026年のOSSベクターDBデファクトスタンダードです。
ベクターデータベースを選ぶ理由
- 意味検索: キーワード一致ではなく「意味的に近い」文書を検索(「犬の散歩」→「ペットの運動」がヒット)
- RAG高精度化: LLMに渡す参照文書を関連性の高いものに絞って回答精度を向上
- マルチモーダル: テキスト・画像・音声を同じベクター空間で横断検索
- スケール: 数億ベクターを低レイテンシ(1〜10ms)で検索できる専用インデックス(HNSW)
主要ツールの概要
Qdrant
2021年公開、Rust製のOSSです。GitHubスター21k+。Rustの性能を活かした高速・メモリ効率に優れたベクターDBで、ペイロード(メタデータ)フィルタリング・スパース/デンスベクターのハイブリッド検索・量子化(Scalar・Product)をサポートします。
# docker-compose.yml - Qdrant
version: "3.8"
services:
qdrant:
image: qdrant/qdrant:v1.12.0
restart: unless-stopped
ports:
- "6333:6333" # HTTP/REST API
- "6334:6334" # gRPC API
volumes:
- qdrant_data:/qdrant/storage
environment:
QDRANT__SERVICE__API_KEY: ${QDRANT_API_KEY}
volumes:
qdrant_data:
# Python: Qdrant + LangChain でRAGパイプラインを構築
from qdrant_client import QdrantClient
from qdrant_client.models import (
VectorParams, Distance, PointStruct,
Filter, FieldCondition, MatchValue,
SearchRequest, SparseVector,
)
from langchain_anthropic import ChatAnthropic
from langchain.embeddings import OpenAIEmbeddings
import uuid
client = QdrantClient(url='http://localhost:6333', api_key='your-api-key')
embedder = OpenAIEmbeddings(model='text-embedding-3-large')
llm = ChatAnthropic(model='claude-sonnet-4-6')
COLLECTION_NAME = 'knowledge_base'
VECTOR_SIZE = 3072 # text-embedding-3-large の次元数
# コレクション作成(ハイブリッド検索対応)
client.recreate_collection(
collection_name=COLLECTION_NAME,
vectors_config=VectorParams(size=VECTOR_SIZE, distance=Distance.COSINE),
)
def index_documents(documents: list[dict]):
'''ドキュメントをベクター化してQdrantに保存'''
texts = [doc['content'] for doc in documents]
embeddings = embedder.embed_documents(texts)
points = [
PointStruct(
id=str(uuid.uuid4()),
vector=embedding,
payload={
'content': doc['content'],
'source': doc['source'],
'title': doc['title'],
'category': doc['category'],
}
)
for doc, embedding in zip(documents, embeddings)
]
client.upsert(collection_name=COLLECTION_NAME, points=points)
print(f'{len(points)}件のドキュメントをインデックス化')
def semantic_search(query: str, category: str = None, limit: int = 5) -> list[dict]:
'''意味的類似検索(カテゴリフィルタ付き)'''
query_vector = embedder.embed_query(query)
# ペイロードフィルター
search_filter = None
if category:
search_filter = Filter(
must=[FieldCondition(key='category', match=MatchValue(value=category))]
)
results = client.search(
collection_name=COLLECTION_NAME,
query_vector=query_vector,
query_filter=search_filter,
limit=limit,
with_payload=True,
score_threshold=0.7, # 類似度スコア閾値
)
return [
{'content': hit.payload['content'], 'score': hit.score, 'source': hit.payload['source']}
for hit in results
]
def rag_query(question: str) -> str:
'''RAGクエリ: 関連ドキュメントを検索してLLMで回答生成'''
# 1. ベクター検索で関連文書を取得
relevant_docs = semantic_search(question, limit=5)
context = '
'.join([f'[{i+1}] {doc["content"]}' for i, doc in enumerate(relevant_docs)])
# 2. LLMで回答を生成
prompt = f'''以下のコンテキストを参考に質問に答えてください。
コンテキスト:
{context}
質問: {question}
コンテキストに基づいて簡潔に回答してください。'''
response = llm.invoke(prompt)
return response.content
# 使用例
index_documents([
{'content': 'Qdrantは高速なRust製ベクターデータベースです...', 'source': 'docs/qdrant.md', 'title': 'Qdrant概要', 'category': 'tech'},
{'content': 'RAGはRetrieval-Augmented Generationの略で...', 'source': 'docs/rag.md', 'title': 'RAG入門', 'category': 'tech'},
])
answer = rag_query('ベクターデータベースとRAGの関係は?')
print(answer)
Weaviate
2019年公開、Go製のOSSです。GitHubスター12k+。スキーマ定義型・GraphQL API・BM25とベクター検索のハイブリッドが特徴のベクターDBです。モジュールシステム(text2vec-openai・text2vec-cohere・generative-openai)で埋め込み生成とLLM生成をWeaviate内で完結させられます。
# Weaviate: スキーマ定義とデータ投入
import weaviate
import weaviate.classes as wvc
client = weaviate.connect_to_local(
host='localhost',
port=8080,
grpc_port=50051,
)
# コレクション(クラス)を作成
documents = client.collections.create(
name='Document',
vectorizer_config=wvc.config.Configure.Vectorizer.text2vec_openai(
model='text-embedding-3-large',
),
generative_config=wvc.config.Configure.Generative.openai(model='gpt-4o'),
properties=[
wvc.config.Property(name='content', data_type=wvc.config.DataType.TEXT),
wvc.config.Property(name='source', data_type=wvc.config.DataType.TEXT),
wvc.config.Property(name='category', data_type=wvc.config.DataType.TEXT),
],
)
# ハイブリッド検索(BM25 + ベクター)
results = client.collections.get('Document').query.hybrid(
query='ベクターデータベース 検索',
alpha=0.5, # 0=BM25のみ、1=ベクターのみ、0.5=50/50
limit=5,
)
client.close()
Milvus
2019年公開、Go/C++製のOSSです。GitHubスター32k+。十億スケールのベクターを分散処理できる本格的なベクターDBで、Kubernetes上での分散クラスター構成・GPU対応・複数インデックス(IVF・HNSW・DiskANN)をサポートします。
# Milvus: コレクション作成と検索
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri='http://localhost:19530', token='root:Milvus')
schema = client.create_schema()
schema.add_field('id', DataType.INT64, is_primary=True, auto_id=True)
schema.add_field('content', DataType.VARCHAR, max_length=65535)
schema.add_field('embedding', DataType.FLOAT_VECTOR, dim=1536)
index_params = client.prepare_index_params()
index_params.add_index('embedding', index_type='IVF_FLAT', metric_type='COSINE', params={'nlist': 128})
client.create_collection('docs', schema=schema, index_params=index_params)
# 検索
results = client.search(
collection_name='docs',
data=[query_vector],
anns_field='embedding',
limit=10,
output_fields=['content'],
)
機能比較表
| 比較項目 | Qdrant | Weaviate | Milvus |
|---|---|---|---|
| 言語 | Rust | Go | Go/C++ |
| スケーラビリティ | 大 | 大 | 最大(10億+) |
| ハイブリッド検索 | ✅ | ✅ | ✅ |
| GraphQL API | ❌ | ✅ | ❌ |
| GPU対応 | △ | ❌ | ✅ |
| GitHub Stars | 21k+ | 12k+ | 32k+ |
ベクターデータベースはLLM Toolsカテゴリ/categories/llm-toolsのLangChain・LlamaIndex・OpenAI Embeddingsと統合してRAGシステムの中核を担います。DevOpsカテゴリ/categories/devopsのMinIO・S3にドキュメントを保存して、変更検知→再インデックス化のパイプラインをAirflowで自動化します。
FAQ
Q. Pinecone(商用SaaS)とQdrant/Weaviateを比較するとどうですか?
A. 管理コスト0・即日スタートならPinecone、コスト削減・セルフホスト・データ主権ならQdrant/Weaviateが向いています。コスト比較: Pinecone Starter無料枠は1インデックス・100万ベクターまで。それ以上は月$70〜(Standard)。Qdrantセルフホスト: VPS($20/月)でGB単位のベクター管理が可能。Weaviate Cloud: Sandboxは14日無料後有料。機能差: ①Pineconeはマルチテナント・メタデータフィルタリングが充実②QdrantはRust性能でPineconeとほぼ同等のレイテンシ③Weaviateはモジュールシステムでエンベッディング生成をまとめて管理。
Q. Qdrantのコレクションに大量ドキュメント(100万件+)を効率的にインデックス化するには?
A. バッチ処理(upload_collection)+ 並列エンベッディング生成で高速化します。①client.upload_collection(collection_name, vectors=embeddings_list, payload=payloads_list, batch_size=256)でバッチUpsert②エンベッディング生成はasyncioまたはconcurrent.futures.ThreadPoolExecutorでOpenAI APIを並列呼び出し(Rate limit内で並列度を調整)③大規模(10万+)は一時的にインデックス作成を停止(optimizers_config: {indexing_threshold: 0})してバルク投入後に再有効化④Qdrantのオンディスクペイロードインデックス(create_payload_index)でフィルタリングが高速になる。目安: 100万ベクター(dim=1536)をQdrantに投入するのに約30分(エンベッディング生成が主ボトルネック)。
Q. ハイブリッド検索(BM25+ベクター)はいつ使うべきですか?
A. 技術用語・固有名詞・型番などキーワード完全一致が重要な場合にハイブリッドが効果的です。ベクター検索のみの弱点: 「iPhone 15 Pro Max」→「最新スマートフォン」にマッチしてしまい、特定の製品番号や人名を正確に検索できない。ハイブリッド(BM25+ベクター): ①BM25がキーワードの完全一致・IDF重み付けを担当②ベクターが意味的類似度を担当③alphaパラメーターで重み調整(技術ドキュメント: alpha=0.3でBM25寄り、一般文書: alpha=0.7でベクター寄り)。Qdrantのハイブリッド実装: スパースベクター(sparse_vectorsフィールド)とデンスベクターを両方定義してquery_sparse_vectorsとquery_vectorを同時指定。
Q. RAGのチャンク分割はどのようにすべきですか?
A. チャンク戦略がRAGの精度に最も影響します。主要戦略: ①Fixed Size + Overlap: 512トークン単位でチャンク分割・50トークンオーバーラップ(最も一般的・Langchain RecursiveCharacterTextSplitter)②Semantic Chunking: 文の類似度が急変するポイントでチャンクを分割(langchain_experimental.text_splitter.SemanticChunker)③Document Structure: H1/H2/H3見出しの構造に合わせてチャンク分割(Markdown・HTMLドキュメント向け)④Small-to-Big: 小チャンク(128トークン)でベクター検索して、ヒットしたチャンクの周辺のより大きな文脈(512トークン)をLLMに渡す。実測値: 256〜512トークンのチャンクサイズが多くのユースケースでF1スコアが最も高くなります。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| RAG・高速検索・Rust性能・フィルタリング | Qdrant |
| GraphQL・モジュールシステム・スキーマ型 | Weaviate |
| 10億+スケール・GPU・分散クラスター | Milvus |