Before you begin
- pg_pinecone installed.
- A Pinecone API key stored in the database. Store it with
SELECT pinecone.set_api_key('YOUR_API_KEY');. pg_pineconeinshared_preload_libraries, followed by a Postgres restart. See Preload the extension.- A table with a single-column primary key, which becomes each document’s ID. You must own the table.
- A Pinecone plan that includes the hosted model you use. For example,
gemini-embedding-2requires a Builder, Standard, or Enterprise plan.
Search by meaning
Embed a text column
Call This creates a Pinecone index and copies the table’s existing rows to it, then keeps it in sync. To check when the initial copy is done, see the full-text search guide.
pinecone.track_docs() and give one text column an embed option. Pinecone then embeds that column’s text with a hosted model on every write and every query, using integrated embedding:SQL
- Model settings: pg_pinecone passes the
embedobject to Pinecone.modelis required, and you can also setdimension,metric,processing_location,write_parameters, andread_parameters. Pinecone fills in defaults for anything you leave out. - Keyword and semantic search on one column: The column keeps its full-text index, so
mode => 'text'still ranks it with BM25. Semantic and BM25 scores use different scales. To rank by both, run two searches and merge the results by rank. - Filters:
mode => 'embed'works withfilterandmust, so you can rank by meaning within rows that match a metadata value or required text. For examples, see the full-text search guide. - One embedded column: Only one text column can set
embed, and you can’t combine it withvector_column. - Empty text: A row whose
embedcolumn isNULLor blank isn’t indexed. If Pinecone already has a copy of that row, pg_pinecone deletes it.
Combine text and vector search
If your table already stores embeddings, declare the column withvector_column instead of using embed. Then pass a query vector with vector, and name the column the text query must match with field. The text query narrows the results to rows that match it in that column, and the vector ranks what’s left.
This example uses the articles table from Search a table with full-text search, which declares vector_column => 'embedding':
SQL
Output
Embed a field on an index directly
To embed a field on an index that isn’t tied to a table, add the sameembed object to the field in pinecone.create_doc_index(), then search it with an embed clause in pinecone.search_doc_index():
SQL
pinecone.upsert_docs() and delete the index with pinecone.drop_doc_index(), see the full-text search guide.