Skip to main content
Store a dense vector and a sparse vector on each record in a single Pinecone index, then query both signals in one request. Pinecone combines them server-side. Because sparse (BM25-style) scores are unbounded, you set the balance between the two signals client-side, by scaling the query vectors before the request (an alpha weighting). This is the Vectors API single-index hybrid pattern.

Normalize sparse and dense values

A single index that stores both vector types doesn’t reconcile their score ranges. Dense-vector scores fall in a bounded range (roughly [-1, 1] for dotproduct on unit-norm embeddings), while BM25-style sparse weights are unbounded and can run into double digits. Without explicit weighting, the sparse component dominates the combined score. To make the two signals comparable, apply a convex combination at query time using an alpha parameter:
  • combined = alpha * dense + (1 - alpha) * sparse
  • alpha = 1.0 ranks by dense only (pure semantic).
  • alpha = 0.0 ranks by sparse only (pure keyword).
  • alpha = 0.5 weights the two signals equally.
Pinecone applies this weighting by scaling the query vectors before sending them to the index (the index itself stores raw values). Use the hybrid_score_norm helper documented in the walkthrough below; it multiplies the dense values by alpha and the sparse values by 1 - alpha, so the underlying dotproduct produces the desired combination.

Choosing alpha

There’s no universal best value — alpha depends on your data and query distribution. Reasonable starting points:
  • alpha = 0.75 (dense-leaning) — a good default for natural-language queries on conversational or document-style content.
  • alpha = 0.5 (balanced) — useful when keyword and semantic signals contribute equally (e.g., mixed exact-match and synonym queries).
  • alpha = 0.25 (sparse-leaning) — good for queries with high keyword specificity (product SKUs, technical IDs, named entities).
We recommend evaluating multiple alpha values against a labeled relevance set drawn from your own workload. To perform hybrid search with a single index that stores both dense and sparse vectors, follow these steps:
1

Create the index

To store both dense and sparse vectors in a single index, use the create_index operation, setting the vector_type to dense and the metric to dotproduct. This is the only combination that supports dense/sparse search on a single index.
Python
2

Generate vectors

Use Pinecone’s hosted embedding models to convert data into dense and sparse vectors.
Python
Python
3

Upsert records with dense and sparse vectors

Use the upsert operation, specifying dense values in the value parameter and sparse values in the sparse_values parameter.
Only indexes that store dense vectors with the dotproduct distance metric accept records that also have sparse vectors. Upserting such records into an index with a different distance metric will succeed, but querying will return an error.
Python
4

Search the index

Use the embed operation to convert your query into a dense vector and a sparse vector, and then use the query operation to search the index for the 40 most relevant records.
Python
Response
5

Search the index with explicit weighting

For a conceptual overview of why this normalization is needed, see Normalize sparse and dense values.Because Pinecone views your sparse-dense vector as a single vector, it does not offer a built-in parameter to adjust the weight of a query’s dense part against its sparse part; the index is agnostic to density or sparsity of coordinates in your vectors. You may, however, incorporate a linear weighting scheme by customizing your query vector, as demonstrated in the function below.The following example transforms vector values using an alpha parameter.
Python
The following example transforms a vector using the above function, then queries a Pinecone index.
Python