命名空间 #
什么是命名空间? #
命名空间是索引内的逻辑分区,用于隔离不同类型的向量数据。每个索引可以包含多个命名空间,每个命名空间中的向量 ID 可以重复。
text
┌─────────────────────────────────────────────────────────────┐
│ 命名空间结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Index: my-app-index │
│ │ │
│ ├── Namespace: "products" │
│ │ ├── Vector: "item-1" → [0.1, 0.2, ...] │
│ │ ├── Vector: "item-2" → [0.3, 0.4, ...] │
│ │ └── Vector: "item-3" → [0.5, 0.6, ...] │
│ │ │
│ ├── Namespace: "articles" │
│ │ ├── Vector: "item-1" → [0.7, 0.8, ...] ← 同名 ID │
│ │ ├── Vector: "item-2" → [0.9, 1.0, ...] │
│ │ └── Vector: "item-3" → [1.1, 1.2, ...] │
│ │ │
│ └── Namespace: "users" │
│ ├── Vector: "user-1" → [1.3, 1.4, ...] │
│ └── Vector: "user-2" → [1.5, 1.6, ...] │
│ │
│ 注意:不同命名空间中的向量 ID 可以相同 │
│ │
└─────────────────────────────────────────────────────────────┘
命名空间的特点 #
text
┌─────────────────────────────────────────────────────────────┐
│ 命名空间特点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ 逻辑隔离 │
│ 不同命名空间的向量互不影响 │
│ 查询只返回指定命名空间的结果 │
│ │
│ ✅ 共享资源 │
│ 所有命名空间共享索引资源 │
│ 无需为每种数据创建新索引 │
│ │
│ ✅ ID 可重复 │
│ 不同命名空间可以使用相同的向量 ID │
│ 适合多租户场景 │
│ │
│ ✅ 自动创建 │
│ 首次写入时自动创建命名空间 │
│ 无需预先定义 │
│ │
│ ⚠️ 删除限制 │
│ 不能直接删除命名空间 │
│ 需要删除其中所有向量 │
│ │
└─────────────────────────────────────────────────────────────┘
使用命名空间 #
插入向量到命名空间 #
python
from pinecone import Pinecone
pc = Pinecone(api_key="your-api-key")
index = pc.Index("my-index")
index.upsert(
vectors=[
("doc-1", [0.1, 0.2, 0.3], {"title": "Product 1"}),
("doc-2", [0.4, 0.5, 0.6], {"title": "Product 2"}),
],
namespace="products"
)
index.upsert(
vectors=[
("doc-1", [0.7, 0.8, 0.9], {"title": "Article 1"}),
("doc-2", [1.0, 1.1, 1.2], {"title": "Article 2"}),
],
namespace="articles"
)
print("向量已插入到不同命名空间")
查询命名空间 #
python
results = index.query(
vector=[0.1, 0.2, 0.3],
top_k=5,
namespace="products"
)
print("Products 命名空间结果:")
for match in results.matches:
print(f" ID: {match.id}, Score: {match.score}")
results = index.query(
vector=[0.1, 0.2, 0.3],
top_k=5,
namespace="articles"
)
print("\nArticles 命名空间结果:")
for match in results.matches:
print(f" ID: {match.id}, Score: {match.score}")
获取命名空间中的向量 #
python
result = index.fetch(
ids=["doc-1", "doc-2"],
namespace="products"
)
print("Products 命名空间中的向量:")
for id, vector in result.vectors.items():
print(f" ID: {id}, Metadata: {vector.metadata}")
删除命名空间中的向量 #
python
index.delete(
ids=["doc-1"],
namespace="products"
)
print("已从 products 命名空间删除 doc-1")
删除命名空间中所有向量 #
python
index.delete(
delete_all=True,
namespace="articles"
)
print("已清空 articles 命名空间")
查看命名空间统计 #
python
stats = index.describe_index_stats()
print("索引统计:")
print(f" 总向量数: {stats.total_vector_count}")
print(f" 维度: {stats.dimension}")
print("\n命名空间统计:")
for namespace, info in stats.namespaces.items():
print(f" {namespace}: {info.vector_count} 向量")
使用场景 #
多租户架构 #
text
┌─────────────────────────────────────────────────────────────┐
│ 多租户架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 场景:SaaS 应用,每个客户独立的数据空间 │
│ │
│ Index: saas-app-index │
│ │ │
│ ├── Namespace: "tenant_001" │
│ │ └── 客户 A 的所有向量数据 │
│ │ │
│ ├── Namespace: "tenant_002" │
│ │ └── 客户 B 的所有向量数据 │
│ │ │
│ └── Namespace: "tenant_003" │
│ └── 客户 C 的所有向量数据 │
│ │
│ 优势: │
│ ✅ 数据完全隔离 │
│ ✅ 共享索引资源,降低成本 │
│ ✅ 简化权限管理 │
│ │
└─────────────────────────────────────────────────────────────┘
python
def query_tenant_data(tenant_id, query_vector, top_k=10):
namespace = f"tenant_{tenant_id}"
results = index.query(
vector=query_vector,
top_k=top_k,
namespace=namespace
)
return results
results = query_tenant_data("001", [0.1, 0.2, ...])
数据类型隔离 #
text
┌─────────────────────────────────────────────────────────────┐
│ 数据类型隔离 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 场景:同一应用中存储不同类型的数据 │
│ │
│ Index: content-index │
│ │ │
│ ├── Namespace: "documents" │
│ │ └── 文档向量 │
│ │ │
│ ├── Namespace: "images" │
│ │ └── 图片向量 │
│ │ │
│ ├── Namespace: "videos" │
│ │ └── 视频向量 │
│ │ │
│ └── Namespace: "audio" │
│ └── 音频向量 │
│ │
│ 优势: │
│ ✅ 按类型搜索 │
│ ✅ 相同 ID 可用于不同类型 │
│ ✅ 灵活的数据组织 │
│ │
└─────────────────────────────────────────────────────────────┘
python
def search_by_type(query_vector, content_type, top_k=10):
results = index.query(
vector=query_vector,
top_k=top_k,
namespace=content_type
)
return results
doc_results = search_by_type(query_vector, "documents")
image_results = search_by_type(query_vector, "images")
环境隔离 #
text
┌─────────────────────────────────────────────────────────────┐
│ 环境隔离 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 场景:开发、测试、生产环境使用同一索引 │
│ │
│ Index: app-index │
│ │ │
│ ├── Namespace: "dev" │
│ │ └── 开发环境数据 │
│ │ │
│ ├── Namespace: "staging" │
│ │ └── 测试环境数据 │
│ │ │
│ └── Namespace: "prod" │
│ └── 生产环境数据 │
│ │
│ 注意: │
│ ⚠️ 生产环境建议使用独立索引 │
│ ⚠️ 此方式仅适合小型项目 │
│ │
└─────────────────────────────────────────────────────────────┘
语言隔离 #
python
languages = ["en", "zh", "ja", "ko"]
for lang in languages:
index.upsert(
vectors=generate_vectors(lang),
namespace=lang
)
def search_by_language(query_vector, language, top_k=10):
return index.query(
vector=query_vector,
top_k=top_k,
namespace=language
)
命名空间最佳实践 #
命名规范 #
text
┌─────────────────────────────────────────────────────────────┐
│ 命名规范 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 推荐格式: │
│ - 使用小写字母和下划线 │
│ - 使用有意义的前缀 │
│ - 保持命名一致性 │
│ │
│ 示例: │
│ ✅ tenant_001, tenant_002 │
│ ✅ env_dev, env_staging, env_prod │
│ ✅ type_documents, type_images │
│ ✅ lang_en, lang_zh, lang_ja │
│ │
│ 避免: │
│ ❌ 过长的命名空间名称 │
│ ❌ 特殊字符 │
│ ❌ 含义不清的缩写 │
│ │
└─────────────────────────────────────────────────────────────┘
数据迁移 #
python
def migrate_namespace(source_ns, target_ns, batch_size=100):
all_ids = []
offset = 0
while True:
results = index.query(
vector=[0] * 1536,
top_k=10000,
namespace=source_ns,
include_values=True,
include_metadata=True
)
if not results.matches:
break
vectors = [
(m.id, m.values, m.metadata)
for m in results.matches
]
index.upsert(vectors=vectors, namespace=target_ns)
all_ids.extend([m.id for m in results.matches])
if len(results.matches) < 10000:
break
print(f"迁移完成: {len(all_ids)} 个向量")
命名空间管理工具 #
python
class NamespaceManager:
def __init__(self, index):
self.index = index
def list_namespaces(self):
stats = self.index.describe_index_stats()
return list(stats.namespaces.keys())
def get_namespace_size(self, namespace):
stats = self.index.describe_index_stats()
return stats.namespaces.get(namespace, {}).get("vector_count", 0)
def clear_namespace(self, namespace):
self.index.delete(delete_all=True, namespace=namespace)
print(f"命名空间 {namespace} 已清空")
def namespace_exists(self, namespace):
return namespace in self.list_namespaces()
def copy_namespace(self, source, target):
vectors = []
results = self.index.query(
vector=[0] * 1536,
top_k=10000,
namespace=source,
include_values=True,
include_metadata=True
)
vectors = [
(m.id, m.values, m.metadata)
for m in results.matches
]
if vectors:
self.index.upsert(vectors=vectors, namespace=target)
print(f"复制完成: {len(vectors)} 个向量")
manager = NamespaceManager(index)
print("所有命名空间:", manager.list_namespaces())
print("products 向量数:", manager.get_namespace_size("products"))
Node.js 示例 #
javascript
const { Pinecone } = require('@pinecone-database/pinecone');
async function namespaceExample() {
const pc = new Pinecone({
apiKey: process.env.PINECONE_API_KEY
});
const index = pc.index('my-index');
await index.upsert([
{ id: 'doc-1', values: [0.1, 0.2, 0.3], metadata: { type: 'product' } },
{ id: 'doc-2', values: [0.4, 0.5, 0.6], metadata: { type: 'product' } }
], { namespace: 'products' });
await index.upsert([
{ id: 'doc-1', values: [0.7, 0.8, 0.9], metadata: { type: 'article' } },
{ id: 'doc-2', values: [1.0, 1.1, 1.2], metadata: { type: 'article' } }
], { namespace: 'articles' });
const productResults = await index.query({
vector: [0.1, 0.2, 0.3],
topK: 5,
namespace: 'products'
});
console.log('Products 结果:', productResults.matches.length);
const stats = await index.describeIndexStats();
console.log('命名空间:', Object.keys(stats.namespaces));
}
namespaceExample();
下一步 #
现在你已经掌握了命名空间,接下来学习 元数据过滤,了解如何使用元数据进行精确过滤!
最后更新:2026-04-04