fix(go.sum): update ResolveSpec dependency to v1.0.87
This commit is contained in:
+483
@@ -0,0 +1,483 @@
|
||||
# pgvector-go
|
||||
|
||||
[pgvector](https://github.com/pgvector/pgvector) support for Go
|
||||
|
||||
Supports [pgx](https://github.com/jackc/pgx), [pg](https://github.com/go-pg/pg), [Bun](https://github.com/uptrace/bun), [Ent](https://github.com/ent/ent), [GORM](https://github.com/go-gorm/gorm), and [sqlx](https://github.com/jmoiron/sqlx)
|
||||
|
||||
[](https://github.com/pgvector/pgvector-go/actions)
|
||||
|
||||
## Getting Started
|
||||
|
||||
Run:
|
||||
|
||||
```sh
|
||||
go get github.com/pgvector/pgvector-go
|
||||
```
|
||||
|
||||
And follow the instructions for your database library:
|
||||
|
||||
- [pgx](#pgx)
|
||||
- [pg](#pg)
|
||||
- [Bun](#bun)
|
||||
- [Ent](#ent)
|
||||
- [GORM](#gorm)
|
||||
- [sqlx](#sqlx)
|
||||
|
||||
Or check out some examples:
|
||||
|
||||
- [Embeddings](examples/openai/main.go) with OpenAI
|
||||
- [Binary embeddings](examples/cohere/main.go) with Cohere
|
||||
- [Hybrid search](examples/hybrid/main.go) with Ollama (Reciprocal Rank Fusion)
|
||||
- [Sparse search](examples/sparse/main.go) with Text Embeddings Inference
|
||||
- [Recommendations](examples/disco/main.go) with Disco
|
||||
- [Horizontal scaling](examples/citus/main.go) with Citus
|
||||
- [Bulk loading](examples/loading/main.go) with `COPY`
|
||||
|
||||
## pgx
|
||||
|
||||
Import the packages
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/pgvector/pgvector-go"
|
||||
pgxvec "github.com/pgvector/pgvector-go/pgx"
|
||||
)
|
||||
```
|
||||
|
||||
Enable the extension
|
||||
|
||||
```go
|
||||
_, err := conn.Exec(ctx, "CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Register the types with the connection
|
||||
|
||||
```go
|
||||
err := pgxvec.RegisterTypes(ctx, conn)
|
||||
```
|
||||
|
||||
or the pool
|
||||
|
||||
```go
|
||||
config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
|
||||
return pgxvec.RegisterTypes(ctx, conn)
|
||||
}
|
||||
```
|
||||
|
||||
Create a table
|
||||
|
||||
```go
|
||||
_, err := conn.Exec(ctx, "CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))")
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
_, err := conn.Exec(ctx, "INSERT INTO items (embedding) VALUES ($1)", pgvector.NewVector([]float32{1, 2, 3}))
|
||||
```
|
||||
|
||||
Get the nearest neighbors to a vector
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
_, 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](pgx_test.go)
|
||||
|
||||
## pg
|
||||
|
||||
Import the package
|
||||
|
||||
```go
|
||||
import "github.com/pgvector/pgvector-go"
|
||||
```
|
||||
|
||||
Enable the extension
|
||||
|
||||
```go
|
||||
_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Add a vector column
|
||||
|
||||
```go
|
||||
type Item struct {
|
||||
Embedding pgvector.Vector `pg:"type:vector(3)"`
|
||||
}
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
item := Item{
|
||||
Embedding: pgvector.NewVector([]float32{1, 2, 3}),
|
||||
}
|
||||
_, err := db.Model(&item).Insert()
|
||||
```
|
||||
|
||||
Get the nearest neighbors to a vector
|
||||
|
||||
```go
|
||||
var items []Item
|
||||
err := db.Model(&items).
|
||||
OrderExpr("embedding <-> ?", pgvector.NewVector([]float32{1, 2, 3})).
|
||||
Limit(5).
|
||||
Select()
|
||||
```
|
||||
|
||||
Add an approximate index
|
||||
|
||||
```go
|
||||
_, 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_test.go)
|
||||
|
||||
## Bun
|
||||
|
||||
Import the package
|
||||
|
||||
```go
|
||||
import "github.com/pgvector/pgvector-go"
|
||||
```
|
||||
|
||||
Enable the extension
|
||||
|
||||
```go
|
||||
_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Add a vector column
|
||||
|
||||
```go
|
||||
type Item struct {
|
||||
Embedding pgvector.Vector `bun:"type:vector(3)"`
|
||||
}
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
item := Item{
|
||||
Embedding: pgvector.NewVector([]float32{1, 2, 3}),
|
||||
}
|
||||
_, err := db.NewInsert().Model(&item).Exec(ctx)
|
||||
```
|
||||
|
||||
Get the nearest neighbors to a vector
|
||||
|
||||
```go
|
||||
var items []Item
|
||||
err := db.NewSelect().
|
||||
Model(&items).
|
||||
OrderExpr("embedding <-> ?", pgvector.NewVector([]float32{1, 2, 3})).
|
||||
Limit(5).
|
||||
Scan(ctx)
|
||||
```
|
||||
|
||||
Add an approximate index
|
||||
|
||||
```go
|
||||
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](bun_test.go)
|
||||
|
||||
## Ent
|
||||
|
||||
Import the package
|
||||
|
||||
```go
|
||||
import "github.com/pgvector/pgvector-go"
|
||||
import entvec "github.com/pgvector/pgvector-go/ent"
|
||||
```
|
||||
|
||||
Enable the extension (requires the [sql/execquery](https://entgo.io/docs/feature-flags/#sql-raw-api) feature)
|
||||
|
||||
```go
|
||||
_, err := client.ExecContext(ctx, "CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Add a vector column
|
||||
|
||||
```go
|
||||
func (Item) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.Other("embedding", pgvector.Vector{}).
|
||||
SchemaType(map[string]string{
|
||||
dialect.Postgres: "vector(3)",
|
||||
}),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
_, err := client.Item.
|
||||
Create().
|
||||
SetEmbedding(pgvector.NewVector([]float32{1, 2, 3})).
|
||||
Save(ctx)
|
||||
```
|
||||
|
||||
Get the nearest neighbors to a vector
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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](ent_test.go)
|
||||
|
||||
## GORM
|
||||
|
||||
Import the package
|
||||
|
||||
```go
|
||||
import "github.com/pgvector/pgvector-go"
|
||||
```
|
||||
|
||||
Enable the extension
|
||||
|
||||
```go
|
||||
db.Exec("CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Add a vector column
|
||||
|
||||
```go
|
||||
type Item struct {
|
||||
Embedding pgvector.Vector `gorm:"type:vector(3)"`
|
||||
}
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
item := Item{
|
||||
Embedding: pgvector.NewVector([]float32{1, 2, 3}),
|
||||
}
|
||||
result := db.Create(&item)
|
||||
```
|
||||
|
||||
Get the nearest neighbors to a vector
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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](gorm_test.go)
|
||||
|
||||
## sqlx
|
||||
|
||||
Import the package
|
||||
|
||||
```go
|
||||
import "github.com/pgvector/pgvector-go"
|
||||
```
|
||||
|
||||
Enable the extension
|
||||
|
||||
```go
|
||||
db.MustExec("CREATE EXTENSION IF NOT EXISTS vector")
|
||||
```
|
||||
|
||||
Add a vector column
|
||||
|
||||
```go
|
||||
type Item struct {
|
||||
Embedding pgvector.Vector
|
||||
}
|
||||
```
|
||||
|
||||
Insert a vector
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
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](sqlx_test.go)
|
||||
|
||||
## Reference
|
||||
|
||||
### Vectors
|
||||
|
||||
Create a vector from a slice
|
||||
|
||||
```go
|
||||
vec := pgvector.NewVector([]float32{1, 2, 3})
|
||||
```
|
||||
|
||||
Get a slice
|
||||
|
||||
```go
|
||||
slice := vec.Slice()
|
||||
```
|
||||
|
||||
### Half Vectors
|
||||
|
||||
Create a half vector from a slice
|
||||
|
||||
```go
|
||||
vec := pgvector.NewHalfVector([]float32{1, 2, 3})
|
||||
```
|
||||
|
||||
Get a slice
|
||||
|
||||
```go
|
||||
slice := vec.Slice()
|
||||
```
|
||||
|
||||
### Sparse Vectors
|
||||
|
||||
Create a sparse vector from a slice
|
||||
|
||||
```go
|
||||
vec := pgvector.NewSparseVector([]float32{1, 0, 2, 0, 3, 0})
|
||||
```
|
||||
|
||||
Or a map of non-zero elements
|
||||
|
||||
```go
|
||||
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
|
||||
|
||||
```go
|
||||
dim := vec.Dimensions()
|
||||
```
|
||||
|
||||
Get the indices of non-zero elements
|
||||
|
||||
```go
|
||||
indices := vec.Indices()
|
||||
```
|
||||
|
||||
Get the values of non-zero elements
|
||||
|
||||
```go
|
||||
values := vec.Values()
|
||||
```
|
||||
|
||||
Get a slice
|
||||
|
||||
```go
|
||||
slice := vec.Slice()
|
||||
```
|
||||
|
||||
## History
|
||||
|
||||
View the [changelog](https://github.com/pgvector/pgvector-go/blob/master/CHANGELOG.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
||||
|
||||
- [Report bugs](https://github.com/pgvector/pgvector-go/issues)
|
||||
- Fix bugs and [submit pull requests](https://github.com/pgvector/pgvector-go/pulls)
|
||||
- Write, clarify, or fix documentation
|
||||
- Suggest or add new features
|
||||
|
||||
To get started with development:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```sh
|
||||
createdb pgvector_example
|
||||
go run ./examples/loading
|
||||
```
|
||||
Reference in New Issue
Block a user