May 24, 2017

Elasticsearch in Rails for Newbies

blogpost cover image
Hey Hi Hello! Today I want to show you my favourite technology. Elasticsearch is the search engine based on Lucene. Why it is nice? Let me show you a few things about this technology. 

Introduction – what is ES?

  1. You can create full-text-search. Use Elasticsearch for creating more “intelligent” search.

  2. You can use Elasticsearch if you are interested in Big Data. Elastic lets you process large amounts of data very fast.

  3. Elasticsearch has also helpful environment - e.g., Kibana (as interface for statistics) or Logstash (for logs management)

  4. Elasticsearch has many options “out of the box”. You can decide that you want to search something with only part of phrase, or you can very easily get statistics about data in your database.

I hope that above things convinced you to write application using Elasticsearch. So let’s do it!

Elasticsearch - basic information

The first thing that is important to say is that Elasticsearch is not Ruby on Rails technology. This is the reason why I want to show you ES firstly out-of Rails world.

How to install

Firstly - let’s install Elasticsearch. Go to your console and install it using the brew.

‘brew install elasticsearch’

After installation, run your ES server – just enter ‘elasticsearch’ and… that’s all. Your Elasticsearch node (the ES node will be explained later) should be available on 9200 port. Now you can go to your browser and enter ‘localhost:9200’. You can also send request by curl: ‘curl -XGET 'http://localhost:9200' ‘.

You will receive a response like this:


"name" : "Hardshell",

"cluster_name" : "elasticsearch_maro",

"version" : {

    "number" : "2.4.0",

    "build_hash" : "ce9f0c7394dee074091dd1bc4e9469251181fc55",

    "build_timestamp" : "2016-08-29T09:14:17Z",

    "build_snapshot" : false,

    "lucene_version" : "5.5.2"


"tagline" : "You Know, for Search"


Building of Elasticsearch

Elasticsearch has a non-relational database. Below you can see how it is built.


The greatest “instance”. Cluster is a collection of nodes (servers). Cluster has a name (default - “Elasticsearch”). You shouldn’t focus on a cluster, because we will use only one.


Node is just a single server. You started your node on 9200 port. Node also has a name, which is a random UUID (Universally Uniqe IDentifier). What is interesting – default name is randomized with a set of characters from the Marvel’s world ;-) In the explained sample the name of my node is “Hardshell”.


Index, collection – a set of documents. It is some kind of equivalent of a relational database table.


You can create one or more types in the index. A type is some kind of category of your index. You decide about semantics of type.


Document is some kind of information unit. It is equivalent of a record in relational database. The document has fields (like columns in relational db). The important thing is that this object is expressed as JSON (JavaScript Object Notation), which is comfortable to use.

Communication with Elasticsearch

Ok! Now you know how it is build, so we can start using ES. Firstly – let’s look at indexing. Indexing is just adding and updating documents in the database. We should send a PUT request with the collection, type, and id. Just like in a sample below (I use curl. For do this, just go to your terminal and paste it).

curl -XPUT “http://localhost:9200/employees/employee/1” -d’{

  “name”: “Adam Smith”,

  “level”: “Junior”,

  “pension”: 100000,

  “sex”: women


The second step is getting by id. Just send the same request as above, but with GET method.

curl -XGET “http://localhost:9200/employees/employee/1” -d’’

And finally - removing document. As you can imagine, the request is the similar, but with DELETE method.

curl -XDELETE “http://localhost:9200/employees/employee/1” -d’’

Searching using Elasticsearch

Now I recommend you to add at least 10-20 documents (employee type). If you don’t want to create your own set of employees, you can use mine (curl requests are available below the article).

Let’s go to this “nice part”, which is searching.

Now we will try to search documents with different groups of employees. We will use query_string, which is some kind of query (in ES called DSL).

Let’s try to search everyone who is junior. Send POST request on ‘_search’ endpoint.

curl -XPOST “http://localhost:9200/_search” -d




          “query_string”: “junior”




In response we will get JSON like this

{"took":88,"timed_out":false,"_shards":{"total":51,"successful":51,"failed":0},"hits":{"total":2,"max_score":0.83837724,"hits":[{"_index":"employees","_type":"employee","_id":"12","_score":0.83837724,"_source": {"name": "Adam Smith", "level": "Junior", "pension": 200, "sex": "man" }},{"_index":"employees","_type":"employee","_id":"11","_score":0.375,"_source": {"name": "George Bush Junior", "level": "Senior", "pension": 2000, "sex": "man" }}]}}

In this response we have very important thing - “score”. This is the “weight” of your search result.

The query presented above will search every document with “junior” word. But we want to search only people, who are juniors in company (We’ve got also “George Bush Junior” - hmm…).

Let’s try the next query, more precise.

curl -XPOST “http://localhost:9200/_search” -d




          “query_string”: “junior”,

    "fields": ["level"]




Now everything is ok;-) You told ElasticSearch that you want to search only by the “level” field. Of course, you can add another fields, like “sex” (“fields”: [“level”, “sex”]).


That’s all! Now you have a basic, but important knowledge about Elasticsearch:

  1. You know why ElasticSearch is so cool.

  2. You know how to install Elasticsearch

  3. You know how is Elasticsearch built.

  4. You know how to create, update, get, and destroy document in Elasticsearch

  5. You know how to search documents using query string query.

Nice! Congratulations! This is absolutely enough to go to the next step - using Elasticsearch in your Rails application. How to do it? I will show you soon ;-)

Below you can see data for searching;-)

curl -XPUT "http://localhost:9200/employees/employee/1" -d' {"name": "Jessica Jones", "level": "Senior", "salary": 100000, "sex": "woman" }'
curl -XPUT "http://localhost:9200/employees/employee/2" -d' {"name": "Mieszko Pierwszy", "level": "Beginer", "salary": 10, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/3" -d' {"name": "Ronald Reagan", "level": "Senior", "salary": 90000, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/4" -d' {"name": "Steve Jobs", "level": "Mid1", "salary": 15, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/5" -d' {"name": "Bill Clinton", "level": "Mid3", "salary": 4000, "sex": "woman" }'
curl -XPUT "http://localhost:9200/employees/employee/6" -d' {"name": "Elon Musk", "level": "Senior", "salary": 24000, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/7" -d' {"name": "Marek Czuma", "level": "Beginer", "salary": 0, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/8" -d' {"name": "Hayley Williams", "level": "Senior", "salary": 0, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/9" -d' {"name": "Lana Del Rey", "level": "Mid3", "salary": 70000, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/10" -d' {"name": "Jennifer Lawrence", "level": "Mid1", "salary": 2000, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/11" -d' {"name": "Goerge Bush Junior", "level": "Senior", "salary": 2000, "sex": "man" }'
curl -XPUT "http://localhost:9200/employees/employee/12" -d' {"name": "Jan Kowalski", "level": "Junior", "salary": 200, "sex": "man" }'