1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【クラウド型ベクトルDB】Pineconeってなにもの?色々調べながら使ってみた

1
Last updated at Posted at 2026-02-07

Pineconeとは

Pineconeとはフルマネージドなクラウド型のベクトルデータベースです。
ローカル管理は不要でDB作成、拡張、削除など全て提供されるAPIで実施することができます。
クラウド型のベクトルDBには他にもたくさん存在しますが、Pineconeは商用実績が豊富、導入が楽、無料枠があるため検証にはもってこいだと思います。

他のクラウド型ベクトルDB代表例
・Qdrant
・Upstash
・Zilliz Cloud
・Cloudflare Vectorize
ちなみに読み方は ピンコーン パインコーン です。

Pineconeはどういう仕組みなのか

Pineconeの仕組みについて簡単に図にまとめました。
image.png
それぞれの概念について以下で説明していきます。

アカウント管理

Organization

Pineconeアカウントの最上位単位。
Organization単位で課金が発生する。
通常利用において意識することはない。

Project

Organization内に作成できるグループ。
APIキーの発行やIndex管理はProject単位で行う。
検証環境、性能環境、本番環境といった使い分けでの利用が想定される。

Index管理

Index

ベクトルデータを格納、検索する基本単位。
セマンティック検索やキーワード検索、データ永続化を行う。

セマンティック検索 : ニュアンスや文脈を理解した上で最適な情報を検索すること

無料枠で作成できるIndex数は1つのみ。

Index作成において以下のような設定が可能。
spec
設定例: Serverless, Pod-based

  • Serverless
    従量課金型。
    自動スケーリング可能で、Read/Write単位で課金が発生する。
  • Pod-based
    専用のコンピューティングリソース。
    自動スケーリングはせずキャパシティ固定。
    Index作成時にはType,Size,Replicasを設定する。
    • Replicas : Podの複製数。複製数を増やすことでスループットや可用性が向上する。
      読み込みスループットが向上するだけで書き込むSpecが増えるわけではない。
Type 詳細
s1 Storage優先。大量データや低頻度のクエリ実行の場合に適する。
p1 パフォーマンス優先。高頻度のクエリ実行、低レイテンシが求められる場合に的する。
p2 s1,p1を超える性能。
Size 詳細
x1 基本の容量サイズ
x2 基本の2倍の容量サイズ
x4 基本の4倍の容量サイズ
x8 基本の8倍の容量サイズ

demension
設定例: 1536
Indexに保存するベクトルの次元数。
利用する埋め込み(Embedding)モデルの次元数に合わせる必要がある。

metric
設定例: cosine, euclidean, dotproduct

項目 詳細
cosine (コサイン類似度) ベクトルの向きによる類似性を測定する必要がある場合に使用。文書や単語などの類似性測定に有用。
euclidean (ユークリッド距離) ベクトル間の物理的距離を測定する必要がある場合に使用。画像や音声などの類似性測定に有効。
dotproduct (ドット積) ベクトルの向きと大きさによる類似性を測定する必要がある場合に使用。
# Serverless Index作成例
c.create_index(
    name="my-index",
    dimension=1536,
    metric="cosine",
    spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# Pod-based Index作成例
pc.create_index(
    name="my-index",
    dimension=1536,
    metric="cosine",
    spec=PodSpec(
        environment="us-east-1-aws",
        pod_type="p1.x1",
        pods=1,
        replicas=2
    )
)

データ管理

namespace

Index内の論理的なパーティション。
任意項目(デフォルトは""が設定される)。
Index内でデータ分離を行うことで、迅速な検索やデータ更新を可能にする。

# Namespace別にデータを格納
index.upsert(vectors=[...], namespace="user_123")
index.upsert(vectors=[...], namespace="user_456")

vector

Pineconeに格納される最小単位のデータ。
チャンクに分割した際には、1チャンク = 1vectorになるイメージ。
vectorの構成要素:id, values, metadata, sparse_values
metadata
ベクトルデータに付随するデータ。
フィルタリング検索や補足情報の追加などで活用される。

# メタデータでフィルタリング
index.query(
    vector=[...],
    filter={
        "category": {"$eq": "programming"},
        "year": {"$gte": 2020}
    },
    top_k=10
)

sparse_values
ハイブリッド検索(意味検索 + キーワード検索)を実現するために、キーワード情報を格納するための引数。

  • 概要
    ベクトル検索は通常、プロンプトの「意味」を数値化した密ベクトル(Dense Vector)検索なのに対して、Sparse Vectorはキーワードの頻出度や重要度を数値化した疎ベクトルを指す。
ベクトル 強み・弱み
密ベクトル セマンティック検索
強み:同じニュアンスや意味を読み取ること
弱み:「iOS 18.1」のような固有名詞の完全一致検索
疎ベクトル キーワード検索
強み:キーワードが含まれているか、一致するか厳密に判定すること
弱み:セマンティック検索ができない

sparse_valuesを設定することでセマンティック検索、キーワード検索どちらも考慮した上で最適な検索が可能になる。

その他

Collection

Indexの静的スナップショット。
Indexのバックアップを取りたい時(設定変更時やDR対策)に利用する。
バックアップに特化しているため、Collectionに対して検索やデータ登録はできない。

Collectionは有料枠でしか利用できない。

導入手順

インストール

pip install pinecone-client

アカウント作成
以下の公式アカウントからアカウント作成する。

APIキーの設定
アカウント作成した後に「Generate API Key」を押下してAPIキーを発行する。
image.png

実際に実装してみる

Indexを作成する

Indexは実装だけでなく、PineconeのGUIから作成することも可能です。
GUIから作成する場合は「Create index」を押下。
image.png

実装例

from dotenv import load_dotenv
from pinecone import Pinecone, ServerlessSpec

# APIキーの設定
load_dotenv()
# インスタンス生成
pc = Pinecone()
index_name = "sample_index"
# Index作成
pc.create_index(
  index_name,
  dimension=1536,  # text-embedding-3-smallの次元数
  metric="cosine",
  spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# APIキーは別ファイルに設定
OPENAI_API_KEY="hogehogehoge"
PINECONE_API_KEY="fugafugafuga"

作成したIndexにデータを投入する

作成したIndexに実際にデータを投入するには upsert を使います。
upsertを指定した場合、データが存在しない場合には登録、既にデータが存在する場合には更新を行います。
upsertのデータ更新は新しいデータで古いデータを上書きします。
もし、データの一部だけ更新したい場合には update を利用しましょう。
実装例

from langchain_openai import OpenAIEmbeddings

# データ埋め込みモデル生成
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
texts = [
  {
    "header_level": 1,
    "header_title": "第1章",
    "body": "サンプルテキスト1"
  },
  {
    "header_level": 1,
    "header_title": "第2章",
    "body": "サンプルテキスト2"
  }
]
# テキストのベクトル化
vectors = embeddings.embed_documents(texts)

# Pinecone用のデータを作成
upsert_data = []
for j, (text, vector) in enumerate(zip(texts, vectors)):
    # ユニークなIDを生成
    doc_id = f"unique_{j}"
    upsert_data.append({
        "id": doc_id,
        "values": vector,
        "metadata": {
            "header_level": doc["header_level"],
            "header_title": doc["header_title"],
            "body": doc["body"],            
        }
    })
# Pineconeにアップサート
index.upsert(vectors=upsert_data)

解説
Pineconeにデータをupsertするには2点必須で実施しないといけません。

  1. ユニークidの生成
  2. upsertするデータのベクトル化

1. ユニークidの生成
上記でも述べていますが、データ登録の最小単位はvectorです。
vectorはidを主キーとするため一意な値を生成する必要があります。

2. upsertするデータのベクトル化
データはvectorのvaluesに設定しますが設定値はベクトル数値である必要があります。
そのために、OpenAIのデータ埋め込みモデル:text-embedding-3-smallの生成、テキストのベクトル化を行います。
ベクトル数値は以下のような値で人間には解読できない値です。
[0.0275665745139122, 0.04805426672101021]

【補足】metadataについて
metadataには付随データを設定しています。
ここで設定した項目は検索時のフィルタリングや補足情報の付与等を行う際に活用されます。
metadataのkeyとvalueの値は完全任意なのでユーザごとに自由に設定可能です。
適切な設定を行うことで検索速度、回答精度の向上につながります。

Indexからデータを取得する

作成したデータを取得するには query を使います。
実装例

# データ検索用にベクトル化
input_query = "第2章について教えて"
query_vector = embeddings.embed_query(input_query)
# filter付き検索
results = index.query(
    vector=query_vector,
    top_k=100,
    include_metadata=False,
    filter={"chapter": {"$eq": chapter_num}}
)

解説
検索も比較的簡単にできます。
index.queryの引数として設定する項目は以下の通り。

引数名 必須 説明
vector ※1 検索の基準となるベクトルデータ。通常はOpenAIなどのEmbeddingモデルで作った数値配列を渡す。
id ※1 ベクトルの代わりに、既にDB内にあるデータのIDを指定して、それに似たものを探すことができます。
top_k 類似度の高い順に何件取得するかを指定します。
filter メタデータフィルタリング。特定の条件に合致するものだけに絞り込んでから検索します。
include_metadata True : header_level,header_title,body等の登録したメタデータも返却する。
False : デフォルト値
include_values True : 取得したデータのベクトル数値も返却する。
False : デフォルト値
namespace Index内でデータをパーティション分けしている場合に、検索対象のグループを指定します。

※1 vector または id のどちらか一方が必須です。

metadataでfilterする際の検索条件

演算子 説明
$eq 等しい {"status": {"$eq": "active"}}
$ne 等しくない {"status": {"$ne": "deleted"}}
$gt より大きい {"price": {"$gt": 100}}
$gte 以上 {"price": {"$gte": 100}}
$lt より小さい {"price": {"$lt": 100}}
$lte 以下 {"price": {"$lte": 100}}
$in 含む {"tag": {"$in": ["a", "b"]}}
$nin 含まない {"tag": {"$nin": ["x"]}}

Indexを削除する

不要なIndexを削除する際に利用します。
こちらもIndex作成と同様にGUI上から可能です。
image.png
実装例

res = index.delete(
    ids=['100'],
    namespace='blog_example'
)

少し使ってみた感想

Chroma同様、セットアップは楽にできるし導入コストは低い。
Pineconeはmetadatasparse_valuesの設定が結構難しくクセがあると感じた。
もちろん使いこなすことができれば低コストで高性能、低レイテンシなRAGを作ることができるが、使いこなせるようになるまでには一定の訓練が必要そう。
ただ、冒頭でも書いたが実績No1のクラウド型ベクトルDBでナレッジが豊富に転がっているので、少し訓練すれば大丈夫そう。
まだ触り始めて1週間程度なので、しばらく色々触ってみます。

その他おすすめ記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?