Merhaba,

 

Bu yazıda Node.js ile Elasticsearch kullanımından bahsedeceğim. Elasticsearch ile ilgili detaylı bilgiye buradan ulaşabilirsiniz.

 

Örnek uygulamamızda önce IMDB Top 100 listesinde bulunan filmlerden oluşan bir json dosyasındaki verileri Elasticsearch'e aktarıp sonrasında bu verilerin üzerinde arama işlemi yapacağız.

 

İlk olarak istediğimiz bir dizine gelerek Node.js projesi oluşturalım:

npm init -y

 

Sonrasında Elasticsearch için gerekli paketi yükleyelim:

npm install elasticsearch

 

Şimdi Elasticsearch'ü ayağa kaldıralım. Ben Windows işletim sistemi kullandığım için bu işlemi Elasticsearch'ün kurulu olduğu dizindeki bin/elasticsearch.bat dosyasını çalıştırarak yapıyorum. Sonrasında localhost:9200 üzerinde şu çıktıyı alıyorum:

Projemizde esClient.js adında bir dosya oluşturarak Elasticsearch için Client tanımlaması yapalım:

const es = require('elasticsearch');
const esClient = new es.Client({
  host: 'localhost:9200'
});

module.exports = esClient;

 

index.js dosyası oluşturup Elasticsearch'e ping atalım ve sonucu gözlemleyelim:

const esClient = require('./esClient');

esClient.ping({}, async (error) => {
  if (error) {
    console.log(error);
  } else {
    console.log('Elasticsearch is running...');
  }
});

 

Dosyayı çalıştırıyoruz:

node index.js

 

Konsolda çıktımızı alıyoruz:

Elasticsearch is running...

 

Verilerimizin bulunduğu bir data.json dosyamız mevcut. İçeriği ise şu şekilde;

[
  {
    "title": "The Shawshank Redemption",
    "rank": "1"
  },
  {
    "title": "The Godfather",
    "rank": "2"
  },
  {
    "title": "The Godfather: Part II",
    "rank": "3"
  },
  {
    "title": "Pulp Fiction",
    "rank": "4"
  },
...
]

 

Bunu index.js dosyamıza dahil edelim:

const data = require('./data.json');

 

Şimdi de movies adında bir Indice oluşturalım. Indice kavramı, RDMS'deki veritabanına karşılık gelmektedir:

const index = 'movies';

await esClient.indices.create({
  index
});

 

Sonrasında verilerimizin hangi tipte olacağını belirtmek için bir mapping objesi oluşturalım:

const mapping = {
  properties: {
    title: {
      type: 'text'
    },
    rank: {
      type: 'integer'
    }
  }
};

 

Bu objeyi de oluşturduğumuz Indice'e movie Type'ı ile atayalım. Type kavramı ise RDMS'deki tabloya karşılık gelmektedir:

await esClient.indices.putMapping({
  index,
  type: 'movie',
  body: mapping,
  includeTypeName: true
});

 

Verilerimizi döngüye sokarak Elasticsearch'e aktaralım:

data.forEach(async (item, key) => {
  await esClient.index({
    index,
    type: 'movie',
    id: key + 1,
    body: item
  })
});

 

index.js dosyamızın son hali şu şekilde olacaktır:

const data = require('./data.json');
const esClient = require('./esClient');

esClient.ping({}, async (error) => {
  if (error) {
    console.log(error);
  } else {
    console.log('Elasticsearch is running...');

    const index = 'movies';

    await esClient.indices.create({
      index
    });

    const mapping = {
      properties: {
        title: {
          type: 'text'
        },
        rank: {
          type: 'integer'
        }
      }
    };

    await esClient.indices.putMapping({
      index,
      type: 'movie',
      body: mapping,
      includeTypeName: true
    });

    data.forEach(async (item, key) => {
      await esClient.index({
        index,
        type: 'movie',
        id: key + 1,
        body: item
      })
    });
  }
});

 

Şimdi çalıştırıp verileri Elasticsearch'e aktaralım:

node index.js

 

Aktardığımız verileri görmek için ise Kibana kullanacağız. Kibana ile ilgili detaylı bilgiye buradan ulaşabilirsiniz. Kibana'yı ayağa kaldırmak için ben Windows'da Kibana'nın kurulu olduğu dizindeki bin/kibana.bat dosyasını çalıştırıyorum. Sonrasında localhost:5601 üzerinde şu ekranla karşılaşıyorum:

Soldaki menüden AnalyticsDiscover kısmına gelip verileri görüntülüyorum:

 

Verileri Elasticsearch'e aktardığımıza göre artık arama işlemini gerçekleştirebiliriz. Bunun için search.js dosyası oluşturup yine Client'ı dahil ederek ping atma işlemiyle başlıyoruz:

const esClient = require('./esClient');

esClient.ping({}, async (error) => {
  if (error) {
    console.log(error);
  } else {
    console.log('Elasticsearch is running...');
  }

 

Ardından Indice verimizi tanımlıyoruz:

const index = 'movies';

 

Elasticsearch'de arama yaparken birçok sorgu çeşidinden yararlanabiliriz. Ben match_phrase_prefix'i kullanacağım. Bunu RDMS'deki LIKE sorgusuna benzetebiliriz. Diğer sorgu çeşitleriyle ilgili olarak de şu linki inceleyebilirsiniz. Şimdi sorgu objemizi oluşturalım. Örnek olarak başlığında “The” geçen filmleri arayacağız:

const searchBody = {
  query: {
    match_phrase_prefix: {
      "title": "The"
    }
  }
};

 

Arama işlemini yapalım:

const search = await esClient.search({
  index,
  type: 'movie',
  body: searchBody
});

 

Son olarak da arama işleminin sonucunu konsola yazdıralım:

const result = search.hits.hits;
result.forEach(item => {
  console.log(item._source.title);
});

 

search.js dosyasını çalıştırıp konsolda çıktımıza bakabiliriz:

node search.js

 

Çıktımız şu şekilde olacaktır:

 

Projenin Github reposuna buradan ulaşabilirsiniz.

 

Umarım yararlı olmuştur.

 

İyi çalışmalar.