Tuesday, January 14, 2014

ElasticSearch from AngularJS (fun w/ elasticsearch-js!)

We've recently switched over to AngularJS (from ExtJS).  And if you've been following along at home, you know that we are *HUGE* ElasticSearch fans.  So today, I set out to answer the question, "How easy would it be to hit Elastic Search directly from javascript?"  The answer lies below. =)

First off, I should say that we recently hired a rock-star UI architect (@ddubya) that has brought with him Javascript Voodoo the likes of which few have seen.  We have wormsign... and we now have grunt paired with bower for package management.  Wicked cool.

So, when I set out to connect our Angular App to Elastic Search, I was pleased to see that Elastic Search Inc recently announced a javascript client that they will officially support.  I quickly raced over to bower.io and found a rep listed in their registry...

I then spent the next two hours banging my head against a wall.

Do NOT pull the git repo via bower even though it is listed in the bower registry!  There is an open issue on the project to add support for bower.  Until that closes, the use of Node's require() within the angular wrapper prevents it from running inside a browser.  Using browserify, the ES guys kindly generate a browser compatible version for us.   So *use* the browser download (zip or tar ball) instead!

Once you have the download, just unzip it in your app.  Load the library with a script tag:
<script src="third_party_components/elasticsearch-js/elasticsearch.angular.js"></script>
That code registers the elastic search module and creates a factory that you can use:
angular.module('elasticsearch', [])
  .factory('esFactory', ['$http', '$q', function ($http, $q) {

    var factory = function (config) {
      config = config || {};
      config.connectionClass = AngularConnector;
      config.$http = $http;
      config.defer = function () {
        return $q.defer();
      return new Client(config);
You can then create a service that uses that factory, creating an instance of a client that you can use from your controller, etc:
  .service('es', function (esFactory) {
  return esFactory({
    host: 'search01:9200'
Then, assuming you have a controller defined similar to:
  .controller('searchController', ['$window', '$scope', 'es', function ($window, $scope, es) {
The following code, translated from their example, works like a champ!
  requestTimeout: 1000,
  hello: "elasticsearch!"
}, function (error) {
  if (error) {
    console.error('elasticsearch cluster is down!');
  } else {
    console.log('All is well');
From there, you can extend things to do much more... like search! =)

Kudos to the Elastic Search Inc crew for making this available.


Keith Garrod said...

Thanks to this post I only spent an hour banging my head against the wall! All the other examples I found were outdated.

Danny said...

I'm currently working on a project and considering to use ElasticSearch as our search engine. Is it a good approach to hit ElasticSearch directly from browser?

Azad Memon said...

If I understand correctly, elastic search for browser Allows you to directly connect to es from the browser. What would be the advantage of this over using a nodejs server to respond to a request by the browser and appropriately query es?

Administrador del Blog said...

Hi Brian,

I am trying to follow your blog but calls to elasticsearch-js just do nothing. Well, they log to the console as if everything is ok but never enter the callback function. Using wireshark I have confirmed that they don't even try to connect to the server:

requestTimeout: 1000,
ignore: [404],
hello: 'elasticsearch!'
}, function (error, response, status) {
if (error) {
console.error('elasticsearch cluster is down!');
} else {
console.log('All is well response = ' + response + ' and status = ' + status);

INFO: 'INFO: 2014-04-15T10:32:51Z
Adding connection to http://ourHost:9200/

DEBUG: 'DEBUG: 2014-04-15T10:32:51Z
starting request { method: 'HEAD',
requestTimeout: 1000,
castExists: true,
path: '/',
ignore: [ 404 ],
query: { hello: 'elasticsearch!' } }

Any clue what might be happening?

Arvind Das said...

Hi Brian

I am getting following error.

Error: [$injector:unpr] Unknown provider: esProvider <- es

Can you please tell me what could be the issue ?


Arvind Das said...
This comment has been removed by the author.
osvaldo anderson said...

There are tutorials that is specially designed to help you learn AngularJS as quickly and efficiently as possible.

for IT the said...

Great Article

Angularjs Training | Angularjs Training in Chennai

caroline jesi said...

Pretty post, I hope your site useful for many users who want to learn basics of programming to enhance their skill for getting good career in IT, thanks for taking time to discuss about fundamental programming niche.
With Regards,
Angularjs training in chennai|Angularjs course in chennai

Priya said...

The oracle database is capable of storing the data in two forms such as logically in the form of table spaces and physically like data files.
Oracle Training in Chennai | oracle dba training in chennai

Nikshitha S said...

Very informative content that guided me to know the details about the training offered in different technology. Angular JS is a structural framework for dynamic web application and angular's data binding eliminates much of the code that you would otherwise write it.
Angularjs Training in Chennai | angularjs course in chennai