查询与搜索 #

查询基础 #

Pinecone 的核心功能是向量相似性搜索,通过计算查询向量与索引中所有向量的相似度,返回最相似的结果。

text
┌─────────────────────────────────────────────────────────────┐
│                    查询流程                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   查询向量          相似度计算          返回结果            │
│                                                             │
│   [0.1, 0.2, ...] ───────────────> Top-K 相似向量          │
│         │                │                │                 │
│         │                │                │                 │
│         ▼                ▼                ▼                 │
│   ┌─────────┐      ┌─────────┐      ┌─────────┐            │
│   │ 查询    │      │ 计算与  │      │ 返回最  │            │
│   │ 向量    │      │ 所有向量│      │ 相似的K │            │
│   │         │      │ 的距离  │      │ 个结果  │            │
│   └─────────┘      └─────────┘      └─────────┘            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本查询 #

执行查询 #

python
from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
index = pc.Index("my-index")

query_vector = [0.1, 0.2, 0.3, ...]

results = index.query(
    vector=query_vector,
    top_k=10
)

for match in results.matches:
    print(f"ID: {match.id}, Score: {match.score}")

查询参数 #

text
┌─────────────────────────────────────────────────────────────┐
│                    查询参数说明                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  vector(必需):                                            │
│  - 查询向量                                                 │
│  - 维度必须与索引维度匹配                                   │
│                                                             │
│  top_k(必需):                                             │
│  - 返回结果数量                                             │
│  - 最大 10000                                               │
│                                                             │
│  namespace(可选):                                         │
│  - 指定查询的命名空间                                       │
│  - 默认为空命名空间                                         │
│                                                             │
│  filter(可选):                                            │
│  - 元数据过滤条件                                           │
│  - 支持多种操作符                                           │
│                                                             │
│  include_values(可选,默认 False):                        │
│  - 是否返回向量值                                           │
│                                                             │
│  include_metadata(可选,默认 False):                      │
│  - 是否返回元数据                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

查询结果 #

结果结构 #

python
results = index.query(
    vector=query_vector,
    top_k=5,
    include_metadata=True,
    include_values=True
)

print(f"命名空间: {results.namespace}")

for match in results.matches:
    print(f"ID: {match.id}")
    print(f"Score: {match.score}")
    print(f"Values: {match.values[:3]}...")
    print(f"Metadata: {match.metadata}")
    print("---")

分数解释 #

text
┌─────────────────────────────────────────────────────────────┐
│                    分数含义                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  余弦相似度(cosine):                                      │
│  - 范围:[-1, 1]                                            │
│  - 1 表示完全相同                                           │
│  - 0 表示正交(无关)                                       │
│  - -1 表示完全相反                                          │
│  - 分数越高越相似                                           │
│                                                             │
│  欧几里得距离(euclidean):                                 │
│  - 范围:[0, +∞)                                            │
│  - 0 表示完全相同                                           │
│  - 分数越小越相似                                           │
│  - Pinecone 返回距离的平方                                  │
│                                                             │
│  点积(dotproduct):                                        │
│  - 范围:(-∞, +∞)                                           │
│  - 分数越高越相似                                           │
│  - 受向量长度影响                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

元数据过滤查询 #

基本过滤 #

python
results = index.query(
    vector=query_vector,
    top_k=10,
    filter={
        "category": {"$eq": "technology"}
    },
    include_metadata=True
)

多条件过滤 #

python
results = index.query(
    vector=query_vector,
    top_k=10,
    filter={
        "category": {"$eq": "technology"},
        "views": {"$gte": 1000},
        "tags": {"$in": ["AI", "ML"]}
    },
    include_metadata=True
)

过滤操作符 #

text
┌─────────────────────────────────────────────────────────────┐
│                    过滤操作符                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  比较操作符:                                                │
│  ┌──────────┬────────────────────────────────────────────┐  │
│  │ 操作符   │ 描述                                        │  │
│  ├──────────┼────────────────────────────────────────────┤  │
│  │ $eq      │ 等于                                        │  │
│  │ $ne      │ 不等于                                      │  │
│  │ $gt      │ 大于                                        │  │
│  │ $gte     │ 大于等于                                    │  │
│  │ $lt      │ 小于                                        │  │
│  │ $lte     │ 小于等于                                    │  │
│  └──────────┴────────────────────────────────────────────┘  │
│                                                             │
│  数组操作符:                                                │
│  ┌──────────┬────────────────────────────────────────────┐  │
│  │ 操作符   │ 描述                                        │  │
│  ├──────────┼────────────────────────────────────────────┤  │
│  │ $in      │ 在列表中                                    │  │
│  │ $nin     │ 不在列表中                                  │  │
│  └──────────┴────────────────────────────────────────────┘  │
│                                                             │
│  逻辑操作符:                                                │
│  ┌──────────┬────────────────────────────────────────────┐  │
│  │ 操作符   │ 描述                                        │  │
│  ├──────────┼────────────────────────────────────────────┤  │
│  │ $and     │ 且(所有条件都满足)                        │  │
│  │ $or      │ 或(任一条件满足)                          │  │
│  │ $not     │ 非(条件不满足)                            │  │
│  └──────────┴────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

复杂过滤示例 #

python
results = index.query(
    vector=query_vector,
    top_k=10,
    filter={
        "$and": [
            {"category": {"$in": ["technology", "science"]}},
            {"views": {"$gte": 500}},
            {
                "$or": [
                    {"author": {"$eq": "John"}},
                    {"author": {"$eq": "Jane"}}
                ]
            }
        ]
    },
    include_metadata=True
)

命名空间查询 #

指定命名空间 #

python
results = index.query(
    vector=query_vector,
    top_k=10,
    namespace="products"
)

跨命名空间查询 #

python
namespaces = ["products", "articles", "users"]

all_results = []

for ns in namespaces:
    results = index.query(
        vector=query_vector,
        top_k=5,
        namespace=ns
    )
    all_results.extend(results.matches)

all_results.sort(key=lambda x: x.score, reverse=True)
top_results = all_results[:10]

批量查询 #

批量查询方法 #

python
query_vectors = [
    [0.1, 0.2, 0.3, ...],
    [0.4, 0.5, 0.6, ...],
    [0.7, 0.8, 0.9, ...],
]

results = []
for vec in query_vectors:
    result = index.query(vector=vec, top_k=5)
    results.append(result)

异步批量查询 #

python
import asyncio

async def async_query(index, vector):
    return index.query(vector=vector, top_k=5)

async def batch_query(index, vectors):
    tasks = [async_query(index, vec) for vec in vectors]
    return await asyncio.gather(*tasks)

query_vectors = [[0.1, 0.2, ...], [0.3, 0.4, ...], ...]
results = asyncio.run(batch_query(index, query_vectors))

查询优化 #

使用元数据过滤优化 #

text
┌─────────────────────────────────────────────────────────────┐
│                    查询优化策略                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 使用元数据过滤减少搜索空间                              │
│                                                             │
│     不推荐:                                                │
│     results = index.query(vector=v, top_k=100)             │
│     filtered = [r for r in results if r.metadata['cat'] == 'A'] │
│                                                             │
│     推荐:                                                  │
│     results = index.query(                                 │
│         vector=v,                                          │
│         top_k=10,                                          │
│         filter={"category": {"$eq": "A"}}                  │
│     )                                                       │
│                                                             │
│  2. 只请求需要的数据                                        │
│                                                             │
│     不需要向量值时:                                        │
│     include_values=False                                   │
│                                                             │
│     不需要元数据时:                                        │
│     include_metadata=False                                 │
│                                                             │
│  3. 合理设置 top_k                                          │
│                                                             │
│     - 不要设置过大的 top_k                                  │
│     - 根据实际需求设置                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

查询性能监控 #

python
import time

def timed_query(index, vector, top_k=10):
    start = time.time()
    results = index.query(vector=vector, top_k=top_k)
    elapsed = time.time() - start
    print(f"查询耗时: {elapsed*1000:.2f}ms")
    return results

完整查询示例 #

语义搜索示例 #

python
from openai import OpenAI
from pinecone import Pinecone

openai_client = OpenAI(api_key="your-openai-key")
pc = Pinecone(api_key="your-pinecone-key")
index = pc.Index("documents")

def get_embedding(text):
    response = openai_client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    )
    return response.data[0].embedding

def semantic_search(query, top_k=5, filters=None):
    query_embedding = get_embedding(query)
    
    query_params = {
        "vector": query_embedding,
        "top_k": top_k,
        "include_metadata": True
    }
    
    if filters:
        query_params["filter"] = filters
    
    results = index.query(**query_params)
    
    return [
        {
            "id": match.id,
            "score": match.score,
            "metadata": match.metadata
        }
        for match in results.matches
    ]

results = semantic_search(
    "如何学习机器学习",
    top_k=5,
    filters={"category": {"$eq": "tutorial"}}
)

for r in results:
    print(f"Score: {r['score']:.4f}")
    print(f"Title: {r['metadata'].get('title')}")
    print("---")

RAG 查询示例 #

python
def rag_query(query, top_k=5):
    query_embedding = get_embedding(query)
    
    results = index.query(
        vector=query_embedding,
        top_k=top_k,
        include_metadata=True
    )
    
    context = "\n\n".join([
        match.metadata.get("content", "")
        for match in results.matches
    ])
    
    prompt = f"""基于以下上下文回答问题:

上下文:
{context}

问题:{query}

回答:"""
    
    response = openai_client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
    
    return response.choices[0].message.content

Node.js 查询示例 #

javascript
const { Pinecone } = require('@pinecone-database/pinecone');

async function queryExample() {
  const pc = new Pinecone({
    apiKey: process.env.PINECONE_API_KEY
  });

  const index = pc.index('my-index');

  const results = await index.query({
    vector: [0.1, 0.2, 0.3],
    topK: 10,
    includeMetadata: true,
    filter: {
      category: { $eq: 'technology' }
    }
  });

  console.log(`找到 ${results.matches.length} 个结果`);
  
  results.matches.forEach(match => {
    console.log(`ID: ${match.id}`);
    console.log(`Score: ${match.score}`);
    console.log(`Metadata:`, match.metadata);
    console.log('---');
  });
}

queryExample();

下一步 #

现在你已经掌握了查询与搜索,接下来学习 命名空间,了解如何使用命名空间组织数据!

最后更新:2026-04-04