Skip to content

pgvector support for Node.js (and TypeScript)

License

Notifications You must be signed in to change notification settings

cometkim/pgvector-node

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pgvector-node

pgvector support for Node.js (and TypeScript)

Supports node-postgres, Sequelize, pg-promise, Prisma, Postgres.js, Knex.js, and Drizzle ORM

Build Status

Installation

Run:

npm install pgvector

And follow the instructions for your database library:

Or check out some examples:

node-postgres

Enable the extension

await client.query('CREATE EXTENSION IF NOT EXISTS vector');

Register the type for a client

import pgvector from 'pgvector/pg';

await pgvector.registerType(client);

or a pool

pool.on('connect', async function (client) {
  await pgvector.registerType(client);
});

Create a table

await client.query('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))');

Insert a vector

const embedding = [1, 2, 3];
await client.query('INSERT INTO items (embedding) VALUES ($1)', [pgvector.toSql(embedding)]);

Get the nearest neighbors to a vector

const result = await client.query('SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [pgvector.toSql(embedding)]);

Sequelize

Enable the extension

await sequelize.query('CREATE EXTENSION IF NOT EXISTS vector');

Register the type

import { Sequelize } from 'sequelize';
import pgvector from 'pgvector/sequelize';

pgvector.registerType(Sequelize);

Add a vector field

Item.init({
  embedding: {
    type: DataTypes.VECTOR(3)
  }
}, ...);

Insert a vector

await Item.create({embedding: [1, 2, 3]});

Get the nearest neighbors to a vector

const items = await Item.findAll({
  order: [sequelize.literal(`embedding <-> '[1, 2, 3]'`)],
  limit: 5
});

pg-promise

Enable the extension

await db.none('CREATE EXTENSION IF NOT EXISTS vector');

Register the type

import pgpromise from 'pg-promise';
import pgvector from 'pgvector/pg';

const initOptions = {
  async connect(e) {
    await pgvector.registerType(e.client);
  }
};
const pgp = pgpromise(initOptions);

Create a table

await db.none('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))');

Insert a vector

const embedding = [1, 2, 3];
await db.none('INSERT INTO items (embedding) VALUES ($1)', [pgvector.toSql(embedding)]);

Get the nearest neighbors to a vector

const result = await db.any('SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [pgvector.toSql(embedding)]);

Prisma

Import the library

import pgvector from 'pgvector/utils';

Add the extension to the schema

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["postgresqlExtensions"]
}

datasource db {
  provider   = "postgresql"
  url        = env("DATABASE_URL")
  extensions = [vector]
}

Add a vector column to the schema

model Item {
  id        Int                       @id @default(autoincrement())
  embedding Unsupported("vector(3)")?
}

Insert a vector

const embedding = pgvector.toSql([1, 1, 1])
await prisma.$executeRaw`INSERT INTO items (embedding) VALUES (${embedding}::vector)`

Get the nearest neighbors to a vector

const embedding = pgvector.toSql([1, 1, 1])
const items = await prisma.$queryRaw`SELECT id, embedding::text FROM items ORDER BY embedding <-> ${embedding}::vector LIMIT 5`

Postgres.js

Import the library

import pgvector from 'pgvector/utils';

Enable the extension

await sql`CREATE EXTENSION IF NOT EXISTS vector`;

Create a table

await sql`CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))`;

Insert vectors

const newItems = [
  {embedding: pgvector.toSql([1, 2, 3])},
  {embedding: pgvector.toSql([4, 5, 6])}
];
await sql`INSERT INTO items ${ sql(newItems, 'embedding') }`;

Get the nearest neighbors to a vector

const embedding = pgvector.toSql([1, 2, 3]);
const items = await sql`SELECT * FROM items ORDER BY embedding <-> ${ embedding } LIMIT 5`;

Knex.js

Import the library

import pgvector from 'pgvector/utils';

Enable the extension

await knex.schema.raw('CREATE EXTENSION IF NOT EXISTS vector');

Create a table

await knex.schema.createTable('items', (table) => {
  table.increments('id');
  table.specificType('embedding', 'vector(3)');
});

Insert vectors

const newItems = [
  {embedding: pgvector.toSql([1, 2, 3])},
  {embedding: pgvector.toSql([4, 5, 6])}
];
await knex('items').insert(newItems);

Get the nearest neighbors to a vector

const items = await knex('items')
  .orderByRaw('embedding <-> ?', pgvector.toSql([1, 2, 3]))
  .limit(5);

Drizzle ORM

Note: This is currently experimental and does not work with Drizzle Kit

Enable the extension

await client`CREATE EXTENSION IF NOT EXISTS vector`;

Add a vector field

import { vector } from 'pgvector/drizzle-orm';

const items = pgTable('items', {
  id: serial('id').primaryKey(),
  embedding: vector('embedding', {dimensions: 3})
});

Insert vectors

const newItems = [
  {embedding: [1, 2, 3]},
  {embedding: [4, 5, 6]}
];
await db.insert(items).values(newItems);

Get the nearest neighbors to a vector

import { l2Distance } from 'pgvector/drizzle-orm';

const embedding = [1, 2, 3];
const allItems = await db.select().from(items).orderBy(l2Distance(items.embedding, embedding)).limit(5);

Also supports maxInnerProduct and cosineDistance

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

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 migrate dev
npm test

About

pgvector support for Node.js (and TypeScript)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%