Documentation Index
Fetch the complete documentation index at: https://docs.pinecone.io/llms.txt
Use this file to discover all available pages before exploring further.
Documents
A document is the unit of data in an index with a document schema — a JSON object with a required_id field plus any fields declared in the index’s schema. Documents support multiple field types in a single record: a dense_vector field (for semantic search), a sparse_vector field (for sparse-vector lexical search), one or more string fields with full_text_search enabled (for full-text search with BM25 and Lucene queries), and filterable metadata fields of type string, string_list, float, or boolean.
The schema, declared at index creation, tells Pinecone how to index each field. Field types:
dense_vector— indexed for ANN similarity search.sparse_vector— indexed for sparse-vector lexical search.stringwith a nestedfull_text_searchconfig object ({}enables with all defaults; optional sub-fields:language,stemming,stop_words) — indexed for BM25 ranking and Lucene queries. Lowercasing and the token length cap are server-applied and cannot be overridden.string,string_list,float,booleanwithfilterable: true— indexed for metadata filtering.
string_list field holds an array of strings; a dense_vector field holds an array of floats; a sparse_vector field is an object with two parallel arrays — indices (token positions) and values (token weights).
A schema can declare up to 100 string fields with full_text_search enabled, but at most one dense_vector field and at most one sparse_vector field per index.
Additional fields not declared in the schema are stored on the document and returned via include_fields. Today, these are also auto-indexed for filtering. Forward-looking: in a future release, only schema-declared fields with filterable: true will be indexed for filtering — declare metadata fields in the schema now to be future-proof.
Example document for an index with title, body, embedding, and category fields:
- Must be unique, non-empty strings.
- Must not start with
_(reserved for system-managed fields like_idand_score) or$(reserved for filter operators). - Limited to 64 bytes.
Chunking granularity. A document is the unit of retrieval —
top_k and _score are computed per document, not per sub-section. In public preview, Pinecone does not split a single document into multiple in-document chunks at index time. If your source content is longer than what you want to retrieve as one hit (a long article, a PDF, a transcript), do the chunking in your application before upsert and store each chunk as its own document, with an ID like document1#chunk1, document1#chunk2, and a metadata field that ties chunks back to the parent document for grouping at query time.Schema patterns
The same document model supports several common schema shapes. Pick the one that matches the signal you want to rank by, and plan your fields up front: in public preview, schema migration is not supported after index creation. Filters are deterministic per document and apply before scoring; choose your hard yes/no constraints (including text-match operators on FTS-enabledstring fields) first, then pick a score_by method to rank whatever remains. See Filters vs. scoring.
The Python snippets in each accordion below assume an initialized client and the schema-builder import:Each accordion shows the pattern-specific schema, an example document, and a search snippet. The control-plane (
Python
pc.preview.indexes.create(...)) and data-plane (index = pc.preview.index(name=...)) calls in the snippets reuse this pc.Single text field — keyword search only (FTS)
Single text field — keyword search only (FTS)
Use when you want BM25 keyword ranking on one piece of text per document (a review body, a support ticket, a product description) and you don’t have embeddings to manage.A document upserted into this index looks like:Search with a single See Full-text search.
Python
text clause (the score_by type, not a field type — this clause runs BM25 ranking on the named string field):Python
Multi-field FTS — score across two text fields (e.g. body + summary)
Multi-field FTS — score across two text fields (e.g. body + summary)
Use when a document has more than one piece of text that should both contribute to ranking — for example, a long A document upserted into this index looks like:Pass two
review_text plus a short review_summary. Pinecone combines the per-field BM25 scores into one ranking per document.Python
text clauses in score_by; the server combines them into one ranking, with each contributing field weighted equally in 2026-01.alpha.Python
Dense + FTS — semantic and keyword in one index
Dense + FTS — semantic and keyword in one index
Most workloads that combine semantic ranking with keyword matching reach for this pattern: rank by dense (or sparse) similarity, restricted to documents that contain a specific term or phrase. Common examples include semantic search over patents, regulatory filings, internal knowledge bases, or other technical literature where the right answer must contain a specific term. A single schema can include one A document upserted into this index looks like:Option B — run BM25 and dense searches separately and merge client-side (when you want both signals to contribute to ranking, e.g. via reciprocal rank fusion):See Hybrid search for a fuller discussion.
dense_vector field plus any number of FTS-enabled string fields:Python
review_embedding is a 1024-dim list of floats produced by your dense embedding model. Use the same model at query time so the query vector lives in the same space.A single search request ranks by one scoring type. With this schema you have two query options:Option A — dense ranking restricted by a text-match filter (the most common hybrid pattern):Python
Python
Multi-signal index — dense + sparse + FTS in one schema
Multi-signal index — dense + sparse + FTS in one schema
Use when a single document is best described by more than one ranking signal — for example, a video catalog where each item has frame embeddings (dense), auto-generated captions you’ve encoded as sparse vectors (sparse), and a transcript text field (BM25/Lucene). One schema declares all three; you pick the ranking signal per query with A document upserted into this index looks like:Semantic frame search — rank by visual similarity:Caption lexical search — rank by sparse-vector lexical similarity over your encoded captions:Semantic search restricted to spoken phrase — semantic frame ranking, narrowed to clips where the transcript contains a specific phrase:
score_by. No second index, no cross-index linkage to maintain.Python
frame_embedding is a 1024-dim list of floats from your dense vision model. caption_sparse is the output of your sparse encoder — an object with parallel indices (token IDs) and values (token weights) arrays.The same index supports three different query shapes. All three assume:Python
Python
Python
Python
score_by selects one ranking signal per request, but every signal stays addressable on the same documents.Sparse + dense hybrid — single-vector index (vector API)
Sparse + dense hybrid — single-vector index (vector API)
Use when you’re modeling data with the vector API (not the document API) and want to combine a sparse and dense vector in one record on a single index. For new document-centric projects with text data, prefer the document-shape Dense + FTS pattern above.See Hybrid search.
Records
Records are how you model data for indexes with dense vectors and indexes with sparse vectors. Each record carries one vector (dense, sparse, or both for single-index hybrid) plus optional metadata, and you can upsert raw text in place of a vector when the index is integrated with an embedding model.- Vectors
- Text
When you upsert pre-generated vectors, each record consists of the following:Example:
- ID: A unique string identifier for the record.
- Vector: A dense vector for semantic search, a sparse vector for sparse-vector lexical search, or both for single-index hybrid search (vector API).
- Metadata (optional): A flat JSON document containing key-value pairs with additional information (nested objects are not supported). You can filter by metadata when searching or deleting records.
When importing data from object storage, records must be in Parquet format. For more details, see Import data.
Use structured IDs
Use a structured, human-readable format for record IDs, including ID prefixes that reflect the type of data you’re storing, for example:- Document chunks:
document_id#chunk_number - User data:
user_id#data_type#item_id - Multi-tenant data:
tenant_id#document_id#chunk_id
document1#chunk1- Using hash delimiterdocument1_chunk1- Using underscore delimiterdocument1:chunk1- Using colon delimiter
- Efficiency: Applications can quickly identify which record it should operate on.
- Clarity: Developers can easily understand what they’re looking at when examining records.
- Flexibility: ID prefixes enable list operations for fetching and updating records.
Include metadata
Include metadata key-value pairs that support your application’s key operations, for example:- Enable query-time filtering: Add fields for time ranges, categories, or other criteria for filtering searches for increased accuracy and relevance.
- Link related chunks: Use fields like
document_idandchunk_numberto keep track of related records and enable efficient chunk deletion and document updates. - Link back to original data: Include
chunk_textordocument_urlfor traceability and user display.
- String
- Number (stored as a 64-bit floating point)
- Boolean (true, false)
- List of strings
Pinecone supports 40 KB of metadata per record.
Example
This example demonstrates how to manage document chunks in Pinecone using structured IDs and comprehensive metadata. It covers the complete lifecycle of chunked documents: upserting, searching, fetching, updating, and deleting chunks, and updating an entire document.Upsert chunks
When upserting documents that have been split into chunks, combine structured IDs with comprehensive metadata:- Upsert text
- Upsert vectors
Upserting raw text is supported only for indexes with integrated embedding.
Python
Search chunks
To search the chunks of a document, use a metadata filter expression that limits the search appropriately:- Search with text
- Search with a vector
Searching with text is supported only for indexes with integrated embedding.
Python
Fetch chunks
To retrieve all chunks for a specific document, first list the record IDs using the document prefix, and then fetch the complete records:Python
Pinecone is eventually consistent, so it’s possible that a write (upsert, update, or delete) followed immediately by a read (query, list, or fetch) may not return the latest version of the data. If your use case requires retrieving data immediately, consider implementing a small delay or retry logic after writes.
Update chunks
To update specific chunks within a document, first list the chunk IDs, and then update individual records:Python
Delete chunks
To delete chunks of a document, use a metadata filter expression that limits the deletion appropriately:Python
Update an entire document
When the amount of chunks or ordering of chunks for a document changes, the recommended approach is to first delete all chunks using a metadata filter, and then upsert the new chunks:Python
Data freshness
Pinecone is eventually consistent, so it’s possible that a write (upsert, update, or delete) followed immediately by a read (query, list, or fetch) may not return the latest version of the data. If your use case requires retrieving data immediately, consider implementing a small delay or retry logic after writes.Design for multi-tenancy
Many applications have a concept of tenants—users, organizations, projects, or other groups that should only access their own data. How you model this access control significantly impacts query performance and cost.Use namespaces for tenant isolation
The most efficient way to implement multi-tenancy is to use namespaces to separate data by tenant. With this approach, each tenant has their own namespace, and queries only scan that tenant’s data—resulting in better performance and lower costs. For a complete implementation guide with examples across all SDKs, see Implement multitenancy.Why namespaces are more efficient
Why namespaces are more efficient
When you use namespaces for multi-tenancy:
- Lower query costs and faster performance: Query cost is based on namespace size. If you have 100 tenants with 1 GB each, querying one tenant’s namespace costs 1 RU and scans only 1 GB. With metadata filtering in a single namespace (100 GB total), the same query costs 100 RUs and scans all 100 GB, even though the filter narrows results.
- Natural isolation: Reduces the risk of application bugs that could query the wrong tenant’s data (for example, by passing an incorrect filter value).
Avoid filtering by high-cardinality IDs
A common anti-pattern is storing all data in a single namespace and using metadata filters to scope queries to specific users:- Performance degradation: Large
$infilters increase network payload size and query latency. - Hard limits: Each
$inor$ninoperator is limited to 10,000 values. Exceeding this limit will cause the request to fail. See Metadata filter limits.
Use access control groups instead of individual IDs
If data must be shared across many tenants, design your access control using the smallest number of groups that describe a user’s access:Multitenancy patterns
The following table provides general guidelines for choosing a multitenancy approach. Evaluate your specific use case, access patterns, and requirements to determine the best fit for your application.| Data pattern | Recommended approach | Query cost | Performance |
|---|---|---|---|
| Each tenant’s data is completely separate | One index, one namespace per tenant | Lowest (scans only tenant namespace) | Fastest |
| Large tenants with many sub-groups | One index per large tenant, namespaces for sub-groups | Low (scans only sub-group namespace) | Fast |
| Data shared across tenants | One index, shared namespace, filter by group IDs (org, project, role) | Higher (scans entire shared namespace) | Slower |