What is Elasticsearch, Why do we need it and how to implement ?

Elasticsearch is a open source, NOSQL, distributed full text database. Which means that this database is document based instead of using tables or schema, we use documents. lots and lots of documents. Elasticsearch is a real-time distributed and open source full-text search and analytics engine.

Why do we need it?

Considering the limitations of full text search on relational database, people feel to use elasticsearch so that we can achieve the speed we would like in searching, index millions of documents. Elasticsearch can perform queries across all those millions of documents and return accurate results in a fraction of a second.

Elasticsearch – General Features

The general features of Elasticsearch are as follows −

  • scalable up to petabytes of structured and unstructured data.
  • A replacement of document stores like MongoDB and RavenDB.
  • Denormalization to improve the search performance.
  • One of the popular enterprise search engines, which is currently being used by many big organizations.

Comparison between Elasticsearch and RDBMS

In Elasticsearch, index is a collection of type just as database is a collection of tables in RDBMS (Relational Database Management System). Every table is a collection of rows just as every mapping is a collection of JSON objects Elasticsearch.

RDBMS Elasticsearch
Database Index
Shard Shard
Table Mapping/Type
Field Field
Tuple JSON Object

In this blog we are going to see the basic operation of Elasticsearch through API

The elasticsearch can be downloaded from link

The ElasticSearch runs on default port is 9200. you can change it by changing http.port inside elasticsearch.yml file present in bin directory. You can install Sense Plugin from chrome web store is a GUI Query tool for Elasticsearch.

The Below Examples are executed through Sense Plugin

Create a Index

The create index API allows to instantiate an index. The following example Create a Index named ”student”.

API - PUT /student

Result:

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

Create a Mapping

The PUT mapping API allows you to add a new type to an existing index. The following example create mapping named “student_Details” in the “student” index.

API -  PUT student/_mapping/student_Details
{
      "properties": {
        "student_name": {
          "type": "text"
        },"student_id":{
            "type": "text"
        },
        "Mark":{
            "type": "integer"
        },
        "result":{
            "type":"text"
        }
      }
}

Result:

{
   "acknowledged": true
}

Add a Document

The index API adds or updates a typed JSON document in a specific index, making it searchable. The following example inserts the JSON document into the “student” index, under a type called “student_Details” with an id of 1. If you didn’t give the id it will assign automatically.

API -  PUT student/student_Details/1
{
    "student_name":"Joseph",
    "student_id":"1",
    "Mark":88,
    "result":"Pass"
}

Result:

{
   "_index": "student",
   "_type": "student_Details",
   "_id": "1",
   "_version": 1,
   "result": "created",
   "_shards": {
      "total": 2,
      "successful": 1,
      "failed": 0
   },
   "created": true
}

Bulk Index Document

If you want to perform many index/delete operations in a single API call use bulk API.The following example add two document into the “student” index, under a type called “student_Details” with an id of 2 & 3.

API -  POST student/_bulk
{"index":{"_index":"student", "_type":"student_Details", "_id":"2"}}
{"student_name":"Abraham", "student_id":"2", "Mark":"25","result":"Fail"}
{"index":{"_index":"student", "_type":"student_Details", "_id":"3"}}
{"student_name":"Martin", "student_id":"3", "Mark":"55","result":"Pass"}

Result:

{
   "took": 91,
   "errors": false,
   "items": [
      {
         "index": {
            "_index": "student",
            "_type": "student_Details",
            "_id": "2",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "created": true,
            "status": 201
         }
      },
      {
         "index": {
            "_index": "student",
            "_type": "student_Details",
            "_id": "3",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "created": true,
            "status": 201
         }
      }
   ]
}

Search a Document

The get API allows you to search a document from the index.The following example get documents which student name has start a first letter “j” from student_Details type.

API - GET student/student_Details/_search
{
    "query": {
        "match_phrase_prefix": {
           "student_name": "j"
        }
    }
}

Result:

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.2876821,
      "hits": [
         {
            "_index": "student",
            "_type": "student_Details",
            "_id": "1",
            "_score": 0.2876821,
            "_source": {
               "student_name": "Joseph",
               "student_id": "1",
               "Mark": 88,
               "result": "Pass"
            }
         }
      ]
   }
}

Update a Document

In Elastic search add API uses Update a document. if the document_id exist update a document, otherwise add a document

Delete a Document

The delete API allows you to delete index, mapping, document

API – DELETE student/student_Details/1

Let’s explore the elasticsearch with Node.js Implementation

Use elasticsearch node modules to access elasticsearch in node.js

npm install elasticsearch

Configuring the Elasticsearch

The first Step is, access the elasticsearch with the node.js program. We can access elasticsearch with its ip and port no. The following code is access local elasticsearch with node.js program. The below code elasticsearch variable is a elasticsearch library, Bluebird variable is a promises library to use callback function, client variable connects the elasticsearch.

var elasticsearch = require('elasticsearch');
var Bluebird = require('bluebird');
var client = new elasticsearch.Client({
   host: 'localhost:9200',
   log: 'info',
   defer: function () {
       return Bluebird.defer(); // uses bluebird promises service
   },
})

Create a Index

The following node.js code create a “student” index in elasticsearch using callback function. The below code client denotes the elasticsearch configuration.
Note: Elaticsearch Index name should be in lowercase letter

function createIndex(indexName) {
   return client.indices.create({
       index: indexName,
   })
}
 
createIndex("student").then(function(result){
   console.log(result);
}).catch(function(err){
console.log(err);
})

Create a Mapping

The below node.js code create the “student_Details” in mapping under student “index” using callback function.

function createMapping(mappingObject) {
   return client.indices.putMapping(mappingObject);
}
 
var mappingObject = {
   type: "student_Details",
   body: {
       properties: {
           student_name: {
               "type": "text"
           },
           student_id: {
               "type": "text"
           },
           Mark: {
               "type": "integer"
           },
           result: {
               "type": "text"
           }
       }
   }
}
 
createMapping(mappingObject).then(function (result) {
   console.log(result);
}).catch(function (err) {
   console.log(err);
})

Add a Document

The below node.js code add the document in student_Details type under student index using callback function. Here documentObj is object which contains the document data.

function documentAdd(document) {
   return client.index(document);
}
 
var documentObj = {
   index: "student",
   type: "student_Details",
   id: String(1),
   body: {
       student_name: "Joseph",
       student_id: "1",
       Mark: 88,
       result: "Pass"
   }
}
 
documentAdd(documentObj).then(function(result){
   console.log(result)
}).catch(function(err){
   console.log(err);
})

Bulk Index Document

The below node.js code add the two document in student_Details type under student index. Here bulkIndexObj is object which contains body property is array which holds the bulk index data.

function bulkIndex(bulkIndexObj) {
   return client.bulk(bulkIndexObj)
}
 
var bulkIndexObj = {
   index: "student",
   type: "student_Details",
   body: [{
       index: {
           _index: "student",
           _type: "student_Details",
           _id: String(2)
       }
   },{
       student_name:"Abraham",
       student_id:"2",
       Mark:"25",
       result:"Fail"
   },
   {
       index: {
           _index: "student",
           _type: "student_Details",
           _id: String(3)
       }
   },{
       student_name:"Martin",
       student_id:"3",
       Mark:"55",
       result:"Pass"
   }]
}
bulkIndex(bulkIndexObj).then(function(result){
console.log(result)
}).catch(function(err){
console.log(err);
})

Search a Document

The below node.js code get documents which student name has start a first letter “j” from student_Details type.

function search() {
   return client.search({
       index: "student",
       type: "student_Details",
       body: {
           query: {
               match_phrase_prefix: {
                   "student_name": "j"
               }
           }
       }
   });
}
search().then(function(result){
   console.log(result)
}).catch(function(err){
   console.log(err);
})

Delete a Document

The below node.js code delete a document which id has “3” in student_Details type.

function deleteDocument(id){
 return client.delete({
   index: "student",
   type: "student_Details",
   id: id
 })
}
deleteDocument("3").then(function(result){
console.log(result)
}).catch(function(err){
   console.log(err)
})

Elasticsearch – Disadvantages

Elasticsearch does not have multi-language support in terms of handling request and response data only possible in JSON.