pgvector support for Node.js, Deno, and Bun (and TypeScript)
Supports node-postgres, Knex.js, Objection.js, Kysely, Sequelize, pg-promise, Prisma, Postgres.js, Slonik, TypeORM, MikroORM, Drizzle ORM, and Bun SQL
Run:
npm install pgvectorAnd follow the instructions for your database library:
- node-postgres
- Knex.js
- Objection.js
- Kysely
- Sequelize
- pg-promise
- Prisma
- Postgres.js
- Slonik
- TypeORM
- MikroORM
- Drizzle ORM
- Bun SQL
Or check out some examples:
- Embeddings with OpenAI
- Binary embeddings with Cohere
- Sentence embeddings with Transformers.js
- Hybrid search with Transformers.js
- Sparse search with Text Embeddings Inference
- Morgan fingerprints with RDKit.js
- Recommendations with Disco
- Horizontal scaling with Citus
- WebAssembly with PGLite
- Bulk loading with
COPY
Enable the extension
awaitclient.query('CREATE EXTENSION IF NOT EXISTS vector');Register the types for a client
importpgvectorfrom'pgvector/pg';awaitpgvector.registerTypes(client);or a pool
pool.on('connect',asyncfunction(client){awaitpgvector.registerTypes(client);});Create a table
awaitclient.query('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))');Insert a vector
awaitclient.query('INSERT INTO items (embedding) VALUES ($1)',[pgvector.toSql([1,2,3])]);Get the nearest neighbors to a vector
constresult=awaitclient.query('SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5',[pgvector.toSql([1,2,3])]);Add an approximate index
awaitclient.query('CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)');// orawaitclient.query('CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Import the library
importpgvectorfrom'pgvector/knex';Enable the extension
awaitknex.schema.createExtensionIfNotExists('vector');Create a table
awaitknex.schema.createTable('items',(table)=>{table.increments('id');table.vector('embedding',3);});Insert vectors
constnewItems=[{embedding: pgvector.toSql([1,2,3])},{embedding: pgvector.toSql([4,5,6])}];awaitknex('items').insert(newItems);Get the nearest neighbors to a vector
constitems=awaitknex('items').orderBy(knex.l2Distance('embedding',[1,2,3])).limit(5);Also supports maxInnerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
Add an approximate index
awaitknex.schema.alterTable('items',function(table){table.index(knex.raw('embedding vector_l2_ops'),'index_name','hnsw');});Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Import the library
importpgvectorfrom'pgvector/objection';Enable the extension
awaitknex.schema.createExtensionIfNotExists('vector');Create a table
awaitknex.schema.createTable('items',(table)=>{table.increments('id');table.vector('embedding',3);});Insert vectors
constnewItems=[{embedding: pgvector.toSql([1,2,3])},{embedding: pgvector.toSql([4,5,6])}];awaitItem.query().insert(newItems);Get the nearest neighbors to a vector
import{l2Distance}from'pgvector/objection';constitems=awaitItem.query().orderBy(l2Distance('embedding',[1,2,3])).limit(5);Also supports maxInnerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
Add an approximate index
awaitknex.schema.alterTable('items',function(table){table.index(knex.raw('embedding vector_l2_ops'),'index_name','hnsw');});Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Enable the extension
awaitsql`CREATE EXTENSION IF NOT EXISTS vector`.execute(db);Create a table
awaitdb.schema.createTable('items').addColumn('id','serial',(cb)=>cb.primaryKey()).addColumn('embedding',sql`vector(3)`).execute();Insert vectors
importpgvectorfrom'pgvector/kysely';constnewItems=[{embedding: pgvector.toSql([1,2,3])},{embedding: pgvector.toSql([4,5,6])}];awaitdb.insertInto('items').values(newItems).execute();Get the nearest neighbors to a vector
import{l2Distance}from'pgvector/kysely';constitems=awaitdb.selectFrom('items').selectAll().orderBy(l2Distance('embedding',[1,2,3])).limit(5).execute();Also supports maxInnerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
Get items within a certain distance
constitems=awaitdb.selectFrom('items').selectAll().where(l2Distance('embedding',[1,2,3]),'<',5).execute();Add an approximate index
awaitdb.schema.createIndex('index_name').on('items').using('hnsw').expression(sql`embedding vector_l2_ops`).execute();Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Enable the extension
awaitsequelize.query('CREATE EXTENSION IF NOT EXISTS vector');Register the types
import{Sequelize}from'sequelize';importpgvectorfrom'pgvector/sequelize';pgvector.registerTypes(Sequelize);Add a vector field
constItem=sequelize.define('Item',{embedding: {type: DataTypes.VECTOR(3)}}, ...);Insert a vector
awaitItem.create({embedding: [1,2,3]});Get the nearest neighbors to a vector
import{l2Distance}from'pgvector/sequelize';constitems=awaitItem.findAll({order: l2Distance('embedding',[1,1,1],sequelize),limit: 5});Also supports maxInnerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
Add an approximate index
constItem=sequelize.define('Item', ...,{indexes: [{fields: ['embedding'],using: 'hnsw',operator: 'vector_l2_ops'}]});Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Enable the extension
awaitdb.none('CREATE EXTENSION IF NOT EXISTS vector');Register the types
importpgpromisefrom'pg-promise';importpgvectorfrom'pgvector/pg-promise';constinitOptions={asyncconnect(e){awaitpgvector.registerTypes(e.client);}};constpgp=pgpromise(initOptions);Create a table
awaitdb.none('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))');Insert a vector
awaitdb.none('INSERT INTO items (embedding) VALUES ($1)',[pgvector.toSql([1,2,3])]);Get the nearest neighbors to a vector
constresult=awaitdb.any('SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5',[pgvector.toSql([1,2,3])]);Add an approximate index
awaitdb.none('CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)');// orawaitdb.none('CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Note: prisma migrate dev does not support pgvector indexes
Import the library
importpgvectorfrom'pgvector';Add the extension to the schema
generatorclient{provider="prisma-client"previewFeatures=["postgresqlExtensions"]}datasourcedb{provider="postgresql"extensions=[vector]}Add a vector column to the schema
modelItem{idInt@id@default(autoincrement())embeddingUnsupported("vector(3)")?}Insert a vector
constembedding=pgvector.toSql([1,2,3])awaitprisma.$executeRaw`INSERT INTO items (embedding) VALUES (${embedding}::vector)`Get the nearest neighbors to a vector
constembedding=pgvector.toSql([1,2,3])constitems=awaitprisma.$queryRaw`SELECT id, embedding::text FROM items ORDER BY embedding <-> ${embedding}::vector LIMIT 5`See a full example (and the schema)
Import the library
importpgvectorfrom'pgvector';Enable the extension
awaitsql`CREATE EXTENSION IF NOT EXISTS vector`;Create a table
awaitsql`CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))`;Insert vectors
constnewItems=[{embedding: pgvector.toSql([1,2,3])},{embedding: pgvector.toSql([4,5,6])}];awaitsql`INSERT INTO items ${sql(newItems,'embedding')}`;Get the nearest neighbors to a vector
constembedding=pgvector.toSql([1,2,3]);constitems=awaitsql`SELECT * FROM items ORDER BY embedding <-> ${embedding} LIMIT 5`;Add an approximate index
awaitsql`CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)`;// orawaitsql`CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)`;Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Import the library
importpgvectorfrom'pgvector';Enable the extension
awaitpool.query(sql.unsafe`CREATE EXTENSION IF NOT EXISTS vector`);Create a table
awaitpool.query(sql.unsafe`CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))`);Insert a vector
constembedding=pgvector.toSql([1,2,3]);awaitpool.query(sql.unsafe`INSERT INTO items (embedding) VALUES (${embedding})`);Get the nearest neighbors to a vector
constembedding=pgvector.toSql([1,2,3]);constitems=awaitpool.query(sql.unsafe`SELECT * FROM items ORDER BY embedding <-> ${embedding} LIMIT 5`);Add an approximate index
awaitpool.query(sql.unsafe`CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)`);// orawaitpool.query(sql.unsafe`CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)`);Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Import the library
importpgvectorfrom'pgvector';Enable the extension
awaitAppDataSource.query('CREATE EXTENSION IF NOT EXISTS vector');Create a table
awaitAppDataSource.query('CREATE TABLE item (id bigserial PRIMARY KEY, embedding vector(3))');Define an entity
@Entity()classItem{ @PrimaryGeneratedColumn()id: number @Column()embedding: string}Insert a vector
constitemRepository=AppDataSource.getRepository(Item);awaititemRepository.save({embedding: pgvector.toSql([1,2,3])});Get the nearest neighbors to a vector
constitems=awaititemRepository.createQueryBuilder('item').orderBy('embedding <-> :embedding').setParameters({embedding: pgvector.toSql([1,2,3])}).limit(5).getMany();See a full example
Enable the extension
awaitem.execute('CREATE EXTENSION IF NOT EXISTS vector');Define an entity
import{VectorType}from'pgvector/mikro-orm'; @Entity()classItem{ @PrimaryKey()id: number; @Property({type: VectorType})embedding: number[];}Insert a vector
em.create(Item,{embedding: [1,2,3]});Get the nearest neighbors to a vector
import{l2Distance}from'pgvector/mikro-orm';constitems=awaitem.createQueryBuilder(Item).orderBy({[l2Distance('embedding',[1,2,3])]: 'ASC'}).limit(5).getResult();Also supports maxInnerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
See a full example
Drizzle ORM 0.31.0+ has built-in support for pgvector 🎉
Enable the extension
awaitclient`CREATE EXTENSION IF NOT EXISTS vector`;Add a vector field
import{vector}from'drizzle-orm/pg-core';constitems=pgTable('items',{id: serial('id').primaryKey(),embedding: vector('embedding',{dimensions: 3})});Also supports halfvec, bit, and sparsevec
Insert vectors
constnewItems=[{embedding: [1,2,3]},{embedding: [4,5,6]}];awaitdb.insert(items).values(newItems);Get the nearest neighbors to a vector
import{l2Distance}from'drizzle-orm';constallItems=awaitdb.select().from(items).orderBy(l2Distance(items.embedding,[1,2,3])).limit(5);Also supports innerProduct, cosineDistance, l1Distance, hammingDistance, and jaccardDistance
See a full example
Import the library
importpgvectorfrom'pgvector';Enable the extension
awaitsql`CREATE EXTENSION IF NOT EXISTS vector`;Create a table
awaitsql`CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))`;Insert vectors
constnewItems=[{embedding: pgvector.toSql([1,2,3])},{embedding: pgvector.toSql([4,5,6])}];awaitsql`INSERT INTO items ${sql(newItems)}`;Get the nearest neighbors to a vector
constembedding=pgvector.toSql([1,2,3]);constitems=awaitsql`SELECT * FROM items ORDER BY embedding <-> ${embedding} LIMIT 5`.values();Add an approximate index
awaitsql`CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)`;// orawaitsql`CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)`;Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Create a sparse vector from an array
constvec=newSparseVector([1,0,2,0,3,0]);Or a map of non-zero elements
constvec=newSparseVector({0: 1,2: 2,4: 3},6);// orconstmap=newMap();map.set(0,1);map.set(2,2);map.set(4,3);constvec=newSparseVector(map,6);Note: Indices start at 0
Get the number of dimensions
constdim=vec.dimensions;Get the indices of non-zero elements
constindices=vec.indices;Get the values of non-zero elements
constvalues=vec.values;Get an array
constarr=vec.toArray();View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development:
git clone https://github.com/pgvector/pgvector-node.git cd pgvector-node npm install createdb pgvector_node_test npx prisma generate npx prisma migrate dev npm testTo run an example:
cd examples/loading npm install createdb pgvector_example node example.js