ElasticSearch
Resmi Web Sitesi: Elasticsearch: Resmi Dağıtık Arama ve Analiz Motoru | Elastic
Elasticsearch, sürekli ortaya çıkan çeşitli kullanım durumlarını çözebilen dağıtık, RESTful tarzda bir arama ve veri analiz motorudur. Elastic Stack'in çekirdeği olarak, Elasticsearch verilerinizi merkezi olarak depolar, hızlı arama yapmanızı, alaka düzeyini ince ayar yapmanızı, güçlü analizler gerçekleştirmenizi ve ölçeklendirmeyi kolaylaştırır. Bu makale, Go kullanılarak Elasticsearch'te bazı temel işlemlerin nasıl yapılacağını açıklayacaktır, örneğin ekleme, silme, güncelleme ve sorgulama gibi. Eğer Elasticsearch'e aşina değilseniz, lütfen önce kendi başınıza öğrenin.
Bağımlılıklar
Resmi bağımlılık kütüphanesini indirin
$ github.com/elastic/go-elasticsearch/v7Eğer ES8 kullanıyorsanız, versiyonu değiştirin
$ github.com/elastic/go-elasticsearch/v8TIP
Bu makalede ES8 kullanılarak gösterilecektir
Bağlantı
Yeni bir bağlantı oluşturmak için elasticsearch.NewClient fonksiyonunu kullanın
func NewClient(cfg Config) (*Client, error)ES8+ varsayılan olarak HTTPS bağlantısı kullanır. HTTPS bağlantısı kurarken, ya CA sertifikası kullanın ya da CA parmak izi kullanın. Her ikisi de Elasticsearch sunucusunda oluşturulur. Bir örnek aşağıdaki gibidir:
client, err := elasticsearch.NewClient(elasticsearch.Config{
Addresses: []string{"https://192.168.153.132:9200"},
Username: "elastic",
Password: "TETJ8IY+ifbt8SLc+RRQ",
CertificateFingerprint: "C0E9867C7D446BFF72FE46E7E9FE3455E970A8ADB0D3DF0E1472D55DB2612CD5",
})elasticsearch tarafından sağlanan Go API'leri temelde opsiyonel fonksiyonlardır. Örneğin, ping API'si ile servisin kullanılabilir olup olmadığını test edin:
pingResp, err := client.Ping(client.Ping.WithPretty(), client.Ping.WithHuman())
if err != nil {
panic(err)
}
fmt.Println(pingResp)Çıktı
[200 OK]Bir başka örnek olarak, Info API ile servis durumunu kontrol edin:
infoResp, err := client.Info(client.Info.WithHuman())
if err != nil {
panic(err)
}
fmt.Println(infoResp)Çıktı
[200 OK] {
"name" : "db-debian12",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "OMbDIsNwTFiuyjNF9Xnpbw",
"version" : {
"number" : "8.15.0",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "1a77947f34deddb41af25e6f0ddb8e830159c179",
"build_date" : "2024-08-05T10:05:34.233336849Z",
"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"
}TIP
ES API'leri ile ilgili herhangi bir sorunuz varsa, lütfen resmi dokümantasyona başvurun ES Restful API.
İndeks
Go API aracılığıyla indeks işlemleri yapın. İndeks işlemleriyle ilgili tüm API'ler esapi.Indices yapısında bulunur:
// Indices contains the Indices APIs
type Indices struct {
AddBlock IndicesAddBlock
Analyze IndicesAnalyze
ClearCache IndicesClearCache
Clone IndicesClone
Close IndicesClose
...
...
ValidateQuery IndicesValidateQuery
}Oluşturma
Bir indeks oluşturun, aşağıdaki gibi:
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
},
"salary": {
"type": "double"
}
}
}
}Gerçek işlem, HTTP isteği göndermeye benzer:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
dsl := bytes.NewBufferString(`{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
},
"salary": {
"type": "double"
}
}
}
}`)
createIndices := client.Indices.Create
resp, err := createIndices("user", createIndices.WithBody(dsl))
if err != nil {
panic(err)
}
fmt.Println(resp)
}Çıktı
[200 OK] {"acknowledged":true,"shards_acknowledged":true,"index":"user"}Alma
Birden fazla indeks bilgisi alın:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
get := client.Indices.Get
response, err := get([]string{"user"}, get.WithPretty(), get.WithHuman())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {
"user" : {
"aliases" : { },
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
},
"salary" : {
"type" : "double"
}
}
},
"settings" : {
"index" : {
"creation_date_string" : "2024-09-23T04:35:04.528Z",
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "3",
"provided_name" : "user",
"creation_date" : "1727066104528",
"number_of_replicas" : "2",
"uuid" : "AvhhuqV2ShGkRP9z7XbdDA",
"version" : {
"created_string" : "8.14.4-snapshot[8512000]",
"created" : "8512000"
}
}
}
}
}Analiz
Belirli bir indeks için metin dizelerini analiz edin ve sonuçları döndürün. Metin aşağıdaki gibidir:
{
"analyzer": "standard",
"text": ["this is a test", "the second text"]
}Kod
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
analyze := client.Indices.Analyze
dsl := bytes.NewBufferString(`{
"analyzer" : "standard",
"text" : ["this is a test", "the second text"]
}`)
response, err := analyze(analyze.WithIndex("user"), analyze.WithBody(dsl), analyze.WithPretty(), analyze.WithHuman())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {
"tokens" : [
{
"token" : "this",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "is",
"start_offset" : 5,
"end_offset" : 7,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "a",
"start_offset" : 8,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "test",
"start_offset" : 10,
"end_offset" : 14,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "the",
"start_offset" : 15,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 104
},
{
"token" : "second",
"start_offset" : 19,
"end_offset" : 25,
"type" : "<ALPHANUM>",
"position" : 105
},
{
"token" : "text",
"start_offset" : 26,
"end_offset" : 30,
"type" : "<ALPHANUM>",
"position" : 106
}
]
}Silme
Belirtilen birden fazla indeksi silin:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
indicesDelete := client.Indices.Delete
response, err := indicesDelete([]string{"user"})
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {"acknowledged":true}Yukarıdaki bu API'lerde, istek gövdesini manuel olarak serileştirmeniz gerektiği görülebilir. Resmi Go struct'larına dönüştürmemiştir. Yanıt gövdelerini de manuel olarak işlemeniz gerekir. Bunlar yaygın olarak kullanılan API'lerdir, diğerleri de büyük ölçüde benzer şekilde çalışır.
Doküman
Oluşturma
Aşağıdaki gibi bir doküman oluşturun:
{
"name": "jack",
"age": 12,
"salary": 5701.1
}Kod
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
doc := bytes.NewBufferString(`{
"name": "jack",
"age": 12,
"salary": 5701.1
}`)
create := client.Create
response, err := create("user", "1", doc, create.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[201 Created] {
"_index" : "user",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}Alma
Belirli bir ID'ye sahip dokümanı alın:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
get := client.Get
response, err := get("user", "1", get.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {
"_index" : "user",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "jack",
"age" : 12,
"salary" : 5701.1
}
}Güncelleme
Doküman içeriğini güncelleyin:
{
"doc": {
"name": "jack",
"age": 35,
"salary": 5701.1
}
}Kod
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
doc := bytes.NewBufferString(`{
"doc": { "name": "jack",
"age": 35,
"salary": 5701.1
}}`)
update := client.Update
response, err := update("user", "1", doc, update.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {
"_index" : "user",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}Update API ayrıca upsert gibi işlemler için script desteği verir. Daha fazla bilgi için Update API adresine gidin.
Silme
ID ile belirli bir dokümanı silin:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
deleteDoc := client.Delete
response, err := deleteDoc("user", "1", deleteDoc.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Çıktı
[200 OK] {
"_index" : "user",
"_id" : "1",
"_version" : 3,
"result" : "deleted",
"_shards" : {
"total" : 3,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}Arama
ES API'lerinde en yaygın kullanılan arama API'sidir. Aşağıda kullanım örnekleri gösterilecektir. Önce verileri hazırlayın.
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
for i := range 10 {
doc := bytes.NewBufferString(fmt.Sprintf(`{
"name": "%s",
"age": %d,
"salary": %f
}`, randomName(), rand.Intn(18)+18, rand.Float64()))
create := client.Create
response, err := create("user", string('0'+i), doc, create.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}
}
func randomName() string {
var b []byte
for range 10 {
b = append(b, byte(rand.Intn(26)+'a'))
}
return string(b)
}Arama API'si, HTTP API ile tamamen aynı şekilde çalışır.
Tüm dokümanları sorgula:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
dsl := bytes.NewBufferString(`{"query": {"match_all":{}}, "size": 1}`)
search := client.Search
response, err := search(search.WithBody(dsl), search.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Belirli bir alanı eşleştir:
func main() {
client, err := newClient()
if err != nil {
panic(err)
}
dsl := bytes.NewBufferString(`{"query": {"term":{ "age": 22 } }, "size": 1}`)
search := client.Search
response, err := search(search.WithBody(dsl), search.WithPretty())
if err != nil {
panic(err)
}
fmt.Println(response)
}Özet
Temel işlemler büyük ölçüde bunlardır. HTTP API ile tamamen aynı şekilde çalışır. Elasticsearch'i öğrendiğinizde, Go API'lerini kullanmak sorun olmayacaktır. cluster, data stream gibi daha gelişmiş işlemler için kendi keşfinizi yapmanız gerekecektir.
