Most of VectorChord’s vector types are supported by pgvector.
outline: [2,3]
VectorChord Migration Overview
From PGVecto.rs
Most of VectorChord’s vector types are supported by pgvector.
Therefore, migrating from PGVecto.rs to VectorChord is a simple inversion of migrating from pgvector to PGVecto.rs.
In most cases, there will also be one or more vector indexes:
CREATEINDEXindex_vectorONtable_vectorUSINGvectors(vec_f32vectors.vector_l2_ops)WITH(options="[indexing.hnsw]");-- CREATE INDEX index_float16 ON table_float16 USING vectors (vec_f16 vectors.vecf16_cos_ops) WITH (options = "[indexing.hnsw]");
-- CREATE INDEX index_binary ON table_binary USING vectors (vec_bits vectors.bvector_hamming_ops) WITH (options = "[indexing.hnsw]");
This is a typical scenario when PGVecto.rs is used. If the following requirements are met, the migration can be initiated.
Please note that your pgvector and VectorChord extension is not installed in the vectors schema. This means that you can install pgvector and PGVecto.rs at the same time.
Steps to Migration
1. Install VectorChord
Please follow the instructions provided to install VectorChord and ensure that the extension is loaded by PostgreSQL.
CREATEEXTENSIONvchordCASCADE;
Note
This will install vectorchord and pgvector at public schema, if other schema is picked, please substitute public with your schema at the migration command.
Details
The two extensions VectorChord and PGVecto.rs are now installed on PostgreSQL, but inside different schemas.
To validate it, please run \dx in psql. You will see that there are 3 extensions:
vectors for PGVecto.rs at schema vectors
vector for pgvector at schema public
vchord for VectorChord at schema public
postgres=# \dx List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+----------------------------------------------------------------------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
vchord | 0.1.0 | public | vchord: Vector database plugin for Postgres, written in Rust, specifically designed for LLM
vector | 0.8.0 | public | vector data type and ivfflat and hnsw access methods
vectors | 0.4.0 | vectors | vectors: Vector database plugin for Postgres, written in Rust, specifically designed for LLM
2. Check existing indexes
For indexes created at vector columns, please retrieve the definition and record it in a convenient location.
This information is necessary for the recovery of the indexes at a later stage.
To migrate from a PGVecto.rs vector column, the first step is to cast column datatypes between extensions.
Here provides the conversion path for each vector type of VectorChord:
vector(PGVecto.rs) -> real[] -> vector(pgvector)
vecf16 -> vector(PGVecto.rs) -> real[] -> halfvec
bvector -> vector(PGVecto.rs) -> text[] -> real[] -> bit
svector -> text -> index++ -> text -> sparsevec
For sparse vector type svector, we need additional helper function to finish the casting, see the appendix.
The migration will be completed in one command and no additional memory is required.
However, you need to delete the index on the vector column in advance.
Warning
This step will cause some downtime, due to:
a long ACCESS EXCLUSIVE lock by ALTER TABLE ALTER COLUMN
-- The name of index can be found in step 2
DROPINDEXIFEXISTSindex_vector;-- From vector type
ALTERTABLEtable_vectorALTERCOLUMNvec_f32TYPEpublic.vector(3)USINGvec_f32::real[]::public.vector;-- From halfvec type
ALTERTABLEtable_float16ALTERCOLUMNvec_f16TYPEpublic.halfvec(3)USINGvec_f16::vectors.vector::real[]::public.halfvec;-- For bit type
ALTERTABLEtable_binaryALTERCOLUMNvec_bitsTYPEbit(3)USINGarray_to_string(vec_bits::vectors.vector::real[],'')::bit(3);
4. Recreate index
The next step is to recreate index on vector columns for PGVecto.rs.
For more information on creating index at VectorChord, see indexing.
5. Clean the environment
You may now safely remove the PGVecto.rs extension if it is no longer required.
DROP extension vectors;
Appendix: cast of sparse vector
We have discussed most types, but not the sparse vector. It is a little more complicated than other types. Suppose we have a table with a sparse vector column: