Compare commits

...

13 Commits

Author SHA1 Message Date
Andrew Kane
647c9002be Version bump to 0.2.1 [skip ci] 2022-01-02 19:11:37 -05:00
Andrew Kane
3e6345f02a Moved function 2022-01-02 19:09:37 -05:00
Andrew Kane
2b3484ddcd Fixed CI 2022-01-02 19:03:15 -05:00
Andrew Kane
1a6debf281 Fixed operator is not unique error - fixes #20 2022-01-02 18:47:03 -05:00
Andrew Kane
bff4d7ea68 Updated link [skip ci] 2021-10-13 14:29:09 -07:00
Andrew Kane
d5b979e4fa Added guidance on lists [skip ci] 2021-10-13 14:27:01 -07:00
Andrew Kane
d52426b3fa Improved examples [skip ci] 2021-10-13 14:06:55 -07:00
Andrew Kane
b125b2debb Added section on performance [skip ci] 2021-10-13 13:56:03 -07:00
Andrew Kane
3d7186a17c Added Docker to Makefile [skip ci] 2021-10-13 13:53:29 -07:00
Andrew Kane
58ba2139ce Added instructions for reindexing - #17 [skip ci] 2021-10-13 13:48:54 -07:00
Andrew Kane
fd93c9db86 Version bump to 0.2.0 [skip ci] 2021-10-03 20:32:45 -07:00
Andrew Kane
8dde26920c Added support for Postgres 14 2021-09-30 16:28:25 -07:00
Andrew Kane
9153a545a7 Added link to pgvector-cpp [skip ci] 2021-09-10 15:22:44 -07:00
14 changed files with 105 additions and 28 deletions

View File

@@ -8,10 +8,10 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-latest]
postgres: [13, 12, 11, 10, 9.6] postgres: [14, 13, 12, 11, 10, 9.6]
include: include:
- os: macos-latest - os: macos-latest
postgres: 13 postgres: 14
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: ankane/setup-postgres@v1 - uses: ankane/setup-postgres@v1

View File

@@ -1,3 +1,11 @@
## 0.2.1 (unreleased)
- Fixed `operator is not unique` error
## 0.2.0 (2021-10-03)
- Added support for Postgres 14
## 0.1.8 (2021-09-07) ## 0.1.8 (2021-09-07)
- Added cast for `vector` to `real[]` - Added cast for `vector` to `real[]`

View File

@@ -1,9 +1,9 @@
FROM postgres FROM postgres:14
COPY . /tmp/pgvector COPY . /tmp/pgvector
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential postgresql-server-dev-13 && \ apt-get install -y --no-install-recommends build-essential postgresql-server-dev-14 && \
cd /tmp/pgvector && \ cd /tmp/pgvector && \
make clean && \ make clean && \
make OPTFLAGS="" && \ make OPTFLAGS="" && \
@@ -11,6 +11,6 @@ RUN apt-get update && \
mkdir /usr/share/doc/pgvector && \ mkdir /usr/share/doc/pgvector && \
cp LICENSE README.md /usr/share/doc/pgvector && \ cp LICENSE README.md /usr/share/doc/pgvector && \
rm -r /tmp/pgvector && \ rm -r /tmp/pgvector && \
apt-get remove -y build-essential postgresql-server-dev-13 && \ apt-get remove -y build-essential postgresql-server-dev-14 && \
apt-get autoremove -y && \ apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*

View File

@@ -2,7 +2,7 @@
"name": "vector", "name": "vector",
"abstract": "Open-source vector similarity search for Postgres", "abstract": "Open-source vector similarity search for Postgres",
"description": "Supports L2 distance, inner product, and cosine distance", "description": "Supports L2 distance, inner product, and cosine distance",
"version": "0.1.8", "version": "0.2.1",
"maintainer": [ "maintainer": [
"Andrew Kane <andrew@ankane.org>" "Andrew Kane <andrew@ankane.org>"
], ],
@@ -20,7 +20,7 @@
"vector": { "vector": {
"file": "sql/vector.sql", "file": "sql/vector.sql",
"docfile": "README.md", "docfile": "README.md",
"version": "0.1.8", "version": "0.2.1",
"abstract": "Open-source vector similarity search for Postgres" "abstract": "Open-source vector similarity search for Postgres"
} }
}, },

View File

@@ -1,5 +1,5 @@
EXTENSION = vector EXTENSION = vector
EXTVERSION = 0.1.8 EXTVERSION = 0.2.1
MODULE_big = vector MODULE_big = vector
DATA = $(wildcard sql/*--*.sql) DATA = $(wildcard sql/*--*.sql)
@@ -42,3 +42,8 @@ prove_installcheck:
dist: dist:
mkdir -p dist mkdir -p dist
git archive --format zip --prefix=$(EXTENSION)-$(EXTVERSION)/ --output dist/$(EXTENSION)-$(EXTVERSION).zip master git archive --format zip --prefix=$(EXTENSION)-$(EXTVERSION)/ --output dist/$(EXTENSION)-$(EXTVERSION).zip master
.PHONY: docker
docker:
docker build --pull --no-cache -t ankane/pgvector:latest .

View File

@@ -4,7 +4,7 @@ Open-source vector similarity search for Postgres
```sql ```sql
CREATE TABLE table (column vector(3)); CREATE TABLE table (column vector(3));
CREATE INDEX ON table USING ivfflat (column); CREATE INDEX ON table USING ivfflat (column vector_l2_ops);
SELECT * FROM table ORDER BY column <-> '[1,2,3]' LIMIT 5; SELECT * FROM table ORDER BY column <-> '[1,2,3]' LIMIT 5;
``` ```
@@ -17,7 +17,7 @@ Supports L2 distance, inner product, and cosine distance
Compile and install the extension (supports Postgres 9.6+) Compile and install the extension (supports Postgres 9.6+)
```sh ```sh
git clone --branch v0.1.8 https://github.com/ankane/pgvector.git git clone --branch v0.2.1 https://github.com/ankane/pgvector.git
cd pgvector cd pgvector
make make
make install # may need sudo make install # may need sudo
@@ -62,7 +62,7 @@ Speed up queries with an approximate index. Add an index for each distance funct
L2 distance L2 distance
```sql ```sql
CREATE INDEX ON table USING ivfflat (column); CREATE INDEX ON table USING ivfflat (column vector_l2_ops);
``` ```
Inner product Inner product
@@ -77,16 +77,30 @@ Cosine distance
CREATE INDEX ON table USING ivfflat (column vector_cosine_ops); CREATE INDEX ON table USING ivfflat (column vector_cosine_ops);
``` ```
Indexes should be created after the table has data for optimal clustering. Also, unlike typical indexes which only affect performance, you may see different results for queries after adding an approximate index. Indexes should be created after the table has data for optimal clustering. If the distribution of data changes significantly, you can reindex without downtime:
```sql
-- Postgres 12+
REINDEX INDEX CONCURRENTLY index_name;
-- Postgres < 12
CREATE INDEX CONCURRENTLY temp_name ON table USING ivfflat (column opclass);
DROP INDEX CONCURRENTLY index_name;
ALTER INDEX temp_name RENAME TO index_name;
```
Also, unlike typical indexes which only affect performance, you may see different results for queries after adding an approximate index.
### Index Options ### Index Options
Specify the number of inverted lists (100 by default) Specify the number of inverted lists (100 by default)
```sql ```sql
CREATE INDEX ON table USING ivfflat (column) WITH (lists = 100); CREATE INDEX ON table USING ivfflat (column opclass) WITH (lists = 100);
``` ```
A [good place to start](https://github.com/facebookresearch/faiss/issues/112) is `4 * sqrt(rows)`
### Query Options ### Query Options
Specify the number of probes (1 by default) Specify the number of probes (1 by default)
@@ -111,11 +125,25 @@ COMMIT;
Consider [partial indexes](https://www.postgresql.org/docs/current/indexes-partial.html) for queries with a `WHERE` clause Consider [partial indexes](https://www.postgresql.org/docs/current/indexes-partial.html) for queries with a `WHERE` clause
```sql ```sql
CREATE INDEX ON table USING ivfflat (column) WHERE (other_column = 123); CREATE INDEX ON table USING ivfflat (column opclass) WHERE (other_column = 123);
``` ```
To index many different values of `other_column`, consider [partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html) on `other_column`. To index many different values of `other_column`, consider [partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html) on `other_column`.
## Performance
To speed up queries without an index, increase `max_parallel_workers_per_gather`.
```sql
SET max_parallel_workers_per_gather = 4;
```
To speed up queries with an index, increase the number of inverted lists (at the expense of recall).
```sql
CREATE INDEX ON table USING ivfflat (column opclass) WITH (lists = 1000);
```
## Reference ## Reference
### Vector Type ### Vector Type
@@ -151,6 +179,7 @@ Libraries that use pgvector:
- [pgvector-node](https://github.com/ankane/pgvector-node) (Node.js) - [pgvector-node](https://github.com/ankane/pgvector-node) (Node.js)
- [pgvector-go](https://github.com/ankane/pgvector-go) (Go) - [pgvector-go](https://github.com/ankane/pgvector-go) (Go)
- [pgvector-rust](https://github.com/ankane/pgvector-rust) (Rust) - [pgvector-rust](https://github.com/ankane/pgvector-rust) (Rust)
- [pgvector-cpp](https://github.com/ankane/pgvector-cpp) (C++)
## Additional Installation Methods ## Additional Installation Methods
@@ -167,7 +196,7 @@ This adds pgvector to the [Postgres image](https://hub.docker.com/_/postgres).
You can also build the image manually You can also build the image manually
```sh ```sh
git clone --branch v0.1.8 https://github.com/ankane/pgvector.git git clone --branch v0.2.1 https://github.com/ankane/pgvector.git
cd pgvector cd pgvector
docker build -t pgvector . docker build -t pgvector .
``` ```

View 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.2.0'" to load this file. \quit

View File

@@ -0,0 +1,19 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION vector UPDATE TO '0.2.1'" to load this file. \quit
DROP CAST (integer[] AS vector);
DROP CAST (real[] AS vector);
DROP CAST (double precision[] AS vector);
DROP CAST (numeric[] AS vector);
CREATE CAST (integer[] AS vector)
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (real[] AS vector)
WITH FUNCTION array_to_vector(real[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (double precision[] AS vector)
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (numeric[] AS vector)
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS ASSIGNMENT;

View File

@@ -108,21 +108,21 @@ CREATE FUNCTION vector_to_float4(vector, integer, boolean) RETURNS real[]
CREATE CAST (vector AS vector) CREATE CAST (vector AS vector)
WITH FUNCTION vector(vector, integer, boolean) AS IMPLICIT; WITH FUNCTION vector(vector, integer, boolean) AS IMPLICIT;
CREATE CAST (integer[] AS vector)
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS IMPLICIT;
CREATE CAST (real[] AS vector)
WITH FUNCTION array_to_vector(real[], integer, boolean) AS IMPLICIT;
CREATE CAST (double precision[] AS vector)
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS IMPLICIT;
CREATE CAST (numeric[] AS vector)
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS IMPLICIT;
CREATE CAST (vector AS real[]) CREATE CAST (vector AS real[])
WITH FUNCTION vector_to_float4(vector, integer, boolean) AS IMPLICIT; WITH FUNCTION vector_to_float4(vector, integer, boolean) AS IMPLICIT;
CREATE CAST (integer[] AS vector)
WITH FUNCTION array_to_vector(integer[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (real[] AS vector)
WITH FUNCTION array_to_vector(real[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (double precision[] AS vector)
WITH FUNCTION array_to_vector(double precision[], integer, boolean) AS ASSIGNMENT;
CREATE CAST (numeric[] AS vector)
WITH FUNCTION array_to_vector(numeric[], integer, boolean) AS ASSIGNMENT;
-- operators -- operators
CREATE OPERATOR <-> ( CREATE OPERATOR <-> (

View File

@@ -180,6 +180,9 @@ void IvfflatInitPage(Relation index, Buffer *buf, Page *page, GenericXLogState
IndexBuildResult *ivfflatbuild(Relation heap, Relation index, IndexInfo *indexInfo); IndexBuildResult *ivfflatbuild(Relation heap, Relation index, IndexInfo *indexInfo);
void ivfflatbuildempty(Relation index); void ivfflatbuildempty(Relation index);
bool ivfflatinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique bool ivfflatinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique
#if PG_VERSION_NUM >= 140000
,bool indexUnchanged
#endif
#if PG_VERSION_NUM >= 100000 #if PG_VERSION_NUM >= 100000
,IndexInfo *indexInfo ,IndexInfo *indexInfo
#endif #endif

View File

@@ -128,6 +128,9 @@ InsertTuple(Relation rel, IndexTuple itup, Relation heapRel, Datum *values)
bool bool
ivfflatinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, ivfflatinsert(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid,
Relation heap, IndexUniqueCheck checkUnique Relation heap, IndexUniqueCheck checkUnique
#if PG_VERSION_NUM >= 140000
,bool indexUnchanged
#endif
#if PG_VERSION_NUM >= 100000 #if PG_VERSION_NUM >= 100000
,IndexInfo *indexInfo ,IndexInfo *indexInfo
#endif #endif

View File

@@ -54,3 +54,9 @@ SELECT cosine_distance('[1,2]', '[0,0]');
SELECT cosine_distance('[1,2]', '[3]'); SELECT cosine_distance('[1,2]', '[3]');
ERROR: different vector dimensions 2 and 1 ERROR: different vector dimensions 2 and 1
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];
?column?
----------
t
(1 row)

View File

@@ -16,3 +16,5 @@ SELECT inner_product('[1,2]', '[3]');
SELECT round(cosine_distance('[1,2]', '[2,4]')::numeric, 5); SELECT round(cosine_distance('[1,2]', '[2,4]')::numeric, 5);
SELECT cosine_distance('[1,2]', '[0,0]'); SELECT cosine_distance('[1,2]', '[0,0]');
SELECT cosine_distance('[1,2]', '[3]'); SELECT cosine_distance('[1,2]', '[3]');
SELECT ARRAY[1,2,3] = ARRAY[1,2,3];

View File

@@ -1,4 +1,4 @@
comment = 'vector data type and ivfflat access method' comment = 'vector data type and ivfflat access method'
default_version = '0.1.8' default_version = '0.2.1'
module_pathname = '$libdir/vector' module_pathname = '$libdir/vector'
relocatable = true relocatable = true