﻿
{"id":28740,"date":"2026-07-01T01:09:20","date_gmt":"2026-07-01T01:09:20","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=28740"},"modified":"2026-07-01T01:16:10","modified_gmt":"2026-07-01T01:16:10","slug":"nette-pgvector-ile-basit-vector-search-islemi","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/nette-pgvector-ile-basit-vector-search-islemi\/","title":{"rendered":".NET&#8217;te PgVector \u0130le Basit Vector Search \u0130\u015flemi"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi.png\" alt=\".NET&#039;te PgVector \u0130le Basit Vector Search \u0130\u015flemi\" width=\"1536\" height=\"1024\" class=\"alignleft size-full wp-image-28766\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi.png 1536w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi-300x200.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi-1024x683.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2026\/06\/NETte-PgVector-Ile-Basit-Vector-Search-Islemi-768x512.png 768w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><\/a><br \/>\nMerhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde, PostgreSQL veritaban\u0131na vekt\u00f6r (embedding) saklama ve benzerlik arama (similarity search) yetene\u011fi kazand\u0131ran open source bir eklenti olan PgVector&#8217;\u00fc, .NET kapsam\u0131nda <a href=\"https:\/\/www.gencayyildiz.com\/blog\/category\/aspire\/\" target=\"_blank\">Aspire<\/a> teknolojisi \u00fczerinden ve <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/ollama-nedir\/\" target=\"_blank\">Ollama<\/a> e\u015fli\u011finde inceleyecek ve deneyimleyece\u011fiz.<\/p>\n<h4>PgVector Ne \u0130\u015fe Yarar?<\/h4>\n<p>PgVector, PostgreSQL veritaban\u0131n\u0131 yaln\u0131zca verileri saklayan klasik bir veritaban\u0131 olmaktan \u00e7\u0131kar\u0131p, verilerin anlamlar\u0131n\u0131 da kar\u015f\u0131la\u015ft\u0131rabilen bir yap\u0131ya d\u00f6n\u00fc\u015ft\u00fcren eklentidir. \u00d6zellikle yapay zeka uygulamalar\u0131nda, anlamsal aramalar\u0131n (semantic search) PostgreSQL ile ger\u00e7ekle\u015ftirilebilmesi i\u00e7in tercih edilmekte ve b\u00f6ylece chatbot&#8217;lar da, RAG sistemlerinde, ak\u0131ll\u0131 arama motorlar\u0131nda veya \u00f6neri sistemlerinin b\u00fcy\u00fck k\u0131sm\u0131nda bu ama\u00e7la kullan\u0131lmaktad\u0131r.<\/p>\n<p>\u015eimdi bu kullan\u0131m noktalar\u0131na tek tek odaklan\u0131rsak e\u011fer;<\/p>\n<ul style=\"font-size:14px;\">\n<li><strong>Semantic Search (Anlamsal Arama)<\/strong><br \/>\nPgVector&#8217;\u00fcn en \u00f6nemli taraf\u0131 bu davran\u0131\u015f\u0131 PostgreSQL&#8217;e kazand\u0131r\u0131yor olmas\u0131d\u0131r.<\/p>\n<p>Normal bir veritaban\u0131nda, kullan\u0131c\u0131 Ankara&#8217;n\u0131n hava durumuyla ilgili bilgiyi a\u015fa\u011f\u0131daki gibi klasik bir talimatla sorgulayacakt\u0131r;<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:230px;font-size:14px;\">select\t* from\tdocuments<br \/>\nwhere content like &#8216;%ankara%&#8217;\n<\/div>\n<p>Bu sorgulama, bildi\u011finiz \u00fczere yaln\u0131zca kelime e\u015fle\u015fmesi yapacakt\u0131r.<\/p>\n<p>Amma velakin kullan\u0131c\u0131 &#8216;Ba\u015fkentte hava nas\u0131l?&#8217; diye sorarsa bu klasik yakla\u015f\u0131mla y\u00fcksek ihtimalle sonu\u00e7 gelmeyecektir. \u00c7\u00fcnk\u00fc, insan olarak hepimiz &#8220;ba\u015fkent&#8221; denince Ankara&#8217;n\u0131n kastedildi\u011fini anl\u0131yoruz, ancak bunu klasik SQL ne yaz\u0131k ki anlamayacakt\u0131r \ud83d\ude42 O sadece karakterlere bakacak, verilerin niceli\u011fiyle ilgilenecektir.<\/p>\n<p>PgVector ise farkl\u0131 \u00e7al\u0131\u015fmaktad\u0131r&#8230; \u00d6nce metinlerin anlam\u0131n\u0131 say\u0131sal koordinatlara (embedding) d\u00f6n\u00fc\u015ft\u00fcrecek ve bunlarla vekt\u00f6rel d\u00fczlemde bir anlam noktas\u0131 olu\u015fturacakt\u0131r. Devam\u0131nda ise gelen sorunun da embedding&#8217;ini \u00e7\u0131kararak bunun en yak\u0131n oldu\u011fu anlam noktas\u0131na g\u00f6re yak\u0131nl\u0131k hesaplamas\u0131n\u0131 yapacak ve muhtemel en yak\u0131n veriyi cevap olarak d\u00f6nd\u00fcrecektir. Buna a\u015fa\u011f\u0131daki sorguyu \u00f6rnek olarak verebiliriz;<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:300px;font-size:14px;\">select * from documents<br \/>\norder by embedding <=> query_embedding<br \/>\nlimit 5;\n<\/div>\n<div style=\"margin: 36px 0;padding: 18px 20px;border: 1px solid #c7d2fe;border-radius: 6px;background: #eef2ff;font-family: system-ui, sans-serif;\">\n<div style=\"font-size: 13px;font-weight: 600;color: #3730a3;margin-bottom: 8px;\">\n        Semantic Search &#038; Vector Search&#8217;\u00fc teoride ve pratikte \u00f6nceden derinlemesine ele ald\u0131\u011f\u0131m a\u015fa\u011f\u0131daki makalelere g\u00f6z atman\u0131z\u0131 \u00f6neririm;\n    <\/div>\n<div style=\"font-size: 15px;line-height: 1.7;color: #1e293b;\">\n<ul>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/vector-search-nedir-teorik-degerlendirmede-bulunalim\/\" target=\"_blank\">Vector Search Nedir? Teorik De\u011ferlendirmede Bulunal\u0131m\u2026<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/sql-server-2025-vector-search\/\" target=\"_blank\">SQL Server 2025 \u2013 Vector Search<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/nette-vector-datalar-qdrant-vector-databasei-ile-semantic-search\/\" target=\"_blank\">.NET\u2019te Vector Data\u2019lar \u2013 Qdrant Vector Database\u2019i E\u015fli\u011finde Semantic Search Uygulama<\/a><\/li>\n<\/ul><\/div>\n<\/div>\n<\/li>\n<li><strong>RAG Sistemleri<\/strong><br \/>\nSemantic Search mant\u0131\u011f\u0131nda oldu\u011fu gibi RAG sistemlerinde de \u00f6nce dok\u00fcmanlar, PDF&#8217;ler ve bilgi depolar\u0131 embedding&#8217;e \u00e7evrilir ve ard\u0131ndan PgVector arac\u0131l\u0131\u011f\u0131yla kaydedilir. Devam\u0131nda ise kullan\u0131c\u0131dan gelen talebinde embedding&#8217;i al\u0131narak PgVector arac\u0131l\u0131\u011f\u0131yla en alakal\u0131 par\u00e7alar bulunup, LLM \u00fczerinden nihai cevap \u00fcretilmeye \u00e7al\u0131\u015f\u0131l\u0131r.\n<\/li>\n<li><strong>Chatbot Haf\u0131zas\u0131<\/strong><br \/>\nPgVector ile ge\u00e7mi\u015f konu\u015fmalardaki benzer bilgiler rahatl\u0131kla taranabilir. \u00d6rne\u011fin, kullan\u0131c\u0131 \u00f6nceden \u015funlar\u0131 s\u00f6ylemi\u015f olsun:<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:250px;font-size:14px;\">&#8211; Ankara&#8217;da ya\u015f\u0131yorum.<br \/>\n&#8211; K\u0131rm\u0131z\u0131 araba seviyorum.\n<\/div>\n<p>Yeni konu\u015fmada ise<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:250px;font-size:14px;\">&#8211; Bana uygun ara\u00e7 \u00f6ner.\n<\/div>\n<p>sorusuna PgVector ge\u00e7mi\u015f konu\u015fmalardaki benzer bilgileri bulup d\u00f6nd\u00fcrecektir.\n<\/li>\n<li><strong>\u00d6neri Sistemleri<\/strong><br \/>\nNetflix mant\u0131\u011f\u0131nda oldu\u011fu gibi.. Kullan\u0131c\u0131n\u0131n izledi\u011fi i\u00e7erikler vekt\u00f6rle\u015ftirilir, ard\u0131ndan benzer i\u00e7erikler elde edip kullan\u0131c\u0131ya tavsiye edilebilir.<\/li>\n<li><strong>G\u00f6rsel Benzerlik Arama<\/strong><br \/>\nPgVector ile resimler de embedding&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclebilir ve farkl\u0131 bir resimle benzerlik a\u00e7\u0131s\u0131ndan k\u0131yaslamalara tabi tutulabilir.\n<\/li>\n<\/ul>\n<h4>PostgreSQL \u0130\u00e7in Aspire \u0130le Nas\u0131l Altyap\u0131 Sa\u011flan\u0131r?<\/h4>\n<p>\u015eimdi PgVector&#8217;\u00fc Aspire altyap\u0131s\u0131yla nas\u0131l yap\u0131land\u0131rabilece\u011fimizi tam teferruatl\u0131 bir \u015fekilde inceleyelim istiyorum. Bunun i\u00e7in i\u00e7eri\u011fimizin ilk sat\u0131rlar\u0131nda bahsedildi\u011fi gibi Ollama platformundan istifade edece\u011fiz. Tabi bu platformu bilgisayar\u0131m\u0131za kurabilece\u011fimiz gibi docker ortam\u0131nda da aya\u011fa kald\u0131rabiliriz. Hatta Aspire&#8217;daki Ollama (bknz : <a href=\"https:\/\/www.nuget.org\/packages\/CommunityToolkit.Aspire.Hosting.Ollama\" target=\"_blank\">CommunityToolkit.Aspire.Hosting.Ollama<\/a>) k\u00fct\u00fcphanesinden de istifade edebiliriz. Malum&#8230; Bizler Aspire ile temelleri ataca\u011f\u0131m\u0131zdan dolay\u0131 t\u00fcm servislerin sorumlulu\u011funu haliyle Aspire&#8217;a verecek ve onun \u00fczerinden yap\u0131land\u0131r\u0131yor olaca\u011f\u0131z. Ayr\u0131ca embedding s\u00fcrecinde Ollama platformu \u00fczerinde aya\u011fa kald\u0131raca\u011f\u0131m\u0131z <code>qwen3-embedding<\/code> modelini kullanaca\u011f\u0131z.<\/p>\n<p>\u015eimdi bunun i\u00e7in bo\u015f bir Aspire projesi olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 s\u0131ral\u0131 bir \u015fekilde seyrediyor olal\u0131m&#8230;<\/p>\n<ul style=\"font-size:14px;\">\n<li><em><strong>Ad\u0131m 1<\/strong> <span style=\"font-size:12px;color:green;\">(Aspire \u00dczerinden Servislerin Kurulumu)<\/span><\/em>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = DistributedApplication.CreateBuilder(args);\r\n\r\nvar ollama = builder.AddOllama(&quot;ollama&quot;)\r\n    .WithLifetime(ContainerLifetime.Persistent) \/\/ Uygulama dursa bile container ayakta kal\u0131r, her seferinde yeniden ba\u015flat\u0131lmaz\r\n    .WithDataVolume() \/\/ Model verileri i\u00e7in kal\u0131c\u0131 volume olu\u015fturur, veriler container silinse bile korunur\r\n    .WithGPUSupport(); \/\/ GPU h\u0131zland\u0131rma deste\u011fini etkinle\u015ftirir (varsa)\r\n\r\nvar embeddingModel = ollama.AddModel(&quot;qwen3-embedding&quot;);\r\n\r\nvar postgreSQL = builder.AddPostgres(&quot;postgreSQL&quot;, port: 6432)\r\n    .WithLifetime(ContainerLifetime.Persistent)\r\n    .WithDataVolume()\r\n    .WithImage(&quot;pgvector\/pgvector&quot;, &quot;pg17&quot;)\r\n    .AddDatabase(&quot;articles&quot;); \/\/ PostgreSQL i\u00e7inde &quot;articles&quot; ad\u0131nda bir veritaban\u0131 olu\u015fturur\r\n\r\nbuilder.AddProject&lt;Projects.Vector_Search_With_PgVector_API&gt;(&quot;api&quot;)\r\n    .WithReference(embeddingModel)\r\n    .WithReference(postgreSQL)\r\n    .WaitFor(embeddingModel) \/\/ API, embedding model haz\u0131r olana kadar ba\u015flamaz\r\n    .WaitFor(postgreSQL); \/\/ API, PostgreSQL haz\u0131r olana kadar ba\u015flamaz\r\n\r\n\/\/ Uygulamay\u0131 derler ve \u00e7al\u0131\u015ft\u0131r\u0131r\r\nbuilder.Build().Run();\r\n\r\n<\/pre>\n<\/div>\n<p>Evet, burada dikkat ederseniz mevzu bahis olan t\u00fcm servisler Aspire arac\u0131l\u0131\u011f\u0131yla aya\u011fa kald\u0131r\u0131lmaktad\u0131r. Belki dikkatinizi \u00e7eken ve izahat gerektiren <em>postgreSQL<\/em> ile ilgili yap\u0131land\u0131rma olabilir. Burada image olarak <code>pgvector\/pgvector<\/code>&#8216;\u00fcn \u00e7ekildi\u011fini g\u00f6r\u00fcyorsunuz. <em>Neden PostgreSQL image&#8217;ini de\u011fil de bunu \u00e7ekiyoruz?<\/em> diye sorarsan\u0131z esas\u0131nda PostgreSQL&#8217;i de \u00e7ekti\u011fimizi bilmenizi isterim. <code>pgvector\/pgvector<\/code>; PostgreSQL&#8217;i, PgVector extension&#8217;\u0131 ile birlikte getiren bir image&#8217;dir. Haliyle buradaki yap\u0131lanma esas\u0131nda \u015funu ifade etmektedir:<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:360px;font-size:12px;\">pgvector\/pgvector:pg17<br \/>\n       \u2502           \u2502<br \/>\n       \u2502           \u2514\u2500\u2500 PostgreSQL 17 versiyonunu getir&#8230;<br \/>\n       \u2514\u2500\u2500 PgVector extension&#8217;\u0131 y\u00fcklenmi\u015f olan\n<\/div>\n<\/li>\n<li><em><strong>Ad\u0131m 2<\/strong> <span style=\"font-size:12px;color:green;\">(API Yap\u0131land\u0131rmas\u0131)<\/span><\/em><br \/>\n\u015eimdi embedding ve vector search s\u00fcre\u00e7lerini tetikleyecek olan bir API projesi olu\u015fturaca\u011f\u0131z. Bu projede a\u015fa\u011f\u0131daki k\u00fct\u00fcphaneler y\u00fckl\u00fc olacakt\u0131r;<\/p>\n<ul style=\"font-size:12px;\">\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Aspire.Npgsql\" target=\"_blank\">Aspire.Npgsql<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Pgvector.Dapper\" target=\"_blank\">Pgvector.Dapper<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/CommunityToolkit.Aspire.OllamaSharp\" target=\"_blank\">CommunityToolkit.Aspire.OllamaSharp<\/a><\/li>\n<\/ul>\n<p>Burada <code>Pgvector.Dapper<\/code> k\u00fct\u00fcphanesi, <code>Vector<\/code> t\u00fcr\u00fcn\u00fcn Dapper ile sorunsuz \u015fekilde kullan\u0131labilmesi i\u00e7in gerekli type handler bile\u015fenini sunacakt\u0131r. Tabi ki de sizler isterseniz Npgsql yahut <a href=\"https:\/\/www.gencayyildiz.com\/blog\/category\/entity-framework-core\/\" target=\"_blank\">EF Core<\/a> k\u00fct\u00fcphanelerini kullanmay\u0131 tercih edebilirsiniz.<\/p>\n<p>\u015eimdi API i\u00e7erisinde ilgili servisleri a\u015fa\u011f\u0131daki gibi kaydedelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\nbuilder.AddOllamaApiClient(&quot;ollama-qwen3-embedding&quot;)\r\n    .AddEmbeddingGenerator();\r\n\r\nbuilder.AddNpgsqlDataSource(&quot;articles&quot;, configureDataSourceBuilder: builder =&gt; builder.UseVector());\r\n\r\nSqlMapper.AddTypeHandler(new VectorTypeHandler());\r\n.\r\n.\r\n.\r\n<\/pre>\n<\/div>\n<p>Burada yap\u0131land\u0131rmay\u0131 tek tek izah etmemiz gerekirse e\u011fer;<\/p>\n<ul>\n<li><strong><em style=\"color:purple;\">AddOllamaApiClient<\/em><\/strong> metodu, Aspire&#8217;da tan\u0131ml\u0131 olan Ollama servisine ba\u011flant\u0131 kurmaktad\u0131r. Burada ilgili metoda verilen metinsel de\u011fer esas\u0131nda connection string&#8217;e kar\u015f\u0131l\u0131k gelmektedir. Aspire, model referans\u0131n\u0131 <code>{servis-ad\u0131}-{model-ad\u0131}<\/code> format\u0131nda olu\u015fturdu\u011fu i\u00e7in \u00f6rnekteki gibi isimlendirme yap\u0131lm\u0131\u015ft\u0131r.\n<p>Ayr\u0131ca bu metot ile <code>OllamaApiClient<\/code> s\u0131n\u0131f\u0131 <a href=\"https:\/\/www.gencayyildiz.com\/blog\/dependency-injection-nedir-nasil-uygulanir\/\" target=\"_blank\">dependency injection<\/a> i\u00e7in IoC container&#8217;\u0131na eklenmektedir.\n<\/li>\n<li><strong><em style=\"color:purple;\">AddEmbeddingGenerator<\/em><\/strong> metodu ise embedding i\u015flemini ger\u00e7ekle\u015ftirecek olan <code>IEmbeddingGenerator&lt;string, Embedding&lt;float&gt;&gt;<\/code> servisini IoC container&#8217;\u0131na eklemektedir.<\/li>\n<li><strong><em style=\"color:purple;\">AddNpgsqlDataSource<\/em><\/strong> metodu ise klasik PostgreSQL ba\u011flant\u0131s\u0131n\u0131 IoC container&#8217;a eklemektedir. Devam\u0131nda <strong><em style=\"color:purple;\">UseVector<\/em><\/strong> metodu ise PgVector deste\u011fini sa\u011flamaktad\u0131r.<\/li>\n<li><strong><em style=\"color:purple;\">SqlMapper.AddTypeHandler<\/em><\/strong> metodu ise Dapper ORM&#8217;sinin Vector tipini tan\u0131mas\u0131 ve veritaban\u0131 i\u015flemlerini kullanmas\u0131 i\u00e7in \u00e7a\u011fr\u0131lmaktad\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li><em><strong>Ad\u0131m 3<\/strong> <span style=\"font-size:12px;color:green;\">(Veritaban\u0131n\u0131n Tasarlan\u0131p Olu\u015fturulmas\u0131 ve PgVector&#8217;\u00fcn Etkinle\u015ftirilmesi)<\/span><\/em><br \/>\nVector&#8217;leri kaydetmeden \u00f6nce beklenece\u011fi \u00fczere bir tablo olu\u015fturulmal\u0131 ve bir yandan da PgVector extension&#8217;\u0131n\u0131n etkile\u015ftirilmesi gerekmektedir. Bunun i\u00e7in API projesi i\u00e7erisinde a\u015fa\u011f\u0131daki s\u0131n\u0131f\u0131 olu\u015ftural\u0131m:<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public static class DatabaseInitializer\r\n    {\r\n        public static async Task InitializeAsync(NpgsqlDataSource npgsqlDataSource)\r\n        {\r\n            try\r\n            {\r\n                await using var connection = await npgsqlDataSource.OpenConnectionAsync();\r\n\r\n                await using var command = new NpgsqlCommand(&quot;CREATE EXTENSION IF NOT EXISTS vector&quot;, connection);\r\n                await command.ExecuteNonQueryAsync();\r\n\r\n                await connection.ReloadTypesAsync();\r\n\r\n                await connection.ExecuteAsync(\r\n                    &quot;&quot;&quot;\r\n                CREATE TABLE IF NOT EXISTS articles (\r\n                    id SERIAL PRIMARY KEY,\r\n                    title TEXT NOT NULL,\r\n                    url TEXT NOT NULL,\r\n                    content TEXT NOT NULL,\r\n                    embedding VECTOR(1024) NOT NULL,\r\n                )\r\n                &quot;&quot;&quot;);\r\n\r\n                await connection.ExecuteAsync(\r\n                    &quot;&quot;&quot;\r\n                CREATE INDEX IF NOT EXISTS articles_embedding_idx\r\n                ON articles USING hnsw (embedding vector_cosine_ops)\r\n                &quot;&quot;&quot;);\r\n\r\n                await Console.Out.WriteLineAsync(&quot;Database initialized successfully.&quot;);\r\n            }\r\n            catch\r\n            {\r\n                await Console.Out.WriteLineAsync(&quot;An error occurred while initializing the database.&quot;);\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Burada tek tan\u0131yamayaca\u011f\u0131n\u0131z komut <code>CREATE EXTENSION IF NOT EXISTS vector<\/code> olsa gerek&#8230; \u0130\u015fte bu, PostgreSQL&#8217;de PgVector extension&#8217;\u0131n\u0131 etkin k\u0131lan SQL talimat\u0131m\u0131z\u0131n ta kendisidir.<\/p>\n<p><strong><em>ReloadTypesAsync<\/em><\/strong> metodu ise PostgreSQL&#8217;e bilinen t\u00fcrlerin d\u0131\u015f\u0131nda <code>vector<\/code> gibi yeni bir tip eklendi\u011finde, Npgsql&#8217;in bu tipi tan\u0131mas\u0131 i\u00e7in ba\u011flant\u0131y\u0131 yenilemektedir. Aksi taktirde <code>vector<\/code> tipini okuma ve yazma hatas\u0131 ka\u00e7\u0131n\u0131lmazd\u0131r!<\/p>\n<p><strong><em>embedding VECTOR(1024)<\/em><\/strong> ifadesine gelirsek e\u011fer vector t\u00fcr\u00fcn\u00fc ifade etmektedir. <strong><em>1024<\/em><\/strong> ise, kulland\u0131\u011f\u0131m\u0131z <code>qwen3-embedding<\/code> modelinin 1024 boyutlu vekt\u00f6r \u00fcretmesinden kaynakl\u0131d\u0131r.<\/p>\n<p><strong><em>vector_cosine_ops<\/em><\/strong> komutu ise vekt\u00f6rler aras\u0131ndaki kar\u015f\u0131la\u015ft\u0131rman\u0131n hangi operat\u00f6re g\u00f6re yap\u0131laca\u011f\u0131n\u0131 kararla\u015ft\u0131rmaktad\u0131r. Haliyle burada <em>Cosine similarity<\/em> kullan\u0131laca\u011f\u0131 a\u015fikard\u0131r. <strong><em>hnsw<\/em><\/strong>&#8216;de Hierarchical Navigable Small World&#8217;e kar\u015f\u0131l\u0131k gelen, olduk\u00e7a h\u0131zl\u0131, yakla\u015f\u0131k en yak\u0131n kom\u015fu aramas\u0131 (ANN) yapan bir algoritmad\u0131r.<\/p>\n<div style=\"background:#0d0d0d;color:#e6e6e6;font-family:Consolas,'Courier New',monospace;white-space:pre;line-height:0.8;padding:12px;width:450px;font-size:12px;\">\n\u0130ndeks OLMADAN (Brute Force):          \u0130ndeks \u0130LE (HNSW):<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510            \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Her sat\u0131r\u0131 tek tek      \u2502            \u2502 Ak\u0131ll\u0131 graf yap\u0131s\u0131      \u2502<br \/>\n\u2502 kar\u015f\u0131la\u015ft\u0131r             \u2502            \u2502 ile atla atla git       \u2502<br \/>\n\u2502                         \u2502            \u2502                         \u2502<br \/>\n\u2502 1M sat\u0131r = 1M i\u015flem \ud83d\udc22  \u2502            \u2502 1M sat\u0131r = ~100 i\u015flem \ud83d\ude80\u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518            \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/div>\n<p>Devam\u0131nda ise <em>Program.cs<\/em> dosyas\u0131nda bu s\u0131n\u0131f \u00fczerinden <code>InitializeAsync<\/code> metodunun a\u015fa\u011f\u0131daki gibi \u00e7a\u011f\u0131r\u0131lmas\u0131 gerekmektedir;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\nusing var scope = app.Services.CreateScope();\r\nawait DatabaseInitializer.InitializeAsync(scope.ServiceProvider.GetRequiredService&lt;NpgsqlDataSource&gt;());\r\n<\/pre>\n<\/div>\n<p>B\u00f6ylece uygulama aya\u011fa kald\u0131r\u0131ld\u0131\u011f\u0131nda hem veritaban\u0131 tablosu olu\u015fturulacak hem de PgVector extension&#8217;\u0131 etkin k\u0131l\u0131nacakt\u0131r.\n<\/li>\n<li><em><strong>Ad\u0131m 4<\/strong> <span style=\"font-size:12px;color:green;\">(Embedding Olu\u015fturma ve Veritaban\u0131na Kaydetme)<\/span><\/em><br \/>\n\u015eimdi de verilerin embedding&#8217;lerini olu\u015ftural\u0131m ve vector&#8217;lerini \u00e7\u0131karal\u0131m, ard\u0131ndan bunlar\u0131 verilerle birlikte veritaban\u0131na kaydedelim.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/embeddings\/generate&quot;, async (IEmbeddingGenerator&lt;string, Embedding&lt;float&gt;&gt; embeddingGenerator, NpgsqlDataSource npgsqlDataSource, BlogService blogService, ILogger&lt;Program&gt; logger) =&gt;\r\n{\r\n    await using var connection = await npgsqlDataSource.OpenConnectionAsync();\r\n    await connection.ReloadTypesAsync();\r\n\r\n    var urls = await blogService.GetSitemapAsync();\r\n    int count = 0;\r\n\r\n    foreach (string url in urls)\r\n    {\r\n        var (title, content) = await blogService.GetTitleAndContentAsync(url);\r\n        var embedding = await embeddingGenerator.GenerateAsync(content);\r\n        await connection.ExecuteAsync(&quot;INSERT INTO articles(title, url, content, embedding) VALUES(@Title, @Url, @Content, @Embedding)&quot;, new { Title = title, Url = url, Content = content, Embedding = new Pgvector.Vector(embedding.Vector.ToArray()) });\r\n        count++;\r\n        logger.LogInformation(&quot;Processed {count}: {url}&quot;, count, url);\r\n    }\r\n});\r\n<\/pre>\n<\/div>\n<p>Burada <code>embeddingGenerator.GenerateAsync(content)<\/code> ilgili veriyi Ollama&#8217;daki modele g\u00f6nderecek ve embedding&#8217;ini olu\u015fturacakt\u0131r.\n<\/li>\n<li><em><strong>Ad\u0131m 5<\/strong> <span style=\"font-size:12px;color:green;\">(Cosine Distance \u0130le Similarity Search)<\/span><\/em><br \/>\nS\u0131rada kosin\u00fcs algoritmas\u0131yla benzerlik aramas\u0131n\u0131 ger\u00e7ekle\u015ftirmeye ge\u00e7ebiliriz;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/search&quot;, async (string query, IEmbeddingGenerator&lt;string, Embedding&lt;float&gt;&gt; embeddingGenerator, NpgsqlDataSource npgsqlDataSource) =&gt;\r\n{\r\n    var searchEmbedding = await embeddingGenerator.GenerateAsync(query);\r\n\r\n    await using var connection = await npgsqlDataSource.OpenConnectionAsync();\r\n    await connection.ReloadTypesAsync();\r\n\r\n    var results = await connection.QueryAsync&lt;dynamic&gt;(\r\n        &quot;&quot;&quot;\r\n        SELECT id, title, url, content, embedding &lt;=&gt; @Embedding as distance\r\n        FROM articles\r\n        ORDER BY embedding &lt;=&gt; @Embedding\r\n        LIMIT 5\r\n        &quot;&quot;&quot;,\r\n        new\r\n        {\r\n            Embedding = new Pgvector.Vector(searchEmbedding.Vector.ToArray())\r\n        });\r\n\r\n    return TypedResults.Ok(new { query, results = results.Select(r =&gt; r.url) });\r\n});\r\n<\/pre>\n<\/div>\n<p>Burada dikkat ederseniz <code><=><\/code> operat\u00f6r\u00fc kullan\u0131lmaktad\u0131r. Bu operat\u00f6r, PgVector&#8217;\u00fcn kosin\u00fcs mesafesini \u00f6l\u00e7\u00fcmleyebilmek i\u00e7in getirmi\u015f oldu\u011fu bir operat\u00f6rd\u00fcr.<\/p>\n<blockquote><p><em>Unutmay\u0131n! Sorgu metninde kullan\u0131lan embedding de\u011ferini \u00fcreten model ile depolanm\u0131\u015f vekt\u00f6rleri \u00fcreten model birebir ayn\u0131 olmal\u0131d\u0131r! Aksi taktirde, \u00fcretilen embedding de\u011ferler farkl\u0131 vekt\u00f6rel uzaylarda temsil edilece\u011fi i\u00e7in bunlar\u0131n kar\u015f\u0131la\u015ft\u0131r\u0131lmas\u0131 anlams\u0131z olacakt\u0131r.<\/em><\/p><\/blockquote>\n<p>PgVector&#8217;\u00fcn destekledi\u011fi di\u011fer operat\u00f6rler ise \u015funlard\u0131r;<\/p>\n<ul>\n<li><code><-><\/code> &#8211; L2 (\u00d6klid) mesafesini hesaplar. \u0130ki vekt\u00f6r aras\u0131ndaki do\u011frusal (ku\u015f u\u00e7u\u015fu) uzakl\u0131\u011f\u0131 \u00f6l\u00e7er. Mesafe ne kadar k\u00fc\u00e7\u00fckse vekt\u00f6rler o kadar benzerdir.<\/li>\n<li><code><=><\/code> &#8211; Kosin\u00fcs mesafesini hesaplar. Vekt\u00f6rlerin b\u00fcy\u00fckl\u00fc\u011f\u00fcnden ziyade y\u00f6nlerini kar\u015f\u0131la\u015ft\u0131r\u0131r. \u00d6zellikle embedding tabanl\u0131 semantik benzerlik aramalar\u0131nda en yayg\u0131n kullan\u0131lan operat\u00f6rd\u00fcr. Mesafe ne kadar k\u00fc\u00e7\u00fckse benzerlik o kadar y\u00fcksektir.<\/li>\n<li><code><#><\/code> &#8211; Negatif i\u00e7 \u00e7arp\u0131m\u0131 (negative inner product) hesaplar. PostgreSQL indekslerinin artan s\u0131rada \u00e7al\u0131\u015fabilmesi i\u00e7in i\u00e7 \u00e7arp\u0131m\u0131n negatif de\u011feri d\u00f6nd\u00fcr\u00fcl\u00fcr. Maksimum i\u00e7 \u00e7arp\u0131m\u0131 bulmak istiyorsan\u0131z en k\u00fc\u00e7\u00fck <code><#><\/code> sonucunu arars\u0131n\u0131z. \u00d6zellikle embedding&#8217;ler normalize edilmi\u015fse olduk\u00e7a h\u0131zl\u0131 ve etkili bir benzerlik \u00f6l\u00e7\u00fcm\u00fcd\u00fcr.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0130\u015fte bu kadar&#8230; \ud83d\ude42<br \/>\nB\u00f6ylece yapt\u0131\u011f\u0131m\u0131z \u00e7al\u0131\u015fma neticesinde PgVector e\u015fli\u011finde Vector Search davran\u0131\u015f\u0131n\u0131 rahatl\u0131kla uygulayabildi\u011fimizi pratik bir \u015fekilde tecr\u00fcbe etmi\u015f bulunuyoruz.<\/p>\n<p>Nihai olarak;<br \/>\n\u0130\u00e7erik boyunca g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, uygulamalar\u0131m\u0131za anlamsal arama (semantic search) davran\u0131\u015f\u0131n\u0131 eklemek i\u00e7in \u00f6zel bir vekt\u00f6r veritaban\u0131na ihtiyac\u0131m\u0131z bulunmamaktad\u0131r. PosgreSQL, PgVector ile yeni bir altyap\u0131ya gerek duyulmaks\u0131z\u0131n vekt\u00f6r depolama ve similarity search davran\u0131\u015f\u0131n\u0131 rahatl\u0131kla sa\u011flamaktad\u0131r. \u00dcstelik bu yetkinli\u011fi, mevcut ili\u015fkisel verilerimizle ayn\u0131 ortamda, ayn\u0131 sorgu diliyle ve Dapper\/EF Core gibi al\u0131\u015fk\u0131n oldu\u011fumuz ara\u00e7lar\u0131 kullanarak, operasyonel karma\u015f\u0131kl\u0131\u011f\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde azaltarak sa\u011flamaktad\u0131r. Bunlar\u0131n yan\u0131nda Aspire&#8217;\u0131n sundu\u011fu orkestrasyon yetene\u011fi sayesinde Ollama ve PostgreSQL altyap\u0131s\u0131n\u0131 tek bir merkezden aya\u011fa kald\u0131rabilmekte, HNSW indeksleme ve kosin\u00fcs benzerli\u011fi gibi g\u00fc\u00e7l\u00fc vekt\u00f6r operasyonlar\u0131n\u0131 olduk\u00e7a h\u0131zl\u0131 ve teredd\u00fcts\u00fcz bir \u015fekilde devreye alabilmekteyiz.<\/p>\n<p>K\u0131sacas\u0131; PgVector, RAG sistemlerinden chatbot haf\u0131zas\u0131na, \u00f6neri motorlar\u0131ndan g\u00f6rsel benzerlik aramaya kadar geni\u015f bir yelpazede, mevcut PostgreSQL yat\u0131r\u0131m\u0131m\u0131z\u0131 ziyan etmeden yapay zeka destekli uygulamalar geli\u015ftirmemizin en pratik ve sa\u011flam yollar\u0131ndan biri olarak kar\u015f\u0131m\u0131za \u00e7\u0131kmaktad\u0131r. \u015eayet sizler de ekosistemde yeni teknolojiler aray\u0131\u015f\u0131ndaysan\u0131z, \u00f6zellikle mevcut PostgreSQL altyap\u0131n\u0131z\u0131n ne kadar ileriye gidebildi\u011fini PgVector ile bir kez daha de\u011ferlendirmenizi tavsiye etmekteyim.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<div style=\"max-width:720px;margin:24px auto;padding:18px 20px;border-radius:12px;background:linear-gradient(135deg,#0d1117,#161b22);border:1px solid #30363d;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#e6edf3;box-shadow:0 10px 30px rgba(0,0,0,.35);\">\n<div style=\"display:flex;align-items:center;gap:14px;margin-bottom:12px;\">\n    <svg style=\"width:34px;height:34px;fill:#58a6ff;flex-shrink:0;\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n      <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.65 7.65 0 012-.27c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z\"><\/path>\n    <\/svg><\/p>\n<div>\n<div style=\"font-size:18px;font-weight:600;line-height:1.2;\">\u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki GitHub reposundan eri\u015febilirsiniz.<\/div>\n<div style=\"font-size:13px;color:#8b949e;\">https:\/\/github.com\/gncyyldz\/Vector.Search.With.PgVector<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div style=\"font-size:14px;line-height:1.6;color:#c9d1d9;margin-bottom:14px;\">\n    Bu repository, ilgili konuya dair \u00f6rnek \u00e7al\u0131\u015fman\u0131n kaynak kodlar\u0131n\u0131 ve mimari yap\u0131s\u0131n\u0131 i\u00e7ermektedir. Detaylar i\u00e7in GitHub \u00fczerinden incelemede bulunabilirsiniz.\n  <\/div>\n<p>  <a href=\"https:\/\/github.com\/gncyyldz\/Vector.Search.With.PgVector\" target=\"_blank\" rel=\"noopener noreferrer\"\n     style=\"display:inline-block;padding:10px 16px;border-radius:8px;background:#238636;color:#ffffff;text-decoration:none;font-size:14px;font-weight:600;transition:all .2s ease;\"><br \/>\n    GitHub\u2019da G\u00f6r\u00fcnt\u00fcle \u2192<br \/>\n  <\/a><\/p>\n<\/div>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde, PostgreSQL veritaban\u0131na vekt\u00f6r (embedding) saklama ve benzerlik arama (similarity search) yetene\u011fi kazand\u0131ran open source bir eklenti olan PgVector&#8217;\u00fc, .NET kapsam\u0131nda Aspire teknolojisi \u00fczerinden ve Ollama e\u015fli\u011finde inceleyecek ve deneyimleyece\u011fiz. PgVector Ne&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":28766,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5183,5222,5220],"tags":[5185,5732,5729,5730,5226,5407,5728,5731],"class_list":["post-28740","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspire","category-llm","category-yapay-zeka-ai","tag-aspire","tag-cosine-similarity","tag-hierarchical-navigable-small-world","tag-hnsw","tag-ollama","tag-pgvector","tag-postgresql","tag-vector_cosine_ops"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=28740"}],"version-history":[{"count":19,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28740\/revisions"}],"predecessor-version":[{"id":28768,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28740\/revisions\/28768"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/28766"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=28740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=28740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=28740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}