命名空间 #

什么是命名空间? #

命名空间是索引内的逻辑分区,用于隔离不同类型的向量数据。每个索引可以包含多个命名空间,每个命名空间中的向量 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