pinecone向量数据库急速入门

一、介绍

pinecone - 松果

英式发音为/ˈpaɪnˌkəʊn/,美式发音为/ˈpɑɪnˌkoʊn/

AI 向量数据库服务

Pinecone 是一家 2019 年成立于美国纽约的人工智能公司,专注于开发向量数据库技术,其核心产品通过 API 服务帮助开发者将向量搜索功能集成到应用程序中。

1)什么是高维向量

复制代码
1. 普通低维向量(你能理解的)
2 维:平面坐标 (x, y),比如 (3,5)
3 维:空间坐标 (x, y, z),比如 (1,2,3)
就是一组数字,有几个数字就叫几维。
2. 高维向量(AI 里的向量)
AI 把文字、图片、音频、视频,转换成一长串浮点数数组,这串数字就是高维向量。
举个例子:
一段文字:Java怎么学?
经过 Embedding 模型(OpenAI、BERT 等)处理后,变成:
plaintext
[0.12, 0.35, -0.22, 0.78, ... 一直有 1536 个数字]
一共 1536 个数字 → 就叫 1536 维高维向量
你之前报错 1536 vs 1024,就是两种长度的向量不匹配
核心特点
维度极高:常见 512、1024、1536、4096 维
含义抽象:单个数字没意义,整串数字代表语义 / 特征
相似内容 → 向量距离近
"猫" 和 "小猫" 向量距离很近
"猫" 和 "汽车" 向量距离很远
高维向量 = 把文字 / 图片变成AI 能看懂的数字指纹

2)什么是向量数据库?

复制代码
1. 传统数据库能干啥 MySQL/ES:存结构化数据,按关键词、条件查找比如:查姓名、年龄、订单号,精准匹配。 
2. 向量数据库专门干啥 专门用来:存储 高维向量 + 快速做相似度搜索普通数据库存 1536 维向量也能存,但查不了:你要找 "语义最相似" 的内容,传统数据库遍历比对超级慢,上亿条直接卡死。 
向量数据库做了两件核心事: 
1. 专门存储成千上万、上亿条高维向量 
2. 内置向量索引算法(HNSW、IVF 等),毫秒级找出最相似的 Top-K 向量  
3. 通俗比喻 
• 普通数据库:查字典,按字精准查找 
• 向量数据库:凭感觉找人,找气质、长相最相似的人,不用精准匹配

3)和你开发场景对应

  1. 你用 RAG 知识库:

◦ 文档 → 切分 → Embedding 转 1536 维高维向量

◦ 存入 Pinecone / 向量数据库 ◦ 用户提问 → 也转成向量

◦ 向量数据库帮你秒级找出语义最相似的文档片段 → 给大模型做上下文

  1. 为什么不能只用 MySQL?

MySQL 能存这 1536 个数字,但没法高效算相似度,数据一多直接崩。

二、安装 Pinecone 库

Pinecone 官方提供了 Python 客户端库,推荐使用最新的 3.x 版本(2.x 已逐步弃用),安装命令:

复制代码
pip install pinecone-client

pip install pinecone

三、获取 Pinecone API Key

访问:https://www.pinecone.io/

需要注册和登录

key: 如果需要选择什么内容,可以直接跳过 skip

复制自己的 key 值

复制代码
pcsk_6XALja_3PKqXmUvFQupF1sFhNASJKHqfhVXW29rtE6TS4Ln2jURbdz346EqR9umqkAeFk2

四、核心 API

在向量数据库中,索引相当于是数据库,向量相当于是一条条的数据

1 初始化 Pinecone 客户端

3.x 版本简化了客户端初始化方式,无需指定 environment,仅需 API Key:

复制代码
import pinecone
from pinecone import Pinecone, ServerlessSpec

# 初始化 Pinecone 客户端(3.x 推荐方式)
pc = Pinecone(api_key="YOUR_PINECONE_API_KEY")

# 兼容 2.x 版本(可选,不推荐)
# pinecone.init(api_key="YOUR_PINECONE_API_KEY", environment="YOUR_ENV")

2、 索引管理(核心载体)

索引是 Pinecone 存储向量的核心单元,所有向量操作均基于索引完成,常用操作包括创建、列出、描述、缩放、删除。

2.1 创建索引

创建索引时需指定向量维度、相似度度量方式、云厂商/区域(Serverless 模式):

以下是手动创建:

我手动创建的默认是 1024 维度的数据,而下面的代码中,维度使用的是1536,所以可能会报错,所以我们还是使用代码创建一个 1536 维度的数据为好

以下是代码创建:

复制代码
# 定义索引名称(自定义)
index_name = "demo-vector-index2"

# 检查索引是否存在,避免重复创建
if index_name not in pc.list_indexes().names():
    # 创建 Serverless 索引(3.x 推荐,无需管理服务器)
    pc.create_index(
        name=index_name,
        dimension=1536,  # 向量维度(如 OpenAI Embedding 为 1536)
        metric="cosine",  # 相似度度量:cosine(余弦)/euclidean(欧氏)/dotproduct(点积)
        spec=ServerlessSpec(
            cloud="aws",  # 云厂商:aws/gcp
            region="us-east-1"  # 区域(需与账号一致)
        )
    )

# 等待索引创建完成(约 10 秒)
import time
while not pc.describe_index(index_name).status['ready']:
    time.sleep(1)

2.2 索引基础操作

复制代码
# 列出所有索引
all_indexes = pc.list_indexes()
print("当前所有索引:", all_indexes.names())

# 描述索引详情(维度、度量方式、状态等)
index_desc = pc.describe_index(index_name)
print("索引详情:", index_desc)

# 缩放索引(仅 Pod 类型索引支持,Serverless 无需缩放)
# pc.scale_index(name=index_name, replicas=2, pods=1)

# 获取索引实例(后续向量操作的核心对象)
index = pc.Index(index_name)

2.3 向量操作(增删改查)

向量是 Pinecone 的核心数据单元,由 id(唯一标识)、values(向量值)、metadata(元数据,可选)组成,常用操作包括插入/更新、获取、删除。

2.3.1 插入/更新向量(upsert)
复制代码
# 1. 单条向量插入
single_vec = {
    "id": "vec-1",
    "values": [0.1, 0.2, 0.3] + [0.0]*1533,  # 补全到 1536 维度
    "metadata": {  # 元数据(自定义键值对,用于过滤)
        "category": "book",
        "price": 29.99,
        "title": "Python编程入门"
    }
}
index.upsert(vectors=[single_vec], namespace="ns1")  # namespace 用于隔离向量

# 2. 批量插入(推荐,提升效率)
batch_vecs = []
for i in range(2, 10):
    batch_vecs.append({
        "id": f"vec-{i}",
        "values": [0.1*i, 0.2*i, 0.3*i] + [0.0]*1533,
        "metadata": {
            "category": "book" if i % 2 == 0 else "movie",
            "price": 10.99 + i,
            "title": f"Content {i}"
        }
    })
# 批量写入,支持指定命名空间
index.upsert(vectors=batch_vecs, namespace="ns1", batch_size=200)  # 分块大小(默认 1000)

点击索引,查看索引中的内容:

整体代码如下:

复制代码
import pinecone
from pinecone import Pinecone, ServerlessSpec

# 初始化 Pinecone 客户端(3.x 推荐方式)
pc = Pinecone(api_key="pcsk_6XALja_3PKqXmUvFQupF1sFhNASJKHqfhVXW29rtE6TS4Ln2jURbdz346EqR9umqkAeFk2")

# 兼容 2.x 版本(可选,不推荐)
# pinecone.init(api_key="YOUR_PINECONE_API_KEY", environment="YOUR_ENV")

# 定义索引名称(自定义)
index_name = "demo-vector-index2"

# 检查索引是否存在,避免重复创建
if index_name not in pc.list_indexes().names():
    # 创建 Serverless 索引(3.x 推荐,无需管理服务器)
    pc.create_index(
        name=index_name,
        dimension=1536,  # 向量维度(如 OpenAI Embedding 为 1536)
        metric="cosine",  # 相似度度量:cosine(余弦)/euclidean(欧氏)/dotproduct(点积)
        spec=ServerlessSpec(
            cloud="aws",  # 云厂商:aws/gcp
            region="us-east-1"  # 区域(需与账号一致)
        )
    )

# 等待索引创建完成(约 10 秒)
import time
while not pc.describe_index(index_name).status['ready']:
    time.sleep(1)

# 列出所有索引
all_indexes = pc.list_indexes()
print("当前所有索引:", all_indexes.names())

# 描述索引详情(维度、度量方式、状态等)
index_desc = pc.describe_index(index_name)
print("索引详情:", index_desc)

# 缩放索引(仅 Pod 类型索引支持,Serverless 无需缩放)
# pc.scale_index(name=index_name, replicas=2, pods=1)

# 获取索引实例(后续向量操作的核心对象)
index = pc.Index(index_name)



# 1. 单条向量插入
single_vec = {
    "id": "vec-1",
    "values": [0.1, 0.2, 0.3] + [0.0]*1533,  # 补全到 1536 维度
    "metadata": {  # 元数据(自定义键值对,用于过滤)
        "category": "book",
        "price": 29.99,
        "title": "Python编程入门"
    }
}
index.upsert(vectors=[single_vec], namespace="ns1")  # namespace 用于隔离向量

# 2. 批量插入(推荐,提升效率)
batch_vecs = []
for i in range(2, 10):
    batch_vecs.append({
        "id": f"vec-{i}",
        "values": [0.1*i, 0.2*i, 0.3*i] + [0.0]*1533,
        "metadata": {
            "category": "book" if i % 2 == 0 else "movie",
            "price": 10.99 + i,
            "title": f"Content {i}"
        }
    })
# 批量写入,支持指定命名空间
index.upsert(vectors=batch_vecs, namespace="ns1", batch_size=200)  # 分块大小(默认 1000)
2.3.2 获取向量(fetch)
复制代码
# 1. 获取单个向量
single_fetch = index.fetch(ids=["vec-1"], namespace="ns1")
print("单个向量:", single_fetch)

# 2. 批量获取向量
batch_fetch = index.fetch(ids=["vec-2", "vec-3", "vec-4"], namespace="ns1")
print("批量向量:", batch_fetch)
2.3.3 更新向量

通过 upsert 实现更新(仅修改元数据时,向量值可传空列表):

复制代码
# 全量更新(向量值 + 元数据)
update_vec = {
    "id": "vec-1",
    "values": [0.4, 0.5, 0.6] + [0.0]*1533,
    "metadata": {"category": "book", "price": 39.99, "discount": True}
}
index.upsert(vectors=[update_vec], namespace="ns1")

# 仅更新元数据(向量值不变)
meta_only_update = {
    "id": "vec-1",
    "values": [],  # 空列表表示不修改向量值
    "metadata": {"sales": 1000}  # 新增/修改元数据字段
}
index.upsert(vectors=[meta_only_update], namespace="ns1")
2.3.4 删除向量
复制代码
# 1. 删除单个向量
index.delete(ids=["vec-1"], namespace="ns1")

# 2. 批量删除向量
index.delete(ids=["vec-2", "vec-3"], namespace="ns1")

# 3. 删除命名空间下所有向量
index.delete(delete_all=True, namespace="ns1")

2.4 向量查询(核心功能)

Pinecone 的核心价值是相似性检索,支持基础查询、元数据过滤、多向量查询、分页等能力。

2.4.1 基础相似性查询
复制代码
# 构造查询向量(模拟 1536 维向量)
query_vec = [0.5, 0.6, 0.7] + [0.0]*1533

# 基础查询:返回最相似的 5 个向量
basic_query = index.query(
    vector=query_vec,
    top_k=5,  # 返回数量
    namespace="ns1",
    include_metadata=True,  # 是否返回元数据
    include_values=False    # 是否返回向量值
)
print("基础查询结果:", basic_query)
2.4.2 元数据过滤查询(高频用法)

支持丰富的过滤操作符(eq/ne/gt/gte/lt/lte/in/nin),以及 and/or/$not 组合条件:

复制代码
# 示例 1:筛选 category=book 且 price>20 的向量
filtered_query = index.query(
    vector=query_vec,
    top_k=3,
    namespace="ns1",
    include_metadata=True,
    filter={
        "category": {"$eq": "book"},
        "price": {"$gt": 20}
    }
)
print("过滤查询结果:", filtered_query)

# 示例 2:复杂条件(category=movie 或 price<15)
complex_filter = index.query(
    vector=query_vec,
    top_k=3,
    namespace="ns1",
    include_metadata=True,
    filter={
        "$or": [
            {"category": {"$eq": "movie"}},
            {"price": {"$lt": 15}}
        ]
    }
)
print("复杂过滤结果:", complex_filter)
2.4.3 多向量查询

支持传入多个查询向量,通过聚合(均值/求和/最大值)生成最终检索结果:

复制代码
# 多查询向量(如多个文本片段的嵌入向量)
multi_query_vecs = [
    [0.5, 0.6, 0.7] + [0.0]*1533,
    [0.8, 0.9, 1.0] + [0.0]*1533
]

multi_vec_query = index.query(
    vector=multi_query_vecs,
    top_k=5,
    namespace="ns1",
    include_metadata=True,
    multi_vector_query_config={"aggregate": "mean"}  # 聚合方式:mean/sum/max
)
print("多向量查询结果:", multi_vec_query)
2.4.4 分页查询

通过 pagination_token 实现分页,适用于结果量较大的场景:

复制代码
# 第一页
first_page = index.query(
    vector=query_vec,
    top_k=2,  # 每页 2 条
    namespace="ns1",
    include_metadata=True,
    pagination_token=None
)
print("第一页:", first_page)

# 第二页(通过第一页的 token 继续查询)
if "pagination_token" in first_page:
    second_page = index.query(
        vector=query_vec,
        top_k=2,
        namespace="ns1",
        include_metadata=True,
        pagination_token=first_page["pagination_token"]
    )
    print("第二页:", second_page)

2.5 高级操作

2.5.1 命名空间(Namespace)

命名空间用于隔离向量(如按用户/场景分库),不同命名空间的向量相互独立:

复制代码
# 向不同命名空间插入向量
index.upsert(vectors=[single_vec], namespace="ns2")

# 查询指定命名空间的向量
ns2_query = index.query(
    vector=query_vec,
    top_k=1,
    namespace="ns2",
    include_metadata=True
)
print("ns2 命名空间查询:", ns2_query)
2.5.2 索引统计信息

查看索引的向量数量、命名空间分布等:

复制代码
stats = index.describe_index_stats()
print("索引统计信息:", stats)
2.5.3 批量操作最佳实践

单次 upsert 建议控制在 1000 条以内,避免超时,可封装分块函数:

复制代码
def batch_upsert(index, vectors, batch_size=200):
    """批量分块插入向量"""
    for i in range(0, len(vectors), batch_size):
        batch = vectors[i:i+batch_size]
        index.upsert(vectors=batch)
        print(f"插入第 {i//batch_size + 1} 批,共 {len(batch)} 条")

# 示例:插入 1000 条向量
large_batch = [
    {
        "id": f"vec-{i}",
        "values": [0.1*i, 0.2*i, 0.3*i] + [0.0]*1533,
        "metadata": {"category": "article", "views": i*10}
    }
    for i in range(10, 1010)
]
batch_upsert(index, large_batch)

2.6 清理资源

使用完成后删除索引,避免不必要的计费:

复制代码
pc.delete_index(index_name)
print(f"索引 {index_name} 已删除")

五、综合实战:文本语义检索

结合 OpenAI Embedding 将文本转为向量,实现语义检索(需安装 openai 库:pip install openai):

复制代码
import openai

# 配置 OpenAI API Key
openai.api_key = "YOUR_OPENAI_API_KEY"

# 1. 初始化 Pinecone 并创建索引
pc = Pinecone(api_key="YOUR_PINECONE_API_KEY")
index_name = "text-semantic-search"
if index_name not in pc.list_indexes().names():
    pc.create_index(
        name=index_name,
        dimension=1536,
        metric="cosine",
        spec=ServerlessSpec(cloud="aws", region="us-east-1")
    )
index = pc.Index(index_name)

# 2. 文本转向量(OpenAI Embedding)
def get_text_embedding(text, model="text-embedding-3-small"):
    """获取文本的 Embedding 向量"""
    return openai.embeddings.create(
        input=[text.replace("\n", " ")],
        model=model
    ).data[0].embedding

# 3. 准备文本数据并插入 Pinecone
texts = [
    {"id": "t1", "content": "Python是一种解释型、面向对象的高级编程语言", "category": "编程"},
    {"id": "t2", "content": "Pinecone是一款专为向量检索优化的托管式向量数据库", "category": "数据库"},
    {"id": "t3", "content": "OpenAI的Embedding API可以将文本转换为高维向量", "category": "AI"},
    {"id": "t4", "content": "语义搜索通过向量相似度匹配实现精准的文本检索", "category": "搜索"},
    {"id": "t5", "content": "向量数据库广泛应用于推荐系统、问答机器人等AI场景", "category": "AI"}
]

# 批量转换并插入
vectors = []
for item in texts:
    embedding = get_text_embedding(item["content"])
    vectors.append({
        "id": item["id"],
        "values": embedding,
        "metadata": {"content": item["content"], "category": item["category"]}
    })
index.upsert(vectors=vectors)

# 4. 语义检索
query_text = "向量数据库在AI中的应用"
query_embedding = get_text_embedding(query_text)

# 检索 AI 分类的文本
results = index.query(
    vector=query_embedding,
    top_k=3,
    include_metadata=True,
    filter={"category": {"$eq": "AI"}}
)

# 输出结果
print(f"\n查询文本:{query_text}")
print("检索结果(按相似度排序):")
for match in results["matches"]:
    print(f"相似度:{match['score']:.4f} | 内容:{match['metadata']['content']}")

# 5. 清理资源
pc.delete_index(index_name)
相关推荐
雪碧聊技术12 小时前
大模型爆火!Java后端如何抓住Agent全栈开发的风口
java·大模型·agent·全栈开发
Mr.朱鹏1 天前
5.LangChain零基础速通-LCEL链式调用
python·langchain·django·大模型·llm·virtualenv
嵌入式小企鹅1 天前
大模型算法工程师面试宝典
人工智能·学习·算法·面试·职场和发展·大模型·面经
Luca_kill1 天前
深度解构 Hermes Agent:从“中央调度”到“自我进化”的架构哲学
大模型·强化学习·agent框架·ai架构·hermes agent
Komorebi_99991 天前
RAG-day2
大模型·rag
Fleshy数模1 天前
基于 Qwen2.5-1.5B-Instruct 实现多轮对话与文本分类实践
人工智能·分类·大模型
Daydream.V1 天前
本地部署大模型实现相关案例
大模型·本地部署大模型·本地模型案例
●VON1 天前
鸿蒙原生APP开发实战指南:三套低成本AI辅助方案全解析
人工智能·华为·chatgpt·大模型·harmonyos·image
荔枝学Python1 天前
Agent设计最强书籍:它真的把Agent讲解的非常透彻!!
人工智能·程序员·大模型·大语言模型·agent·ai大模型·智能体