查询与搜索 #
查询基础 #
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