mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 12:07:34 +08:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69672cd84d | ||
|
|
300adba2f1 | ||
|
|
e362279199 | ||
|
|
53301021f6 | ||
|
|
8f589f6d09 | ||
|
|
dcf206128a | ||
|
|
3244d40e8a | ||
|
|
7d8dbcaa3c | ||
|
|
7f575f55fb | ||
|
|
94e7487d5f | ||
|
|
74a3cd597f | ||
|
|
db8ed738b8 | ||
|
|
54c550420b | ||
|
|
cc539a0a27 | ||
|
|
d885e2bcfa | ||
|
|
a445355a48 | ||
|
|
d5b17a3624 | ||
|
|
6383078029 | ||
|
|
5146c7cc57 | ||
|
|
ac63f9858b | ||
|
|
76a4166857 | ||
|
|
31fb6963a3 | ||
|
|
18c06cb9b1 | ||
|
|
f858796c64 | ||
|
|
f32f695844 | ||
|
|
1b013a94f7 | ||
|
|
00148dfa1f | ||
|
|
67fc791d95 |
@@ -1,3 +1,9 @@
|
||||
## 0.4.2 (2023-05-13)
|
||||
|
||||
- Added notice when index created with little data
|
||||
- Fixed dimensions check for some direct function calls
|
||||
- Fixed installation error with Postgres 12.0-12.2
|
||||
|
||||
## 0.4.1 (2023-03-21)
|
||||
|
||||
- Improved performance of cosine distance
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "vector",
|
||||
"abstract": "Open-source vector similarity search for Postgres",
|
||||
"description": "Supports L2 distance, inner product, and cosine distance",
|
||||
"version": "0.4.1",
|
||||
"version": "0.4.2",
|
||||
"maintainer": [
|
||||
"Andrew Kane <andrew@ankane.org>"
|
||||
],
|
||||
@@ -20,7 +20,7 @@
|
||||
"vector": {
|
||||
"file": "sql/vector.sql",
|
||||
"docfile": "README.md",
|
||||
"version": "0.4.1",
|
||||
"version": "0.4.2",
|
||||
"abstract": "Open-source vector similarity search for Postgres"
|
||||
}
|
||||
},
|
||||
|
||||
8
Makefile
8
Makefile
@@ -1,5 +1,5 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.4.1
|
||||
EXTVERSION = 0.4.2
|
||||
|
||||
MODULE_big = vector
|
||||
DATA = $(wildcard sql/*--*.sql)
|
||||
@@ -63,3 +63,9 @@ dist:
|
||||
|
||||
docker:
|
||||
docker build --pull --no-cache --platform linux/amd64 -t ankane/pgvector:latest .
|
||||
|
||||
.PHONY: docker-release
|
||||
|
||||
docker-release:
|
||||
docker buildx build --push --pull --no-cache --platform linux/amd64,linux/arm64 -t ankane/pgvector:latest .
|
||||
docker buildx build --push --platform linux/amd64,linux/arm64 -t ankane/pgvector:v$(EXTVERSION) .
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.4.1
|
||||
EXTVERSION = 0.4.2
|
||||
|
||||
OBJS = src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\vector.obj
|
||||
|
||||
|
||||
55
README.md
55
README.md
@@ -2,7 +2,11 @@
|
||||
|
||||
Open-source vector similarity search for Postgres
|
||||
|
||||
Supports exact and approximate nearest neighbor search for L2 distance, inner product, and cosine distance
|
||||
Supports
|
||||
|
||||
- exact and approximate nearest neighbor search
|
||||
- L2 distance, inner product, and cosine distance
|
||||
- any [language](#languages) with a Postgres client
|
||||
|
||||
[](https://github.com/pgvector/pgvector/actions)
|
||||
|
||||
@@ -12,7 +16,7 @@ Compile and install the extension (supports Postgres 11+)
|
||||
|
||||
```sh
|
||||
cd /tmp
|
||||
git clone --branch v0.4.1 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.4.2 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
make install # may need sudo
|
||||
@@ -36,7 +40,7 @@ Create a vector column with 3 dimensions
|
||||
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
|
||||
```
|
||||
|
||||
Insert values
|
||||
Insert vectors
|
||||
|
||||
```sql
|
||||
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
|
||||
@@ -124,7 +128,7 @@ SELECT embedding <-> '[3,1,2]' AS distance FROM items;
|
||||
For inner product, multiply by -1 (since `<#>` returns the negative inner product)
|
||||
|
||||
```sql
|
||||
SELECT -1 * (embedding <#> '[3,1,2]') AS inner_product FROM items;
|
||||
SELECT (embedding <#> '[3,1,2]') * -1 AS inner_product FROM items;
|
||||
```
|
||||
|
||||
For cosine similarity, use 1 - cosine distance
|
||||
@@ -133,7 +137,7 @@ For cosine similarity, use 1 - cosine distance
|
||||
SELECT 1 - (embedding <=> '[3,1,2]') AS cosine_similarity FROM items;
|
||||
```
|
||||
|
||||
#### Averaging
|
||||
#### Aggregates
|
||||
|
||||
Average vectors
|
||||
|
||||
@@ -153,15 +157,11 @@ By default, pgvector performs exact nearest neighbor search, which provides perf
|
||||
|
||||
You can add an index to use approximate nearest neighbor search, which trades some recall for performance. Unlike typical indexes, you will see different results for queries after adding an approximate index.
|
||||
|
||||
Two keys to achieving good recall are:
|
||||
Three keys to achieving good recall are:
|
||||
|
||||
1. Create the index *after* the table has some data
|
||||
2. Choose an appropriate number of lists (lower is better for recall, higher is better for speed)
|
||||
|
||||
A good place to start is:
|
||||
|
||||
- `rows / 1000` for up to 1M rows
|
||||
- `sqrt(rows)` for over 1M rows
|
||||
2. Choose an appropriate number of lists - a good place to start is `rows / 1000` for up to 1M rows and `sqrt(rows)` for over 1M rows
|
||||
3. When querying, specify an appropriate number of [probes](#query-options) (higher is better for recall, lower is better for speed) - a good place to start is `lists / 10` for up to 1M rows and `sqrt(lists)` for over 1M rows
|
||||
|
||||
Add an index for each distance function you want to use.
|
||||
|
||||
@@ -190,7 +190,7 @@ Vectors with up to 2,000 dimensions can be indexed.
|
||||
Specify the number of probes (1 by default)
|
||||
|
||||
```sql
|
||||
SET ivfflat.probes = 1;
|
||||
SET ivfflat.probes = 10;
|
||||
```
|
||||
|
||||
A higher value provides better recall at the cost of speed, and it can be set to the number of lists for exact nearest neighbor search (at which point the planner won’t use the index)
|
||||
@@ -199,7 +199,7 @@ Use `SET LOCAL` inside a transaction to set it for a single query
|
||||
|
||||
```sql
|
||||
BEGIN;
|
||||
SET LOCAL ivfflat.probes = 1;
|
||||
SET LOCAL ivfflat.probes = 10;
|
||||
SELECT ...
|
||||
COMMIT;
|
||||
```
|
||||
@@ -279,8 +279,10 @@ Language | Libraries / Examples
|
||||
--- | ---
|
||||
C++ | [pgvector-cpp](https://github.com/pgvector/pgvector-cpp)
|
||||
C# | [pgvector-dotnet](https://github.com/pgvector/pgvector-dotnet)
|
||||
Crystal | [pgvector-crystal](https://github.com/pgvector/pgvector-crystal)
|
||||
Elixir | [pgvector-elixir](https://github.com/pgvector/pgvector-elixir)
|
||||
Go | [pgvector-go](https://github.com/pgvector/pgvector-go)
|
||||
Haskell | [pgvector-haskell](https://github.com/pgvector/pgvector-haskell)
|
||||
Java, Scala | [pgvector-java](https://github.com/pgvector/pgvector-java)
|
||||
Julia | [pgvector-julia](https://github.com/pgvector/pgvector-julia)
|
||||
Lua | [pgvector-lua](https://github.com/pgvector/pgvector-lua)
|
||||
@@ -291,6 +293,7 @@ Python | [pgvector-python](https://github.com/pgvector/pgvector-python)
|
||||
R | [pgvector-r](https://github.com/pgvector/pgvector-r)
|
||||
Ruby | [pgvector-ruby](https://github.com/pgvector/pgvector-ruby), [Neighbor](https://github.com/ankane/neighbor)
|
||||
Rust | [pgvector-rust](https://github.com/pgvector/pgvector-rust)
|
||||
Swift | [pgvector-swift](https://github.com/pgvector/pgvector-swift)
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
@@ -304,10 +307,11 @@ Yes, pgvector uses the write-ahead log (WAL), which allows for replication and p
|
||||
|
||||
#### What if I want to index vectors with more than 2,000 dimensions?
|
||||
|
||||
Two things you can try are:
|
||||
You’ll need to use [dimensionality reduction](https://en.wikipedia.org/wiki/Dimensionality_reduction) at the moment.
|
||||
|
||||
1. use dimensionality reduction
|
||||
2. compile Postgres with a larger block size (`./configure --with-blocksize=32`) and edit the limit in `src/ivfflat.h`
|
||||
#### Why am I seeing less results after adding an index?
|
||||
|
||||
The index was likely created with too little data for the number of lists. Drop the index until the table has more data.
|
||||
|
||||
## Reference
|
||||
|
||||
@@ -351,7 +355,11 @@ If your machine has multiple Postgres installations, specify the path to [pg_con
|
||||
export PG_CONFIG=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config
|
||||
```
|
||||
|
||||
Then re-run the installation instructions (run `make clean` before `make` if needed)
|
||||
Then re-run the installation instructions (run `make clean` before `make` if needed). If `sudo` is needed for `make install`, use:
|
||||
|
||||
```sh
|
||||
sudo --preserve-env=PG_CONFIG make install
|
||||
```
|
||||
|
||||
### Missing Header
|
||||
|
||||
@@ -371,7 +379,7 @@ Support for Windows is currently experimental. Use `nmake` to build:
|
||||
|
||||
```cmd
|
||||
set "PGROOT=C:\Program Files\PostgreSQL\15"
|
||||
git clone --branch v0.4.1 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.4.2 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
nmake /F Makefile.win
|
||||
nmake /F Makefile.win install
|
||||
@@ -392,7 +400,7 @@ This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres) (r
|
||||
You can also build the image manually:
|
||||
|
||||
```sh
|
||||
git clone --branch v0.4.1 https://github.com/pgvector/pgvector.git
|
||||
git clone --branch v0.4.2 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
docker build -t pgvector .
|
||||
```
|
||||
@@ -405,6 +413,8 @@ With Homebrew Postgres, you can use:
|
||||
brew install pgvector
|
||||
```
|
||||
|
||||
Note: This only adds it to the `postgresql@14` formula
|
||||
|
||||
### PGXN
|
||||
|
||||
Install from the [PostgreSQL Extension Network](https://pgxn.org/dist/vector) with:
|
||||
@@ -441,11 +451,10 @@ pgvector is available on [these providers](https://github.com/pgvector/pgvector/
|
||||
|
||||
To request a new extension on other providers:
|
||||
|
||||
- Amazon RDS - follow the instructions on [this page](https://aws.amazon.com/rds/postgresql/faqs/)
|
||||
- Google Cloud SQL - vote or comment on [this page](https://issuetracker.google.com/issues/265172065)
|
||||
- Azure Database - vote or comment on [this page](https://feedback.azure.com/d365community/idea/7b423322-6189-ed11-a81b-000d3ae49307)
|
||||
- DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/app-framework-services/p/pgvector-extension-for-postgresql)
|
||||
- Render - vote or comment on [this page](https://feedback.render.com/features/p/add-pgvector-extension-to-postgresql)
|
||||
- DigitalOcean Managed Databases - vote or comment on [this page](https://ideas.digitalocean.com/managed-database/p/pgvector-extension-for-postgresql)
|
||||
- Heroku Postgres - vote or comment on [this page](https://github.com/heroku/roadmap/issues/156)
|
||||
|
||||
## Upgrading
|
||||
|
||||
|
||||
2
sql/vector--0.4.1--0.4.2.sql
Normal file
2
sql/vector--0.4.1--0.4.2.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION vector UPDATE TO '0.4.2'" to load this file. \quit
|
||||
@@ -431,8 +431,18 @@ ComputeCenters(IvfflatBuildState * buildstate)
|
||||
/* TODO Ensure within maintenance_work_mem */
|
||||
buildstate->samples = VectorArrayInit(numSamples, buildstate->dimensions);
|
||||
if (buildstate->heap != NULL)
|
||||
{
|
||||
SampleRows(buildstate);
|
||||
|
||||
if (buildstate->samples->length < buildstate->lists)
|
||||
{
|
||||
ereport(NOTICE,
|
||||
(errmsg("ivfflat index created with little data"),
|
||||
errdetail("This will cause low recall."),
|
||||
errhint("Drop the index until the table has more data.")));
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate centers */
|
||||
IvfflatBench("k-means", IvfflatKmeans(buildstate->index, buildstate->samples, buildstate->centers));
|
||||
|
||||
|
||||
@@ -174,8 +174,8 @@ GetScanItems(IndexScanDesc scan, Datum value)
|
||||
if (tuples < 100)
|
||||
ereport(DEBUG1,
|
||||
(errmsg("index scan found few tuples"),
|
||||
errdetail("index may have been created without data or lists is too high"),
|
||||
errhint("recreate the index and possibly decrease lists")));
|
||||
errdetail("Index may have been created with little data."),
|
||||
errhint("Recreate the index and possibly decrease lists.")));
|
||||
|
||||
tuplesort_performsort(so->sortstate);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ CheckStateArray(ArrayType *statearray, const char *caller)
|
||||
return (float8 *) ARR_DATA_PTR(statearray);
|
||||
}
|
||||
|
||||
#if PG_VERSION_NUM < 120000
|
||||
#if PG_VERSION_NUM < 120003
|
||||
static pg_noinline void
|
||||
float_overflow_error(void)
|
||||
{
|
||||
@@ -396,10 +396,8 @@ array_to_vector(PG_FUNCTION_ARGS)
|
||||
get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign);
|
||||
deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, &nullsp, &nelemsp);
|
||||
|
||||
if (typmod == -1)
|
||||
CheckDim(nelemsp);
|
||||
else
|
||||
CheckExpectedDim(typmod, nelemsp);
|
||||
CheckDim(nelemsp);
|
||||
CheckExpectedDim(typmod, nelemsp);
|
||||
|
||||
result = InitVector(nelemsp);
|
||||
for (i = 0; i < nelemsp; i++)
|
||||
@@ -952,6 +950,7 @@ vector_avg(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Create vector */
|
||||
dim = STATE_DIMS(statearray);
|
||||
CheckDim(dim);
|
||||
result = InitVector(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,8 @@ SELECT '[1,2,3]'::vector::real[];
|
||||
|
||||
SELECT array_agg(n)::vector FROM generate_series(1, 16001) n;
|
||||
ERROR: vector cannot have more than 16000 dimensions
|
||||
SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n;
|
||||
ERROR: vector cannot have more than 16000 dimensions
|
||||
-- ensure no error
|
||||
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];
|
||||
?column?
|
||||
|
||||
@@ -102,3 +102,5 @@ SELECT avg(v) FROM unnest(ARRAY[]::vector[]) v;
|
||||
|
||||
SELECT avg(v) FROM unnest(ARRAY['[1,2]'::vector, '[3]']) v;
|
||||
ERROR: expected 2 dimensions, not 1
|
||||
SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n;
|
||||
ERROR: vector cannot have more than 16000 dimensions
|
||||
|
||||
@@ -10,6 +10,7 @@ SELECT '{-Infinity}'::real[]::vector;
|
||||
SELECT '{}'::real[]::vector;
|
||||
SELECT '[1,2,3]'::vector::real[];
|
||||
SELECT array_agg(n)::vector FROM generate_series(1, 16001) n;
|
||||
SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n;
|
||||
|
||||
-- ensure no error
|
||||
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];
|
||||
|
||||
@@ -24,3 +24,4 @@ SELECT avg(v) FROM unnest(ARRAY['[1,2,3]'::vector, '[3,5,7]']) v;
|
||||
SELECT avg(v) FROM unnest(ARRAY['[1,2,3]'::vector, '[3,5,7]', NULL]) v;
|
||||
SELECT avg(v) FROM unnest(ARRAY[]::vector[]) v;
|
||||
SELECT avg(v) FROM unnest(ARRAY['[1,2]'::vector, '[3]']) v;
|
||||
SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
comment = 'vector data type and ivfflat access method'
|
||||
default_version = '0.4.1'
|
||||
default_version = '0.4.2'
|
||||
module_pathname = '$libdir/vector'
|
||||
relocatable = true
|
||||
|
||||
Reference in New Issue
Block a user