Skip to content

Commit

Permalink
Create a solution to demonstrate vector search in SQL Server with ML.NET
Browse files Browse the repository at this point in the history
  • Loading branch information
Artem Startsev committed Nov 2, 2023
1 parent 5e63e80 commit c0f9483
Show file tree
Hide file tree
Showing 25 changed files with 646 additions and 0 deletions.
14 changes: 14 additions & 0 deletions Database/Database.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.13"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.13"/>
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions Database/Image.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Database;

public class Image
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[Required] public string FilePath { get; set; }
}
29 changes: 29 additions & 0 deletions Database/ImageDbContext .cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;

namespace Database;

public class ImageDbContext : DbContext
{
public DbSet<Image> Images { get; set; }
public DbSet<Vector> Vectors { get; set; }
public DbSet<SimilarImage> SimilarImages { get; set; }

public IQueryable<SimilarImage> GetSimilarImages(string vector)
{
return SimilarImages.FromSqlRaw(
"SELECT * FROM dbo.SimilarImages({0})", vector);
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=localhost;Database=ReserveImageSearch;User=sa;Password=!MySecretTemplafyPassword1;TrustServerCertificate=true");
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SimilarImage>().HasNoKey();
modelBuilder.Entity<Vector>().HasKey(v => new { v.ImageId, v.VectorPosition });
base.OnModelCreating(modelBuilder);
}
}
2 changes: 2 additions & 0 deletions Database/Scripts/0 - Create Database.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE
DATABASE ReserveImageSearch
5 changes: 5 additions & 0 deletions Database/Scripts/1 - Define Images Table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE Images
(
Id INT PRIMARY KEY IDENTITY(1,1),
FilePath VARCHAR(255) NOT NULL
);
7 changes: 7 additions & 0 deletions Database/Scripts/2 - Define Vectors Table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE Vectors
(
ImageId INT FOREIGN KEY REFERENCES Images(Id),
VectorPosition INT,
VectorValue FLOAT,
PRIMARY KEY (ImageId, VectorPosition)
);
36 changes: 36 additions & 0 deletions Database/Scripts/3 - Define SimilarImages function.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CREATE
OR
ALTER FUNCTION dbo.SimilarImages(@vector NVARCHAR(max))
RETURNS TABLE
AS
RETURN WITH cteVector AS
(
SELECT
cast ([key] AS INT) AS [VectorPosition],
cast ([value] AS FLOAT) AS [VectorValue]
FROM
OPENJSON(@vector)
),
cteSimilar AS
(
SELECT TOP (50)
v2.Id,
SUM (v1.[VectorValue] * v2.[VectorValue]) / (
SQRT(SUM (v1.[VectorValue] * v1.[VectorValue])) * SQRT(SUM (v2.[VectorValue] * v2.[VectorValue]))
) as CosineDistance
FROM
cteVector v1
INNER JOIN
[dbo].[Vectors] v2 ON v1.VectorPosition = v2.VectorPosition
GROUP BY
v2.ImageId
ORDER BY
cosine_distance DESC
)
SELECT i.FilePath,
r.CosineDistance
FROM cteSimilar r
INNER JOIN
[dbo].[Images] i
ON i.Id = r.ImageId
GO
7 changes: 7 additions & 0 deletions Database/SimilarImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Database;

public class SimilarImage
{
public string FilePath { get; set; }
public double CosineDistance { get; set; }
}
16 changes: 16 additions & 0 deletions Database/Vector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace Database;

public class Vector
{
[Column(Order = 0)]
[ForeignKey("Image")]
public int ImageId { get; set; }

[Column(Order = 1)] public int VectorPosition { get; set; }

public float VectorValue { get; set; }

public virtual Image Image { get; set; }
}
216 changes: 216 additions & 0 deletions DatasetBuilder/DatasetBuilder.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Database\Database.csproj"/>
<ProjectReference Include="..\Vectorizer\Vectorizer.csproj"/>
</ItemGroup>

<ItemGroup>
<None Update="Images\image1.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image10.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image11.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image12.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image13.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image14.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image15.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image16.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image17.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image18.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image19.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image2.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image20.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image21.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image22.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image23.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image24.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image25.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image26.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image27.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image28.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image29.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image3.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image30.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image31.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image32.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image33.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image34.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image35.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image36.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image37.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image38.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image39.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image4.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image40.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image41.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image42.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image43.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image44.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image45.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image46.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image47.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image48.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image49.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image5.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image50.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image51.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image52.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image53.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image54.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image55.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image56.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image57.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image58.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image59.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image6.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image60.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image61.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image62.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image63.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image64.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image65.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image66.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image7.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image8.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\image9.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Binary file added DatasetBuilder/Images/image1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c0f9483

Please sign in to comment.