pgvector

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2025 License: MIT Imports: 9 Imported by: 176

README

pgvector-go

pgvector support for Go

Supports pgx, pg, Bun, Ent, GORM, and sqlx

Build Status

Getting Started

Run:

go get github.com/pgvector/pgvector-go

And follow the instructions for your database library:

Or check out some examples:

pgx

Import the packages

import (
    "github.com/pgvector/pgvector-go"
    pgxvec "github.com/pgvector/pgvector-go/pgx"
)

Enable the extension

_, err := conn.Exec(ctx, "CREATE EXTENSION IF NOT EXISTS vector")

Register the types with the connection

err := pgxvec.RegisterTypes(ctx, conn)

or the pool

config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
    return pgxvec.RegisterTypes(ctx, conn)
}

Create a table

_, err := conn.Exec(ctx, "CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))")

Insert a vector

_, err := conn.Exec(ctx, "INSERT INTO items (embedding) VALUES ($1)", pgvector.NewVector([]float32{1, 2, 3}))

Get the nearest neighbors to a vector

rows, err := conn.Query(ctx, "SELECT id FROM items ORDER BY embedding <-> $1 LIMIT 5", pgvector.NewVector([]float32{1, 2, 3}))

Add an approximate index

_, err := conn.Exec(ctx, "CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)")
// or
_, err := conn.Exec(ctx, "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

pg

Import the package

import "github.com/pgvector/pgvector-go"

Enable the extension

_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS vector")

Add a vector column

type Item struct {
    Embedding pgvector.Vector `pg:"type:vector(3)"`
}

Insert a vector

item := Item{
    Embedding: pgvector.NewVector([]float32{1, 2, 3}),
}
_, err := db.Model(&item).Insert()

Get the nearest neighbors to a vector

var items []Item
err := db.Model(&items).
    OrderExpr("embedding <-> ?", pgvector.NewVector([]float32{1, 2, 3})).
    Limit(5).
    Select()

Add an approximate index

_, err := conn.Exec(ctx, "CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)")
// or
_, err := conn.Exec(ctx, "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

Bun

Import the package

import "github.com/pgvector/pgvector-go"

Enable the extension

_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS vector")

Add a vector column

type Item struct {
    Embedding pgvector.Vector `bun:"type:vector(3)"`
}

Insert a vector

item := Item{
    Embedding: pgvector.NewVector([]float32{1, 2, 3}),
}
_, err := db.NewInsert().Model(&item).Exec(ctx)

Get the nearest neighbors to a vector

var items []Item
err := db.NewSelect().
    Model(&items).
    OrderExpr("embedding <-> ?", pgvector.NewVector([]float32{1, 2, 3})).
    Limit(5).
    Scan(ctx)

Add an approximate index

var _ bun.AfterCreateTableHook = (*Item)(nil)

func (*Item) AfterCreateTable(ctx context.Context, query *bun.CreateTableQuery) error {
    _, err := query.DB().NewCreateIndex().
        Model((*Item)(nil)).
        Index("items_embedding_idx").
        ColumnExpr("embedding vector_l2_ops").
        Using("hnsw").
        Exec(ctx)
    return err
}

Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance

See a full example

Ent

Import the package

import "github.com/pgvector/pgvector-go"
import entvec "github.com/pgvector/pgvector-go/ent"

Enable the extension (requires the sql/execquery feature)

_, err := client.ExecContext(ctx, "CREATE EXTENSION IF NOT EXISTS vector")

Add a vector column

func (Item) Fields() []ent.Field {
    return []ent.Field{
        field.Other("embedding", pgvector.Vector{}).
            SchemaType(map[string]string{
                dialect.Postgres: "vector(3)",
            }),
    }
}

Insert a vector

_, err := client.Item.
    Create().
    SetEmbedding(pgvector.NewVector([]float32{1, 2, 3})).
    Save(ctx)

Get the nearest neighbors to a vector

items, err := client.Item.
    Query().
    Order(func(s *sql.Selector) {
        s.OrderExpr(entvec.L2Distance("embedding", pgvector.NewVector([]float32{1, 2, 3})))
    }).
    Limit(5).
    All(ctx)

Also supports MaxInnerProduct, CosineDistance, L1Distance, HammingDistance, and JaccardDistance

Add an approximate index

func (Item) Indexes() []ent.Index {
    return []ent.Index{
        index.Fields("embedding").
            Annotations(
                entsql.IndexType("hnsw"),
                entsql.OpClass("vector_l2_ops"),
            ),
    }
}

Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance

See a full example

GORM

Import the package

import "github.com/pgvector/pgvector-go"

Enable the extension

db.Exec("CREATE EXTENSION IF NOT EXISTS vector")

Add a vector column

type Item struct {
    Embedding pgvector.Vector `gorm:"type:vector(3)"`
}

Insert a vector

item := Item{
    Embedding: pgvector.NewVector([]float32{1, 2, 3}),
}
result := db.Create(&item)

Get the nearest neighbors to a vector

var items []Item
db.Clauses(clause.OrderBy{
    Expression: clause.Expr{SQL: "embedding <-> ?", Vars: []interface{}{pgvector.NewVector([]float32{1, 1, 1})}},
}).Limit(5).Find(&items)

Add an approximate index

db.Exec("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)")
// or
db.Exec("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

sqlx

Import the package

import "github.com/pgvector/pgvector-go"

Enable the extension

db.MustExec("CREATE EXTENSION IF NOT EXISTS vector")

Add a vector column

type Item struct {
    Embedding pgvector.Vector
}

Insert a vector

item := Item{
    Embedding: pgvector.NewVector([]float32{1, 2, 3}),
}
_, err := db.NamedExec(`INSERT INTO items (embedding) VALUES (:embedding)`, item)

Get the nearest neighbors to a vector

var items []Item
db.Select(&items, "SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5", pgvector.NewVector([]float32{1, 1, 1}))

Add an approximate index

db.MustExec("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)")
// or
db.MustExec("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

Reference

Vectors

Create a vector from a slice

vec := pgvector.NewVector([]float32{1, 2, 3})

Get a slice

slice := vec.Slice()
Half Vectors

Create a half vector from a slice

vec := pgvector.NewHalfVector([]float32{1, 2, 3})

Get a slice

slice := vec.Slice()
Sparse Vectors

Create a sparse vector from a slice

vec := pgvector.NewSparseVector([]float32{1, 0, 2, 0, 3, 0})

Or a map of non-zero elements

elements := map[int32]float32{0: 1, 2: 2, 4: 3}
vec := pgvector.NewSparseVectorFromMap(elements, 6)

Note: Indices start at 0

Get the number of dimensions

dim := vec.Dimensions()

Get the indices of non-zero elements

indices := vec.Indices()

Get the values of non-zero elements

values := vec.Values()

Get a slice

slice := vec.Slice()

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-go.git
cd pgvector-go
go mod tidy
createdb pgvector_go_test
go generate ./test/ent
go test -v

To run an example:

createdb pgvector_example
go run ./examples/loading

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HalfVector added in v0.2.0

type HalfVector struct {
	// contains filtered or unexported fields
}

HalfVector is a wrapper for []float32 to implement sql.Scanner and driver.Valuer.

func NewHalfVector added in v0.2.0

func NewHalfVector(vec []float32) HalfVector

NewHalfVector creates a new HalfVector from a slice of float32.

func (HalfVector) EncodeText added in v0.2.1

func (v HalfVector) EncodeText(buf []byte) (newBuf []byte, err error)

EncodeText encodes a text representation of the half vector.

func (HalfVector) MarshalJSON added in v0.2.0

func (v HalfVector) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*HalfVector) Parse added in v0.2.0

func (v *HalfVector) Parse(s string) error

Parse parses a string representation of a half vector.

func (*HalfVector) Scan added in v0.2.0

func (v *HalfVector) Scan(src interface{}) (err error)

Scan implements the sql.Scanner interface.

func (*HalfVector) SetSlice added in v0.3.0

func (v *HalfVector) SetSlice(vec []float32)

SetSlice sets the underlying slice of float32.

func (HalfVector) Slice added in v0.2.0

func (v HalfVector) Slice() []float32

Slice returns the underlying slice of float32.

func (HalfVector) String added in v0.2.0

func (v HalfVector) String() string

String returns a string representation of the half vector.

func (*HalfVector) UnmarshalJSON added in v0.2.0

func (v *HalfVector) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (HalfVector) Value added in v0.2.0

func (v HalfVector) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

type SparseVector added in v0.2.0

type SparseVector struct {
	// contains filtered or unexported fields
}

SparseVector is a wrapper to implement sql.Scanner and driver.Valuer.

func NewSparseVector added in v0.2.0

func NewSparseVector(vec []float32) SparseVector

NewSparseVector creates a new SparseVector from a slice of float32.

func NewSparseVectorFromMap added in v0.2.0

func NewSparseVectorFromMap(elements map[int32]float32, dim int32) SparseVector

NewSparseVectorFromMap creates a new SparseVector from a map of non-zero elements.

func (*SparseVector) DecodeBinary added in v0.2.1

func (v *SparseVector) DecodeBinary(buf []byte) error

DecodeBinary decodes a binary representation of a sparse vector.

func (SparseVector) Dimensions added in v0.2.0

func (v SparseVector) Dimensions() int32

Dimensions returns the number of dimensions.

func (SparseVector) EncodeBinary added in v0.2.1

func (v SparseVector) EncodeBinary(buf []byte) (newBuf []byte, err error)

EncodeBinary encodes a binary representation of the sparse vector.

func (SparseVector) Indices added in v0.2.0

func (v SparseVector) Indices() []int32

Indices returns the non-zero indices.

func (*SparseVector) Parse added in v0.2.0

func (v *SparseVector) Parse(s string) error

Parse parses a string representation of a sparse vector.

func (*SparseVector) Scan added in v0.2.0

func (v *SparseVector) Scan(src interface{}) (err error)

Scan implements the sql.Scanner interface.

func (SparseVector) Slice added in v0.2.0

func (v SparseVector) Slice() []float32

Slice returns a slice of float32.

func (SparseVector) String added in v0.2.0

func (v SparseVector) String() string

String returns a string representation of the sparse vector.

func (SparseVector) Value added in v0.2.0

func (v SparseVector) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

func (SparseVector) Values added in v0.2.0

func (v SparseVector) Values() []float32

Values returns the non-zero values.

type Vector

type Vector struct {
	// contains filtered or unexported fields
}

Vector is a wrapper for []float32 to implement sql.Scanner and driver.Valuer.

func NewVector

func NewVector(vec []float32) Vector

NewVector creates a new Vector from a slice of float32.

func (*Vector) DecodeBinary added in v0.2.1

func (v *Vector) DecodeBinary(buf []byte) error

DecodeBinary decodes a binary representation of a vector.

func (Vector) EncodeBinary added in v0.2.1

func (v Vector) EncodeBinary(buf []byte) (newBuf []byte, err error)

EncodeBinary encodes a binary representation of the vector.

func (Vector) MarshalJSON added in v0.2.0

func (v Vector) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Vector) Parse

func (v *Vector) Parse(s string) error

Parse parses a string representation of a vector.

func (*Vector) Scan

func (v *Vector) Scan(src interface{}) (err error)

Scan implements the sql.Scanner interface.

func (Vector) Slice

func (v Vector) Slice() []float32

Slice returns the underlying slice of float32.

func (Vector) String

func (v Vector) String() string

String returns a string representation of the vector.

func (*Vector) UnmarshalJSON added in v0.2.0

func (v *Vector) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (Vector) Value

func (v Vector) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

Directories

Path Synopsis
examples
citus command
cohere command
disco command
hybrid command
loading command
openai command
sparse command
test
ent

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL