A PGVector extension for Prisma
npm install prisma-extension-pgvector!GitHub Actions Workflow Status
prisma-extension-pgvector is a wrapper around the pgvector-node package
that provides a convenient, type-safe way to interact with databases which
support the pgvector vector-similarity search for Postgres databases.
Learn more in the pgvector andpgvector-node docs.
``bash`
npm i @prisma/client pgvector prisma-extension-pgvector
npm i -D prisma
npx prisma init
At the moment vector is a preview feature, so we need to enable it
`prisma highlight=3,9;add
generator client {
provider = "prisma-client-js"
previewFeatures = ["postgresqlExtensions"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
extensions = [vector]
}
`
Or create a whole new model for your vectors.
`prisma highlight=3;add`
model Item {
id String @id @default(cuid())
vector Unsupported("vector")?
}
Then create or update your client (usually prisma migrate dev).
Add the extension to your Prisma instantiation, and specify the name of the
model which has the vector field, as well as the name of the field.
`js`
const prisma = new PrismaClient().$extends(withPGVector({
modelName: 'item',
vectorFieldName: 'vector'
}));
The model
you use for the vector store must include an ID field, as with all Prisma
models.
Any ID usable for a generic Prisma model should be usable withprisma-extension-pgvector, but it must resolve to either a number orstring type.
Additionally, the model must have a Vector Field of type Unsupportedvector. The field may be optional in the schema, but one must be defined.vector Unsupported("vector")
You can also specify a Vector Field of specific or arbitary length. (e.g., or vector Unsupported("vector(1536)")).
Note: While it is permissable to have the Vector Field as optional
(e.g., vector Unsupported("vector")?), if you perform distance queries
and some records in your database actually have no vector data, you may get
unexpected results.
The documentation is built around the following schema:
`prisma file=schema.prisma showLineNumbers
generator client {
provider = "prisma-client-js"
previewFeatures = ["postgresqlExtensions"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
extensions = [vector]
}
model Vector {
id Int @id @default(autoincrement())
metadata Json?
testfield String?
embedding Unsupported("vector(3)")?
}
`
In addition addition to the usual Prisma installation, and of course
prisma-extension-pgvector, you will need to installpgvector.
`bash`
npm install prisma --save-dev
npm install @prisma/client
npm install pgvector
npm install prisma-extension-pgvector
When you instantiate a Prisma client with prisma-extension-pgvector,model
you need to specify which has the Vector Field, the name of theidFieldName
Vector Field, and the name of the ID field ( is optional, id
and will default to ).
`js
import { PrismaClient } from '@prisma/client';
import { withPGVector } from 'prisma-extension-pgvector';
const prisma = new PrismaClient().$extends(withPGVector({
modelName: 'vector',
vectorFieldName: 'embedding',
idFieldName: 'id'
}));
`
Model-specific methods for the unsupported vector field type are
documented here. You can get an array
of vectors from the database by id with, for example,
`js`
const vectors = await prisma.vector.getVectorsById({
where: {
id: { in: [ 1 ] }
}
})
You can also perform nearest a nearest neighbor search:
`js`
const neighbors = await prisma.vector.findNearestNeighbors({
from: [1, 1, 1],
orderBy: 'L2'
})
Valid distance metrics for orderBy are L2 (default), InnerProduct,Cosine, L1. See PGVector Querying.
Some of the native Prisma client methods have been overridden to support
the vector field. Full documentation is here.
Currently there is support for create, createManyAndReturn, andfindMany.
Other native methods do not support the setting or retrieving of the vector
field (yet!). For example, while you can createManyAndReturn, createMany`
will currently result in an error if you try and set your vector field.
If you have a need for one of the other ones to be supported, feel free to
submit an issue, or, better, write one yourself!