Elasticsearch ile Index Oluşturma ve Arama

Rahim Komaç
5 min readMar 26, 2024

--

Bir önceki yazıda Elasticsearch’ün ne oldugundan, nasıl çalıştıgından, indexleme işlemi nasıl gerçekleştiğinden ve Elasticsearch’ü Docker üzerinde nasıl çalıştırabilceğimizden bahsetmiştik. Bu yazımızda ise Docker üzerinde çalıştırdıgımız Elasticsearch’ü kullanarak indexleme, veri ekleme ve arama işlemlerini gerçekleştirecegiz.

-> Elasticsearch Nedir?

-> Elasticsearch Nasıl Çalışır?

-> Elasticsearch’ü Docker üzerinde çalıştırma

-> PHP ve GO ile Elasticsearch kullanımı

Index Oluşturma

Index oluşturmak için aşağıdaki gibi bir curl isteği atabilirsiniz. Bu işlem postman gibi bir tool ile daha rahat yapılabilir. Ben console üzerinden ilerlemeyi tercih ettim.

Aşagıdaki istek my-index adında bir index oluşturur. Indexin shards ve replica ayarları belirlenmiştir. Mapping kısmında ise indexe eklenen belgedeki alanların tiplerini belirtiyoruz. title ve content alanlarının text tipinde date alanının date ve views alanının integer tipinde oldugunu görüyoruz.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X PUT "https://localhost:9200/my_index" -H 'Content-Type: application/json' -d '
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
},
"date": {
"type": "date"
},
"views": {
"type": "integer"
}
}
}
}'

Settings belirtilmez ise default ayarlar kullanılır. Mappings belirtilmez ise de ilk veri indexlenirken otomatik olarak mapleme gerçekleştirilir. Ancak indexlenecek datanın veri tiplerini biliyor ise maplemek her zaman iyidir, aksi halde date olmasını istedigimiz alanlar keyword ya da integer olması gereken alanlar farklı bir türde maplenebilir.

Yukarıdaki istegin çıktısı ise şu şekilde olmalıdır.

{"acknowledged":true,"shards_acknowledged":true,"index":"my_index"}

Bunun dışında bir indexdeki mapping’i almak için aşağıdaki gibi bir istek atmamız yeterli olacaktır.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X GET "https://localhost:9200/my_index/_mapping"

Çıktısı da şu şekilde olacaktır.

{
"my_index": {
"mappings": {
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
},
"date": {
"type": "date"
},
"views": {
"type": "integer"
}
}
}
}
}

Diyelim ki bir alanın tipini değiştirmek istiyoruz, o halde aşağıdaki gibi bir istek yeterli olacaktır.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X PUT "https://localhost:9200/my_index/_mapping" -H 'Content-Type: application/json' -d '
{
"properties": {
"title": {
"type": "keyword"
}
}
}'

Başarılı bir şekilde çalıştıgını anlamak için aşağıdaki gibi bir çıktı görmeliyiz.

{"acknowledged":true}

Burada sakıncalı olan bir durum söz konusu, eğer daha sonradan bir tip değiştiriyor ya da yeni bir tip ekliyor isek eklenen ya da degiştirilen tipe göre inverted table güncellenmez. Bu durumda re-index yapmak zorunda kalırız.

Re-index isteği şu şekilde yapılır.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_reindex" -H 'Content-Type: application/json' -d '
{
"source": {
"index": "existing_index"
},
"dest": {
"index": "new_index"
}
}'

Aşağıdaki gibi bir çıktı almalıyız.

{
"took": 25,
"timed_out": false,
"total": 1000,
"updated": 0,
"created": 1000,
"deleted": 0,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}

Veri Ekleme

Aşağıdaki gibi bir veri seti kullanalım.

[
{
"title": "Elasticsearch Başlangıç Rehberi",
"content": "Elasticsearch hakkında detaylı bir başlangıç rehberi.",
"date": "2023-05-15",
"views": 100
},
{
"title": "Elasticsearch İleri Seviye Kılavuzu",
"content": "Elasticsearch kullanımında ileri seviye ipuçları ve teknik detaylar.",
"date": "2023-06-20",
"views": 150
},
{
"title": "Elasticsearch ile Veri Analizi",
"content": "Elasticsearch kullanarak veri analizi yöntemleri ve teknikleri.",
"date": "2023-07-10",
"views": 120
}
]

Şimdi bu verileri Elasticsearch’e ekliyoruz.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/my_index/_doc" -H 'Content-Type: application/json' -d '
{
"title": "Elasticsearch Başlangıç Rehberi",
"content": "Elasticsearch hakkında detaylı bir başlangıç rehberi.",
"date": "2023-05-15",
"views": 100
}'
Response
{
"_index": "my_index",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/my_index/_doc" -H 'Content-Type: application/json' -d '
{
"title": "Elasticsearch İleri Seviye Kılavuzu",
"content": "Elasticsearch kullanımında ileri seviye ipuçları ve teknik detaylar.",
"date": "2023-06-20",
"views": 150
}'
Response
{
"_index": "my_index",
"_type": "_doc",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/my_index/_doc" -H 'Content-Type: application/json' -d '
{
"title": "Elasticsearch ile Veri Analizi",
"content": "Elasticsearch kullanarak veri analizi yöntemleri ve teknikleri.",
"date": "2023-07-10",
"views": 120
}'
Response
{
"_index": "my_index",
"_type": "_doc",
"_id": "3",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}

Güzel. Verilerimizi de indexlediğimize göre basit bir arama sorgusu yazıp çıktısını görebiliriz.

Arama

Şimdi “İleri Seviye Elasticsearch” terimi ile bir arama gerçekleştirelim.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X GET "https://localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d '
{
"query": {
"match": {
"title": "İleri Seviye Elasticsearch"
}
}
}'

Yukarıdaki GET isteginin çıktısı ise şu şekilde olacaktır.

{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.5753642,
"hits": [
{
"_index": "sample_index",
"_type": "_doc",
"_id": "2",
"_score": 0.5753642,
"_source": {
"title": "Elasticsearch İleri Seviye Kılavuzu",
"content": "Elasticsearch kullanımında ileri seviye ipuçları ve teknik detaylar.",
"date": "2023-06-20",
"views": 150
}
}
]
}
}

Bu çıktıdaki bazı alanları açıklayalım.

took: Arama sorgusunun tamamlanması için geçen süre (milisaniye cinsinden)

hits: Arama sonucunda elde edilen belgelerin bilgilerini içeren kısım

total Toplam eşleşen belge sayısı

max_score: En yüksek skor değeri

hits: Eşleşen belgelerin detayları

  • _index: Belgelerin bulunduğu indeks adı
  • _id: Belgelerin benzersiz kimliği
  • _score: Belgelerin skor değeri (arama sonucuna göre sıralamada kullanılır)
  • _source: Belgelerin içeriği ve alanları

Şimdi sorgumuzu biraz daha karmaşık hale getirelim.

Views degeri 130'dan büyük ve content alanında Elasticsearch geçen verileri bulalım.

Sorgumuz aşağıdaki gibi olacaktır.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X GET "https://localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "content": "Elasticsearch" } },
{ "range": { "views": { "gt": 130 } } }
]
}
}
}'

Çıktısı da aşağıdaki gibi olacak.

{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931472,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "2",
"_score": 0.6931472,
"_source": {
"title": "Elasticsearch İleri Seviye Kılavuzu",
"content": "Elasticsearch kullanımında ileri seviye ipuçları ve teknik detaylar.",
"date": "2023-06-20",
"views": 150
}
}
]
}
}

Görüldüğü gibi veri setimizde views degeri 130 dan büyük olan ve içerisinde Elasticsearch geçen tek bir veri bulunmakta.

Şimdi işin içerisinde date alanını da ekleyelim. content alanında Elasticsearch terimi geçen ve en yeniden en eskiye dogru sıralanmış bir sonuç için sorgu çalıştıralım.

curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD -X GET "https://localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d '
{
"query": {
"match": {
"content": "Elasticsearch"
}
},
"sort": [
{ "date": { "order": "desc" } }
]
}

Sonuç ise beklenildigi gibi sıralı şekilde ve tüm veri seti ile birlikte gelecektir.

{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "3",
"_score": null,
"_source": {
"title": "Elasticsearch ile Veri Analizi",
"content": "Elasticsearch kullanarak veri analizi yöntemleri ve teknikleri.",
"date": "2023-07-10",
"views": 120
},
"sort": [
1678492800000
]
},
{
"_index": "my-index",
"_type": "_doc",
"_id": "2",
"_score": null,
"_source": {
"title": "Elasticsearch İleri Seviye Kılavuzu",
"content": "Elasticsearch kullanımında ileri seviye ipuçları ve teknik detaylar.",
"date": "2023-06-20",
"views": 150
},
"sort": [
1674144000000
]
},
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": null,
"_source": {
"title": "Elasticsearch Başlangıç Rehberi",
"content": "Elasticsearch hakkında detaylı bir başlangıç rehberi.",
"date": "2023-05-15",
"views": 100
},
"sort": [
1673635200000
]
}
]
}
}

Sonraki yazımızda Elasticsearch kullanarak PHP ve GO ile örnekler yapacağız.

-> PHP ve GO ile Elasticsearch kullanımı

--

--