pgvector support for .NET (C#, F#, and Visual Basic)
Supports Npgsql, Dapper, Entity Framework Core, and Npgsql.FSharp
Follow the instructions for your database library:
- C# - Npgsql, Dapper, Entity Framework Core
- F# - Npgsql.FSharp
- Visual Basic - Npgsql
Or check out some examples:
- Embeddings with OpenAI
- Binary embeddings with Cohere
- Hybrid search with Ollama (Reciprocal Rank Fusion)
- Sparse search with Text Embeddings Inference
- Recommendations with Disco
- Topic modeling with ML.NET
- Horizontal scaling with Citus
- Bulk loading with
COPY
Run
dotnet add package PgvectorCreate a connection
vardataSourceBuilder=newNpgsqlDataSourceBuilder(connString);dataSourceBuilder.UseVector();awaitusingvardataSource=dataSourceBuilder.Build();varconn=dataSource.OpenConnection();Enable the extension
awaitusing(varcmd=newNpgsqlCommand("CREATE EXTENSION IF NOT EXISTS vector",conn)){awaitcmd.ExecuteNonQueryAsync();}conn.ReloadTypes();Create a table
awaitusing(varcmd=newNpgsqlCommand("CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))",conn)){awaitcmd.ExecuteNonQueryAsync();}Insert a vector
awaitusing(varcmd=newNpgsqlCommand("INSERT INTO items (embedding) VALUES ($1)",conn)){varembedding=newVector(newfloat[]{1,1,1});cmd.Parameters.AddWithValue(embedding);awaitcmd.ExecuteNonQueryAsync();}Get the nearest neighbors
awaitusing(varcmd=newNpgsqlCommand("SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5",conn)){varembedding=newVector(newfloat[]{1,1,1});cmd.Parameters.AddWithValue(embedding);awaitusing(varreader=awaitcmd.ExecuteReaderAsync()){while(awaitreader.ReadAsync()){Console.WriteLine(reader.GetValue(0));}}}Add an approximate index
awaitusing(varcmd=newNpgsqlCommand("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)",conn)){awaitcmd.ExecuteNonQueryAsync();}Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Run
dotnet add package Pgvector.DapperImport the library
usingPgvector.Dapper;Create a connection
SqlMapper.AddTypeHandler(newVectorTypeHandler());vardataSourceBuilder=newNpgsqlDataSourceBuilder(connString);dataSourceBuilder.UseVector();awaitusingvardataSource=dataSourceBuilder.Build();varconn=dataSource.OpenConnection();Enable the extension
conn.Execute("CREATE EXTENSION IF NOT EXISTS vector");conn.ReloadTypes();Define a class
publicclassItem{publicintId{get;set;}publicVector?Embedding{get;set;}}Also supports HalfVector and SparseVector
Create a table
conn.Execute("CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))");Insert a vector
varembedding=newVector(newfloat[]{1,1,1});conn.Execute(@"INSERT INTO items (embedding) VALUES (@embedding)",new{embedding});Get the nearest neighbors
varembedding=newVector(newfloat[]{1,1,1});varitems=conn.Query<Item>("SELECT * FROM items ORDER BY embedding <-> @embedding LIMIT 5",new{embedding});foreach(Itemiteminitems){Console.WriteLine(item.Embedding);}Add an approximate index
conn.Execute("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)");// orconn.Execute("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
Run
dotnet add package Pgvector.EntityFrameworkCoreThe latest version works with Entity Framework Core 9 and 10. For Entity Framework Core 8, use version 0.2.2 and this readme.
Import the library
usingPgvector.EntityFrameworkCore;Enable the extension
protectedoverridevoidOnModelCreating(ModelBuildermodelBuilder){modelBuilder.HasPostgresExtension("vector");}Configure the connection
protectedoverridevoidOnConfiguring(DbContextOptionsBuilderoptionsBuilder){optionsBuilder.UseNpgsql("connString", o =>o.UseVector());}Define a model
publicclassItem{publicintId{get;set;}[Column(TypeName="vector(3)")]publicVector?Embedding{get;set;}}Also supports HalfVector and SparseVector
Insert a vector
ctx.Items.Add(newItem{Embedding=newVector(newfloat[]{1,1,1})});ctx.SaveChanges();Get the nearest neighbors
varembedding=newVector(newfloat[]{1,1,1});varitems=awaitctx.Items.OrderBy(x =>x.Embedding!.L2Distance(embedding)).Take(5).ToListAsync();foreach(Itemiteminitems){if(item.Embedding!=null){Console.WriteLine(item.Embedding);}}Also supports MaxInnerProduct, CosineDistance, L1Distance, HammingDistance, and JaccardDistance
Get the distance
varitems=awaitctx.Items.Select(x =>new{Entity=x,Distance=x.Embedding!.L2Distance(embedding)}).ToListAsync();Get items within a certain distance
varitems=awaitctx.Items.Where(x =>x.Embedding!.L2Distance(embedding)<5).ToListAsync();Add an approximate index
protectedoverridevoidOnModelCreating(ModelBuildermodelBuilder){modelBuilder.Entity<Item>().HasIndex(i =>i.Embedding).HasMethod("hnsw").HasOperators("vector_l2_ops").HasStorageParameter("m",16).HasStorageParameter("ef_construction",64);// ormodelBuilder.Entity<Item>().HasIndex(i =>i.Embedding).HasMethod("ivfflat").HasOperators("vector_l2_ops").HasStorageParameter("lists",100);}Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Run
dotnet add package PgvectorImport the library
openPgvectorCreate a connection
letdataSourceBuilder=new NpgsqlDataSourceBuilder(connString) dataSourceBuilder.UseVector()use dataSource = dataSourceBuilder.Build()Enable the extension
dataSource |> Sql.fromDataSource |> Sql.query "CREATE EXTENSION IF NOT EXISTS vector"|> Sql.executeNonQueryCreate a table
dataSource |> Sql.fromDataSource |> Sql.query "CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))"|> Sql.executeNonQueryInsert a vector
letembedding=new Vector([|1f;1f;1f |])letparameter=new NpgsqlParameter("", embedding) dataSource |> Sql.fromDataSource |> Sql.query "INSERT INTO items (embedding) VALUES (@embedding)"|> Sql.parameters ["embedding", Sql.parameter parameter ]|> Sql.executeNonQueryGet the nearest neighbors
typeItem={ Id:int Embedding:Vector} dataSource |> Sql.fromDataSource |> Sql.query "SELECT * FROM items ORDER BY embedding <-> @embedding LIMIT 5"|> Sql.parameters ["embedding", Sql.parameter parameter ]|> Sql.execute (fun read ->{ Id = read.int "id" Embedding = read.fieldValue<Vector>"embedding"})|> printfn "%A"Add an approximate index
dataSource |> Sql.fromDataSource |> Sql.query "CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)"|> Sql.executeNonQueryUse vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Run
dotnet add package PgvectorCreate a connection
DimdataSourceBuilderAsNewNpgsqlDataSourceBuilder(connString)dataSourceBuilder.UseVector()DimdataSource=dataSourceBuilder.Build()Dimconn=dataSource.OpenConnection()Enable the extension
UsingcmdAsNewNpgsqlCommand("CREATE EXTENSION IF NOT EXISTS vector",conn)cmd.ExecuteNonQuery()EndUsingconn.ReloadTypes()Create a table
UsingcmdAsNewNpgsqlCommand("CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))",conn)cmd.ExecuteNonQuery()EndUsingInsert a vector
UsingcmdAsNewNpgsqlCommand("INSERT INTO items (embedding) VALUES ($1)",conn)DimembeddingAsNewVector(NewSingle(){1,1,1})cmd.Parameters.AddWithValue(embedding)cmd.ExecuteNonQuery()EndUsingGet the nearest neighbors
UsingcmdAsNewNpgsqlCommand("SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5",conn)DimembeddingAsNewVector(NewSingle(){1,1,1})cmd.Parameters.AddWithValue(embedding)UsingreaderAsNpgsqlDataReader=cmd.ExecuteReader()Whilereader.Read()Console.WriteLine(reader.GetValue(0))EndWhileEndUsingEndUsingAdd an approximate index
UsingcmdAsNewNpgsqlCommand("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)",conn)cmd.ExecuteNonQuery()EndUsingUse vector_ip_ops for inner product and vector_cosine_ops for cosine distance
See a full example
Create a vector from an array
varvec=newVector(newfloat[]{1,2,3});Get an array
vararr=vec.ToArray();Create a half vector from an array
varvec=newHalfVector(newHalf[]{(Half)1,(Half)2,(Half)3});Get an array
vararr=vec.ToArray();Create a sparse vector from an array
varvec=newSparseVector(newfloat[]{1,0,2,0,3,0});Or a dictionary of non-zero elements
vardictionary=newDictionary<int,float>();dictionary.Add(0,1);dictionary.Add(2,2);dictionary.Add(4,3);varvec=newSparseVector(dictionary,6);Note: Indices start at 0
Get the number of dimensions
vardim=vec.Dimensions;Get the indices of non-zero elements
varindices=vec.Indices;Get the values of non-zero elements
varvalues=vec.Values;Get an array
vararr=vec.ToArray();Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development:
git clone https://github.com/pgvector/pgvector-dotnet.git cd pgvector-dotnet createdb pgvector_dotnet_test dotnet testTo run an example:
cd examples/Loading createdb pgvector_example dotnet run