Bu çalışmada, Oracle Cloud Infrastructure (OCI) üzerinde Elasticsearch’ün vektör arama yeteneklerini deneyimlemek için küçük ve sade bir PoC ortamı kurdum. Mümkün olduğunca düşük kaynak kullanımıyla ilerlemek istediğim için Frankfurt bölgesinde, Ubuntu LTS tabanlı tek bir sanal makine kullanmayı tercih ettim. Kurulum sürecinde güvenlik, ağ ve depolama tarafında varsayılan ve PoC için yeterli ayarlarla ilerleyerek ortamı gereksiz detaylarla karmaşıklaştırmamaya özen gösterdim. Amacım, altyapı ayarlarından ziyade Elasticsearch’ün vektör tabanlı arama davranışını, semantik benzerlik sonuçlarını ve ileride RAG gibi senaryolara nasıl temel oluşturabileceğini pratik olarak gözlemlemekti. Bu yaklaşım sayesinde hızlı, tekrarlanabilir ve maliyet açısından verimli bir deneme ortamı elde etmiş oldum.
PoC ortamını hazırlarken ilk adım olarak Ubuntu üzerinde paket listesini güncelledim ve Docker kurulumu için gerekli olan temel araçların sistemde hazır olduğundan emin oldum. Bu aşamada apt update komutunu çalıştırarak sistemin güncel paket bilgilerini almasını sağladım. apt upgrade adımını ise bilinçli olarak atladım. Bunun nedeni, kernel veya sistem servislerinde yapılabilecek güncellemelerin PoC sürecinin odağını dağıtmasını istemememdi.
Bu adımda kurulan temel paketler şunlardır:
ca-certificates: HTTPS üzerinden güvenli indirmeler yapılabilmesi için,
curl: Docker repository anahtarlarını ve dosyalarını indirmek için,
gnupg: Docker’ın GPG imza anahtarlarının doğrulanabilmesi için.
Aşağıdaki çıktılar, sistemin güncellendiğini ve gerekli paketlerin hazır olduğunu doğrulamaktadır:
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo apt update
Hit:1 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:3 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:4 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble-backports InRelease
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
64 packages can be upgraded. Run ‘apt list –upgradable’ to see them.
ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo apt install -y ca-certificates curl gnupg
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
ca-certificates is already the newest version (20240203).
ca-certificates set to manually installed.
curl is already the newest version (8.5.0-2ubuntu10.6).
curl set to manually installed.
gnupg is already the newest version (2.4.4-2ubuntu17.3).
gnupg set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 64 not upgraded.
ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl –version
curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7
Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Docker’ın resmî repository’sini eklemeden önce, paketlerin güvenilir kaynaktan geldiğini doğrulamak için Docker’ın GPG imza anahtarını sisteme ekledim. Bu sayede ilerleyen adımlarda Docker deposunu tanımladığımda, indirilecek paketlerin imzası doğrulanabilecek ve kurulum daha güvenli şekilde ilerleyecektir.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo install -m 0755 -d /etc/apt/keyrings
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Bu aşamada Docker repository’sini sisteme eklemeden önce, kullanılacak mimari ve işletim sistemi sürümünü doğruladım. dpkg –print-architecture komutu ile sistemin amd64 mimarisinde çalıştığını, /etc/os-release üzerinden ise Ubuntu’nun noble (24.04) sürümünde olduğunu teyit ettim. Ardından bu bilgilerle oluşturulacak Docker repository satırını ekrana yazdırarak, sisteme eklenecek kaynağın doğru mimari ve sürümü hedeflediğinden emin oldum.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ dpkg –print-architecture
amd64
ubuntu@es-vector-pocinstance-20251221-1055:~$ . /etc/os-release && echo “$VERSION_CODENAME”
noble
ubuntu@es-vector-pocinstance-20251221-1055:~$ echo “deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable”
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Bu adımda Docker’ın resmî paket deposunu sisteme tanımladım. Daha önce doğruladığım mimari ve Ubuntu sürüm bilgilerini kullanarak Docker repository satırını oluşturdum ve bu satırı /etc/apt/sources.list.d/docker.list dosyasına ekledim. Böylece sistem, Docker paketlerini hangi kaynaktan ve hangi imza anahtarıyla alacağını öğrenmiş oldu.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ echo “deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo “$VERSION_CODENAME”) stable” \
| sudo tee /etc/apt/sources.list.d/docker.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Bu aşamada apt update komutunu yeniden çalıştırarak Docker repository’sinin sisteme başarıyla tanıtıldığını doğruladım. Çıktıda Docker’ın resmî deposuna (download.docker.com) ait paketlerin listelendiğini görmek, sistemin artık Docker paketlerini bu kaynaktan tanıyabildiğini gösterdi. Bu adımla birlikte Docker kurulumu için gerekli paket bilgileri sisteme dahil edilmiş oldu.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo apt update
Get:1 https://download.docker.com/linux/ubuntu noble InRelease [48.5 kB]
Get:2 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages [41.1 kB]
Hit:3 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:4 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble InRelease
Hit:5 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:6 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble-backports InRelease
Fetched 89.6 kB in 1s (178 kB/s)
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
64 packages can be upgraded. Run ‘apt list –upgradable’ to see them.
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Aşağıdaki komutla Docker Engine ve Docker ile birlikte gelen temel bileşenleri sisteme kurdum. Kurulum sırasında Docker’ın resmî repository’sinden gerekli paketler indirildi ve Docker servisi sistemde aktif hale getirildi. Böylece PoC ortamı, container tabanlı uygulamaları çalıştırabilecek duruma geldi.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
The following additional packages will be installed:
docker-buildx-plugin docker-ce-rootless-extras libslirp0 pigz slirp4netns
Suggested packages:
cgroupfs-mount | cgroup-lite docker-model-plugin
The following NEW packages will be installed:
containerd.io docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin libslirp0 pigz slirp4netns
0 upgraded, 9 newly installed, 0 to remove and 64 not upgraded.
Need to get 91.3 MB of archives.
After this operation, 364 MB of additional disk space will be used.
Get:1 https://download.docker.com/linux/ubuntu noble/stable amd64 containerd.io amd64 2.2.1-1~ubuntu.24.04~noble [23.4 MB]
Get:2 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble/universe amd64 pigz amd64 2.8-1 [65.6 kB]
Get:3 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble/main amd64 libslirp0 amd64 4.7.0-1ubuntu3 [63.8 kB]
Get:4 http://eu-frankfurt-1-ad-2.clouds.archive.ubuntu.com/ubuntu noble/universe amd64 slirp4netns amd64 1.2.1-1build2 [34.9 kB]
Get:5 https://download.docker.com/linux/ubuntu noble/stable amd64 docker-ce-cli amd64 5:29.1.3-1~ubuntu.24.04~noble [16.3 MB]
Get:6 https://download.docker.com/linux/ubuntu noble/stable amd64 docker-ce amd64 5:29.1.3-1~ubuntu.24.04~noble [21.0 MB]
Get:7 https://download.docker.com/linux/ubuntu noble/stable amd64 docker-buildx-plugin amd64 0.30.1-1~ubuntu.24.04~noble [16.4 MB]
Get:8 https://download.docker.com/linux/ubuntu noble/stable amd64 docker-ce-rootless-extras amd64 5:29.1.3-1~ubuntu.24.04~noble [6383 kB]
Get:9 https://download.docker.com/linux/ubuntu noble/stable amd64 docker-compose-plugin amd64 5.0.0-1~ubuntu.24.04~noble [7709 kB]
Fetched 91.3 MB in 1s (145 MB/s)
Selecting previously unselected package containerd.io.
(Reading database … 104585 files and directories currently installed.)
Preparing to unpack …/0-containerd.io_2.2.1-1~ubuntu.24.04~noble_amd64.deb …
Unpacking containerd.io (2.2.1-1~ubuntu.24.04~noble) …
Selecting previously unselected package docker-ce-cli.
Preparing to unpack …/1-docker-ce-cli_5%3a29.1.3-1~ubuntu.24.04~noble_amd64.deb …
Unpacking docker-ce-cli (5:29.1.3-1~ubuntu.24.04~noble) …
Selecting previously unselected package docker-ce.
Preparing to unpack …/2-docker-ce_5%3a29.1.3-1~ubuntu.24.04~noble_amd64.deb …
Unpacking docker-ce (5:29.1.3-1~ubuntu.24.04~noble) …
Selecting previously unselected package pigz.
Preparing to unpack …/3-pigz_2.8-1_amd64.deb …
Unpacking pigz (2.8-1) …
Selecting previously unselected package docker-buildx-plugin.
Preparing to unpack …/4-docker-buildx-plugin_0.30.1-1~ubuntu.24.04~noble_amd64.deb …
Unpacking docker-buildx-plugin (0.30.1-1~ubuntu.24.04~noble) …
Selecting previously unselected package docker-ce-rootless-extras.
Preparing to unpack …/5-docker-ce-rootless-extras_5%3a29.1.3-1~ubuntu.24.04~noble_amd64.deb …
Unpacking docker-ce-rootless-extras (5:29.1.3-1~ubuntu.24.04~noble) …
Selecting previously unselected package docker-compose-plugin.
Preparing to unpack …/6-docker-compose-plugin_5.0.0-1~ubuntu.24.04~noble_amd64.deb …
Unpacking docker-compose-plugin (5.0.0-1~ubuntu.24.04~noble) …
Selecting previously unselected package libslirp0:amd64.
Preparing to unpack …/7-libslirp0_4.7.0-1ubuntu3_amd64.deb …
Unpacking libslirp0:amd64 (4.7.0-1ubuntu3) …
Selecting previously unselected package slirp4netns.
Preparing to unpack …/8-slirp4netns_1.2.1-1build2_amd64.deb …
Unpacking slirp4netns (1.2.1-1build2) …
Setting up docker-buildx-plugin (0.30.1-1~ubuntu.24.04~noble) …
Setting up containerd.io (2.2.1-1~ubuntu.24.04~noble) …
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /usr/lib/systemd/system/containerd.service.
Setting up docker-compose-plugin (5.0.0-1~ubuntu.24.04~noble) …
Setting up docker-ce-cli (5:29.1.3-1~ubuntu.24.04~noble) …
Setting up libslirp0:amd64 (4.7.0-1ubuntu3) …
Setting up pigz (2.8-1) …
Setting up docker-ce-rootless-extras (5:29.1.3-1~ubuntu.24.04~noble) …
Setting up slirp4netns (1.2.1-1build2) …
Setting up docker-ce (5:29.1.3-1~ubuntu.24.04~noble) …
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
Created symlink /etc/systemd/system/sockets.target.wants/docker.socket → /usr/lib/systemd/system/docker.socket.
Processing triggers for man-db (2.12.0-4build2) …
Processing triggers for libc-bin (2.39-0ubuntu8.6) …
Scanning processes…
Scanning linux images…
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Docker kurulumunun ardından Docker servisinin aktif olarak çalıştığını doğruladım. Docker daemon’un sorunsuz şekilde başlatıldığını ve sistem açılışında otomatik olarak devreye girecek şekilde yapılandırıldığını gözlemledim. Ayrıca kullanıcıyı docker grubuna ekleyerek Docker komutlarının sudo kullanmadan çalıştırılmasını sağladım. Yapılan kontroller sonucunda Docker ve Docker Compose bileşenlerinin sağlıklı şekilde çalıştığı teyit edilmiş oldu.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo systemctl status docker –no-pager
● docker.service – Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-12-21 15:04:00 UTC; 3min 8s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 2245 (dockerd)
Tasks: 9
Memory: 26.6M (peak: 28.1M)
CPU: 271ms
CGroup: /system.slice/docker.service
└─2245 /usr/bin/dockerd -H fd:// –containerd=/run/containerd/containerd.sock
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.205305146Z” level=info msg=”Restoring containers: start.”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.216520328Z” level=info msg=”Deleting nftables IPv4 rules” error… status 1″
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.222511950Z” level=info msg=”Deleting nftables IPv6 rules” error… status 1″
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.434614692Z” level=info msg=”Loading containers: done.”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.441587634Z” level=info msg=”Docker daemon” commit=fbf3ed2 conta…ion=29.1.3
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.441720952Z” level=info msg=”Initializing buildkit”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.461458654Z” level=info msg=”Completed buildkit initialization”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.467661228Z” level=info msg=”Daemon has completed initialization”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 dockerd[2245]: time=”2025-12-21T15:04:00.467798363Z” level=info msg=”API listen on /run/docker.sock”
Dec 21 15:04:00 es-vector-pocinstance-20251221-1055 systemd[1]: Started docker.service – Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
ubuntu@es-vector-pocinstance-20251221-1055:~$ sudo usermod -aG docker $USER
newgrp docker
ubuntu@es-vector-pocinstance-20251221-1055:~$ docker version
docker compose version
Client: Docker Engine – Community
Version: 29.1.3
API version: 1.52
Go version: go1.25.5
Git commit: f52814d
Built: Fri Dec 12 14:49:32 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine – Community
Engine:
Version: 29.1.3
API version: 1.52 (minimum version 1.44)
Go version: go1.25.5
Git commit: fbf3ed2
Built: Fri Dec 12 14:49:32 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v2.2.1
GitCommit: dea7da592f5d1d2b7755e3a161be07f43fad8f75
runc:
Version: 1.3.4
GitCommit: v1.3.4-0-gd6d73eb8
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker Compose version v5.0.0
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Elasticsearch container’ını başlattıktan sonra docker ps ile container’ın gerçekten ayakta olduğunu doğruladım. Çıktıda container’ın Up durumda olması ve 9200 portunun host’a map edilmesi, Elasticsearch servisinin erişilebilir olacağı anlamına geliyor.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ docker run -d \
–name es-vector-poc \
-p 9200:9200 \
-e “discovery.type=single-node” \
-e “xpack.security.enabled=false” \
-e “ES_JAVA_OPTS=-Xms1g -Xmx1g” \
docker.elastic.co/elasticsearch/elasticsearch:8.15.3
Unable to find image ‘docker.elastic.co/elasticsearch/elasticsearch:8.15.3’ locally
8.15.3: Pulling from elasticsearch/elasticsearch
2b86227197a9: Pull complete
b9e901c50849: Pull complete
f99c8f037321: Pull complete
152f4d0eac6a: Pull complete
97a64c89942b: Pull complete
8c98676b4b98: Pull complete
053d01667d81: Pull complete
4ca545ee6d5d: Pull complete
ab5081957ccd: Pull complete
011bd20c7dc8: Pull complete
Digest: sha256:01c1732062b4a846c5ca687b0094b89bad0bfed00c6d71626db32fb8f3131a78
Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch:8.15.3
a8dfd3e8b41a6688c774c9c360d680aebf43b6b2cdece9e5cabe5926ff0f7b9c
ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8dfd3e8b41a docker.elastic.co/elasticsearch/elasticsearch:8.15.3 “/bin/tini — /usr/l…” About a minute ago Up 48 seconds 0.0.0.0:9200->9200/tcp, [::]:9200->9200/tcp, 9300/tcp es-vector-poc
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Container’ın ayakta olduğunu gördükten sonra curl http://localhost:9200 ile Elasticsearch API’sine istek attım. Dönen JSON çıktısı, Elasticsearch servisinin başarıyla çalıştığını ve versiyon bilgisinin (8.15.3) doğrulanabildiğini gösterdi. Bu noktadan sonra artık vektör indeksini oluşturup gerçek vector search denemelerine geçebilirim.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl http://localhost:9200
{
“name” : “a8dfd3e8b41a”,
“cluster_name” : “docker-cluster”,
“cluster_uuid” : “OMae3aLIS9KCZvg_pUygnQ”,
“version” : {
“number” : “8.15.3”,
“build_flavor” : “default”,
“build_type” : “docker”,
“build_hash” : “f97532e680b555c3a05e73a74c28afb666923018”,
“build_date” : “2024-10-09T22:08:00.328917561Z”,
“build_snapshot” : false,
“lucene_version” : “9.11.1”,
“minimum_wire_compatibility_version” : “7.17.0”,
“minimum_index_compatibility_version” : “7.0.0”
},
“tagline” : “You Know, for Search”
}
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Aşağıdaki adımda, vektör tabanlı arama yapabilmek için dense_vector alanı içeren bir Elasticsearch index’i oluşturdum. Index içerisinde metin verisini saklamak için keyword alanı, semantik benzerlik hesaplamaları için ise cosine similarity kullanan 3 boyutlu bir vektör alanı tanımladım. Bu yapı, Elasticsearch’ün vektör arama yeteneklerini denemek için gerekli temel altyapıyı sağladı. Mapping çıktısında ayrıca Elasticsearch’ün vektör alanı için otomatik olarak HNSW tabanlı bir index (int8_hnsw) oluşturduğu görüldü; bu da kNN sorgularının hızlı çalışabilmesi için gerekli altyapının hazırlandığını gösterdi.
Not: Index’i 3 boyutlu demo senaryosuna uyarlamak için daha önce oluşturduğum yapıyı kaldırıp aynı isimle yeniden oluşturdum; {“acknowledged”: true} çıktısı bu silme işleminin başarılı olduğunu gösterir.
**
{“acknowledged”:true}ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -X PUT “http://localhost:9200/poc_vectors” \
-H “Content-Type: application/json” \
-d ‘{
“mappings”: {
“properties”: {
“text”: { “type”: “keyword” },
“embedding”: {
“type”: “dense_vector”,
“dims”: 3,
“index”: true,
“similarity”: “cosine”
}
}
}
}’
{“acknowledged”:true,”shards_acknowledged”:true,”index”:”poc_vectors”}ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -s “http://localhost:9200/poc_vectors/_mapping?pretty”
{
“poc_vectors” : {
“mappings” : {
“properties” : {
“embedding” : {
“type” : “dense_vector”,
“dims” : 3,
“index” : true,
“similarity” : “cosine”,
“index_options” : {
“type” : “int8_hnsw”,
“m” : 16,
“ef_construction” : 100
}
},
“text” : {
“type” : “keyword”
}
}
}
}
}
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Bu adımda, oluşturulan vektör index’ine üç adet örnek doküman ekledim. Her doküman için 3 boyutlu, birbirinden farklı vektörler tanımlayarak basit ama anlaşılır bir test veri seti oluşturdum. Elasticsearch’ün döndürdüğü result: created çıktıları, dokümanların başarıyla index’e kaydedildiğini ve vektör alanlarının sorunsuz şekilde işlendiğini doğruladı.
doc-A → [1, 0, 0]
doc-B → [0, 1, 0]
doc-C → [0, 0, 1]
Bu yapı sayesinde, bir sonraki adımda vektör benzerliğine dayalı kNN sorgularının sonuçlarını net biçimde gözlemlemek mümkün hale geldi.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -X POST “http://localhost:9200/poc_vectors/_doc/1” \
-H “Content-Type: application/json” \
-d ‘{“text”:”doc-A”,”embedding”:[1.0,0.0,0.0]}’
{“_index”:”poc_vectors”,”_id”:”1″,”_version”:1,”result”:”created”,”_shards”:{“total”:2,”successful”:1,”failed”:0},”_seq_no”:0,”_primary_term”:1}ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -X POST “http://localhost:9200/poc_vectors/_doc/2” \
-H “Content-Type: application/json” \
-d ‘{“text”:”doc-B”,”embedding”:[0.0,1.0,0.0]}’
{“_index”:”poc_vectors”,”_id”:”2″,”_version”:1,”result”:”created”,”_shards”:{“total”:2,”successful”:1,”failed”:0},”_seq_no”:1,”_primary_term”:1}ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -X POST “http://localhost:9200/poc_vectors/_doc/3” \
-H “Content-Type: application/json” \
-d ‘{“text”:”doc-C”,”embedding”:[0.0,0.0,1.0]}’
{“_index”:”poc_vectors”,”_id”:”3″,”_version”:1,”result”:”created”,”_shards”:{“total”:2,”successful”:1,”failed”:0},”_seq_no”:2,”_primary_term”:1}ubuntu@es-vector-pocinstance-20251221-1055:~$
**
Bu adımda kNN sorgusu çalıştırarak, sorgu vektörü [0.9, 0.1, 0.0] için en yakın dokümanları Elasticsearch üzerinden aradım. Sorgu sonucunda, beklediğim şekilde doc-A en yüksek skorla (≈0.99) ilk sırada, doc-B ise daha düşük skorla (≈0.56) ikinci sırada döndü. Bu sonuç, vektör uzayında cosine benzerliğine göre yapılan sıralamanın doğru çalıştığını gösterdi ve Elasticsearch’ün vektör tabanlı arama mekanizmasını pratik olarak doğrulamış oldu.
**
ubuntu@es-vector-pocinstance-20251221-1055:~$ curl -X POST “http://localhost:9200/poc_vectors/_search?pretty” \
-H “Content-Type: application/json” \
-d ‘{
“knn”: {
“field”: “embedding”,
“query_vector”: [0.9, 0.1, 0.0],
“k”: 2,
“num_candidates”: 10
},
“_source”: [“text”]
}’
{
“took” : 89,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 2,
“relation” : “eq”
},
“max_score” : 0.99694574,
“hits” : [
{
“_index” : “poc_vectors”,
“_id” : “1”,
“_score” : 0.99694574,
“_source” : {
“text” : “doc-A”
}
},
{
“_index” : “poc_vectors”,
“_id” : “2”,
“_score” : 0.5560008,
“_source” : {
“text” : “doc-B”
}
}
]
}
}
ubuntu@es-vector-pocinstance-20251221-1055:~$
**
dense_vector, HNSW, kNN ve Cosine Benzerliği
Bu çalışmada Elasticsearch’ün vektör tabanlı arama yeteneklerini anlamak için dört temel kavramı birlikte kullandım: dense_vector, cosine benzerliği, kNN ve HNSW. Bu kavramlar bir araya geldiğinde, klasik metin aramasından farklı olarak verilerin anlamsal yakınlığına göre sorgulanabilmesini sağlıyor.
dense_vector neyi temsil ediyor?
Index oluştururken dense_vector tipinde bir alan tanımladım. Bu alan, bir verinin (örneğin bir metnin) sayılardan oluşan matematiksel karşılığını saklamak için kullanılıyor. Elasticsearch bu alanı yalnızca bir sayı dizisi olarak ele alıyor; bu sayıların nasıl üretildiği (bir makine öğrenmesi modeliyle veya başka bir yöntemle) Elasticsearch’ün sorumluluğu değil. Bu PoC’de dense_vector alanını, vektör tabanlı aramanın nasıl çalıştığını göstermek için temel yapı taşı olarak kullandım.
Cosine benzerliği neden kullandım?
Vektörler arasındaki benzerliği ölçmek için cosine benzerliğini tercih ettim. Cosine benzerliği, iki vektörün uzunluğundan ziyade aynı yöne bakıp bakmadığına odaklanır. Bu yaklaşım, özellikle metinlerin anlamsal olarak karşılaştırıldığı senaryolarda oldukça yaygındır. Bu PoC’de cosine benzerliği sayesinde, sorgu vektörüne hangi dokümanların daha “yakın” olduğunu net şekilde gözlemleyebildim.
Basitçe ifade etmek gerekirse:
Aynı yöne bakan vektörler daha benzer kabul edilir
Farklı yöne bakan vektörlerin benzerliği düşüktür
kNN (k-Nearest Neighbors) ile ne yaptım?
kNN algoritmasını, verdiğim bir sorgu vektörüne en yakın olan k adet dokümanı bulmak için kullandım. Örneğin bu çalışmada, sorgu vektörüne en yakın ilk 2 dokümanı (k=2) döndürmesini istedim. Elasticsearch, bu dokümanları cosine benzerliği skorlarına göre sıralayarak bana geri döndü. Böylece vektör uzayında gerçekten “en yakın” sonuçların nasıl seçildiğini pratik olarak görmüş oldum.
HNSW neden önemli?
dense_vector alanını index: true olarak tanımladığımda Elasticsearch’ün otomatik olarak HNSW tabanlı bir indeks oluşturduğunu gördüm. HNSW (Hierarchical Navigable Small World), kNN sorgularının performanslı çalışmasını sağlayan bir vektör indeksleme yöntemidir. Tüm vektörleri tek tek karşılaştırmak yerine, aramayı akıllı bir grafik yapı üzerinden gerçekleştirir. Mapping çıktısında görülen int8_hnsw ifadesi, Elasticsearch’ün bu optimizasyonu otomatik olarak uyguladığını ve kNN sorgularını hızlı şekilde çalıştırabildiğini gösterdi.
Özet olarak, dense_vector ile veriyi sayısal olarak temsil ettim, cosine benzerliği ile vektörler arasındaki yakınlığı ölçtüm, kNN ile en benzer dokümanları buldum ve HNSW sayesinde bu sürecin performanslı şekilde çalıştığını pratik olarak doğruladım.
Bu çalışmada, Oracle Cloud üzerinde kurduğum sade bir PoC ortamında Elasticsearch’ün dense_vector temelli vektör arama yeteneklerini uçtan uca deneyimledim. Docker üzerinde çalışan tek node’lu bir Elasticsearch kurulumu ile başlayarak, vektör tabanlı arama için gerekli index yapısını oluşturdum ve cosine benzerliği kullanan kNN sorgularını pratik olarak test ettim. 3 boyutlu örnek vektörlerle oluşturduğum basit veri seti sayesinde, dense_vector, HNSW ve kNN algoritmalarının birlikte nasıl çalıştığını net şekilde gözlemleme imkânı buldum. Bu PoC, Elasticsearch’ün klasik metin aramasının ötesine geçerek semantik benzerlik bazlı arama senaryolarını nasıl desteklediğini göstermiş oldu. Gerçek embedding üretimi, yüksek boyutlu vektörler ve LLM/RAG entegrasyonunu ise bilinçli olarak kapsam dışında bıraktım, vektör arama mekanizmasının temel prensiplerine odaklandım.
Özetle, bu çalışmada Docker üzerinde Elasticsearch kurdum. Daha sonra bazı örnek dokümanlara karşılık gelen embedding vektörlerini index’e ekledim. Son olarak da bir sorgu vektörü vererek, bu sorgunun vektör uzayında hangi dokümanlara daha yakın olduğunu Elasticsearch üzerinden buldum. Bu çalışma, Elasticsearch’ün bir “vector database” olarak nasıl konumlandırılabileceğini anlamak için basit bir giriş niteliği taşımaktadır.
Sarav Asiye Yiğit * 21 Aralık 2025






Yorumunuzu Bırakın