pgvector-dotnet

repository·master·Indexed 43 days ago

https://github.com/pgvector/pgvector-dotnet

.NET support (C#, F#, and Visual Basic) for the pgvector PostgreSQL extension. Provides integration with Npgsql, Dapper, and Entity Framework Core to enable vector similarity search. Supports Vector, HalfVector, and SparseVector types, including distance calculations such as L2Distance, MaxInnerProduct, CosineDistance, L1Distance, HammingDistance, and JaccardDistance.

Tokens
3.1K
Snippets
12
Records
12
Agent score
5%

What's inside pgvector-dotnet

  1. Setup pgvector with Visual Basic

    master

    For Visual Basic users, install the Pgvector package. Configure the NpgsqlDataSourceBuilder with .UseVector() and ensure you call conn.ReloadTypes() after creating the extension.

    dotnet add package Pgvector
    Dim dataSourceBuilder As New NpgsqlDataSourceBuilder(connString)
    dataSourceBuilder.UseVector()
    Dim dataSource = dataSourceBuilder.Build()
    
    Dim conn = dataSource.OpenConnection()
    
    ' Enable extension
    Using cmd As New NpgsqlCommand("CREATE EXTENSION IF NOT EXISTS vector", conn)
        cmd.ExecuteNonQuery()
    End Using
    
    conn.ReloadTypes()
  2. Setup pgvector with Entity Framework Core

    master

    To use pgvector with EF Core, install the Pgvector.EntityFrameworkCore package. You need to:

    1. Enable the extension in OnModelCreating using modelBuilder.HasPostgresExtension("vector").
    2. Configure the connection in OnConfiguring using .UseVector().
    3. Define model properties with the [Column(TypeName = "vector(n)")] attribute.
    dotnet add package Pgvector.EntityFrameworkCore
    using Pgvector.EntityFrameworkCore;
    
    // In your DbContext
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasPostgresExtension("vector");
    }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql("connString", o => o.UseVector());
    }
    
    public class Item
    {
        public int Id { get; set; }
    
        [Column(TypeName = "vector(3)")]
        public Vector? Embedding { get; set; }
    }
  3. Run the project tests and examples

    master

    To set up a local development environment, clone the repository, create a test database, and run the tests. To run a specific example, navigate to the example directory, create its required database, and use dotnet run.

    # Run tests
    git clone https://github.com/pgvector/pgvector-dotnet.git
    cd pgvector-dotnet
    createdb pgvector_dotnet_test
    dotnet test
    
    # Run an example
    cd examples/Loading
    createdb pgvector_example
    dotnet run
  4. Setup pgvector with Dapper

    master

    To use pgvector with Dapper, install the Pgvector.Dapper package. You must register a VectorTypeHandler with SqlMapper.AddTypeHandler and configure the NpgsqlDataSourceBuilder with .UseVector(). This allows Dapper to map Vector, HalfVector, and SparseVector types automatically.

    dotnet add package Pgvector.Dapper
    using Pgvector.Dapper;
    
    // Register the type handler
    SqlMapper.AddTypeHandler(new VectorTypeHandler());
    
    var dataSourceBuilder = new NpgsqlDataSourceBuilder(connString);
    dataSourceBuilder.UseVector();
    await using var dataSource = dataSourceBuilder.Build();
    
    var conn = dataSource.OpenConnection();
    
    // Enable extension
    conn.Execute("CREATE EXTENSION IF NOT EXISTS vector");
    conn.ReloadTypes();
  5. Setup pgvector with Npgsql (C#)

    master

    To use pgvector with Npgsql in C#, install the Pgvector package. You must configure the NpgsqlDataSourceBuilder using .UseVector() to enable vector support. After establishing a connection, you must ensure the vector extension is enabled in your PostgreSQL database and call conn.ReloadTypes() to allow the driver to recognize the new types.

    dotnet add package Pgvector
    var dataSourceBuilder = new NpgsqlDataSourceBuilder(connString);
    dataSourceBuilder.UseVector();
    await using var dataSource = dataSourceBuilder.Build();
    
    var conn = dataSource.OpenConnection();
    
    // Enable the extension
    await using (var cmd = new NpgsqlCommand("CREATE EXTENSION IF NOT EXISTS vector", conn))
    {
        await cmd.ExecuteNonQueryAsync();
    }
    
    conn.ReloadTypes();
  6. Setup pgvector with Npgsql.FSharp

    master

    For F# users, install the Pgvector package. Use NpgsqlDataSourceBuilder.UseVector() to configure the data source. Extension management and queries are typically performed using the Sql helper module.

    dotnet add package Pgvector
    open Pgvector
    
    let dataSourceBuilder = new NpgsqlDataSourceBuilder(connString)
    dataSourceBuilder.UseVector()
    use dataSource = dataSourceBuilder.Build()
    
    // Enable extension
    dataSource
    |> Sql.fromDataSource
    |> Sql.query "CREATE EXTENSION IF NOT EXISTS vector"
    |> Sql.executeNonQuery
  7. Perform vector operations with Npgsql (C#)

    master

    Once the extension is enabled, you can create tables with vector(dimensions), insert Vector objects, and perform similarity searches using distance operators like <-> (L2 distance).

    // Create a table
    await using (var cmd = new NpgsqlCommand("CREATE TABLE items (id serial PRIMARY KEY, embedding vector(3))", conn))
    {
        await cmd.ExecuteNonQueryAsync();
    }
    
    // Insert a vector
    await using (var cmd = new NpgsqlCommand("INSERT INTO items (embedding) VALUES ($1)", conn))
    {
        var embedding = new Vector(new float[] { 1, 1, 1 });
        cmd.Parameters.AddWithValue(embedding);
        await cmd.ExecuteNonQueryAsync();
    }
    
    // Get the nearest neighbors
    await using (var cmd = new NpgsqlCommand("SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5", conn))
    {
        var embedding = new Vector(new float[] { 1, 1, 1 });
        cmd.Parameters.AddWithValue(embedding);
    
        await using (var reader = await cmd.ExecuteReaderAsync())
        {
            while (await reader.ReadAsync())
            {
                Console.WriteLine(reader.GetValue(0));
            }
        }
    }
  8. Query vectors using Entity Framework Core

    master

    EF Core integration provides extension methods on Vector for distance calculations. Supported methods include L2Distance, MaxInnerProduct, CosineDistance, L1Distance, HammingDistance, and JaccardDistance.

    // Get nearest neighbors
    var embedding = new Vector(new float[] { 1, 1, 1 });
    var items = await ctx.Items
        .OrderBy(x => x.Embedding!.L2Distance(embedding))
        .Take(5)
        .ToListAsync();
    
    // Get items within a certain distance
    var itemsWithinRange = await ctx.Items
        .Where(x => x.Embedding!.L2Distance(embedding) < 5)
        .ToListAsync();
  9. Work with Half Vectors

    master

    Use the HalfVector class to represent half-precision vectors. You can instantiate a HalfVector from a Half[] array and convert it back to an array using ToArray().

    var vec = new HalfVector(new Half[] { (Half)1, (Half)2, (Half)3 });
    var arr = vec.ToArray();
  10. Work with Sparse Vectors

    master

    Use the SparseVector class to represent vectors where most elements are zero. You can initialize a SparseVector in two ways:

    1. From a dense float[] array.
    2. From a Dictionary<int, float> containing only non-zero elements, specifying the total number of dimensions.

    Note: Indices start at 0.

    Available properties:

    • Dimensions: Returns the total number of dimensions.
    • Indices: Returns the indices of non-zero elements.
    • Values: Returns the values of non-zero elements.
    • ToArray(): Returns the full dense array representation.
    // From an array
    var vec = new SparseVector(new float[] { 1, 0, 2, 0, 3, 0 });
    
    // From a dictionary of non-zero elements
    var dictionary = new Dictionary<int, float>();
    dictionary.Add(0, 1);
    dictionary.Add(2, 2);
    dictionary.Add(4, 3);
    var vec = new SparseVector(dictionary, 6);
    
    // Accessing properties
    var dim = vec.Dimensions;
    var indices = vec.Indices;
    var values = vec.Values;
    var arr = vec.ToArray();
  11. Map pgvector types to Npgsql using VectorTypeInfoResolverFactory

    master

    The VectorTypeInfoResolverFactory is used to integrate pgvector types into the Npgsql type mapping system. It provides resolvers that map PostgreSQL pgvector data types to their corresponding .NET types. This is typically used when configuring an Npgsql data source to ensure the driver understands how to serialize and deserialize vector types.

    Supported mappings include:

    • vector (PostgreSQL) $\leftrightarrow$ Vector (.NET)
    • halfvec (PostgreSQL) $\leftrightarrow$ HalfVector (.NET) (Available on .NET 5.0 or greater)
    • sparsevec (PostgreSQL) $\leftrightarrow$ SparseVector (.NET)
    // Example of how this factory is typically used when configuring an Npgsql DataSource
    var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
    dataSourceBuilder.UseVectorTypeInfoResolverFactory();
    await using var dataSource = dataSourceBuilder.Build();