I like my ElasticSearch a la Node.js

While ElasticSearch is easy enough to work with via its RESTful HTTP API, there are myriad client libraries available in almost every conceivable programming language. If Node.js is your language of choice, then there’s at least two actively supported libraries available.

My favorite is dubbed, albeit rather dully, ”Elastic Search Client”, but don’t let the library’s unimaginative name fool you: this is a handy library that allows you to do everything you could do via cURL with the added benefit of JavaScript callbacks. Best of all, you can use the Node Elastic Search Client in Coffeescript, which is a handy language that makes JavaScript less verbose and that ultimately compiles into JavaScript.

Accordingly, if you’re familiar with the typical RESTful API calls for creating and mapping indexes, plus indexing and searching documents, then you’ll find Elastic Search Client easy enough to pick up.

To get started, add the library as a dependency in your NPM package.json file like so:

My package.json file that lists the latest version of elasticsearchclient.
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<code class='json'><span class='line'><span class="s2">"dependencies"</span><span class="err">:</span><span class="p">{</span>
</span><span class='line'>  <span class="nt">"elasticsearchclient"</span> <span class="p">:</span> <span class="s2">"latest"</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">"mocha"</span> <span class="p">:</span> <span class="s2">"latest"</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">"should"</span> <span class="p">:</span> <span class="s2">"latest"</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">"coffee-script"</span> <span class="p">:</span> <span class="s2">"latest"</span>
</span><span class='line'><span class="p">}</span>
</span></code>

Since I happen to prefer CoffeeScript over JavaScript, I’ve also included CoffeeScript as a dependency.

Like any Node library, you’ll need to include a library it via a require statement to make use of it. In this case, I’ll require 'elasticsearchclient' and then connect to a local instance like so:

Initalizing a new client
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<code class='javascript'><span class='line'><span class="nx">ElasticSearchClient</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">'elasticsearchclient'</span>
</span><span class='line'><span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ElasticSearchClient</span> <span class="p">{</span> <span class="nx">host</span><span class="o">:</span> <span class="s1">'localhost'</span><span class="p">,</span> <span class="nx">port</span><span class="o">:</span> <span class="mi">9200</span> <span class="p">}</span>
</span></code>

Going forward, I’m going to reference a few variables, namely indexName, which is “beer_recipes” and objName, which is “beer”. What’s more, this code is using Mocha and should, so that’ll explain the various specification related statements in the examples below.

With a connection to an Elasticsearch server, I can consequently create an index like so:

Creating an index in a before clause
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<code class='javascript'><span class='line'><span class="nx">describe</span> <span class="s1">'Create and update an index'</span><span class="p">,</span> <span class="o">-></span>
</span><span class='line'>  <span class="nx">before</span> <span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>      <span class="nx">client</span><span class="p">.</span><span class="nx">createIndex</span><span class="p">(</span><span class="nx">indexName</span><span class="p">).</span><span class="nx">on</span> <span class="s1">'data'</span><span class="p">,</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>          <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">data</span>
</span><span class='line'>          <span class="nx">data</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="nx">ok</span>
</span><span class='line'>          <span class="nx">done</span><span class="p">()</span>
</span><span class='line'>      <span class="p">.</span><span class="nx">exec</span><span class="p">()</span>
</span></code>

And I can update the index’s mapping too. Just use the putMapping call:

Updating an Index mapping
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<code class='javascript'><span class='line'><span class="nx">it</span> <span class="s1">'should support a mapping put which changes the analyzer'</span><span class="p">,</span> <span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>  <span class="nx">snowball</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"mappings"</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">"beer"</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">"properties"</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">"ingredients"</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">"type"</span> <span class="o">:</span> <span class="s2">"string"</span><span class="p">,</span> <span class="s2">"analyzer"</span> <span class="o">:</span> <span class="s2">"snowball"</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}}</span>
</span><span class='line'>  <span class="nx">client</span><span class="p">.</span><span class="nx">putMapping</span><span class="p">(</span><span class="nx">indexName</span><span class="p">,</span> <span class="nx">objName</span><span class="p">,</span> <span class="nx">snowball</span><span class="p">).</span><span class="nx">on</span> <span class="s1">'data'</span><span class="p">,</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>      <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">data</span>
</span><span class='line'>      <span class="nx">data</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="nx">ok</span>
</span><span class='line'>      <span class="nx">done</span><span class="p">()</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">exec</span><span class="p">()</span>
</span></code>

In this case, the actual mapping JSON document is identical to what I’d have to pass via cURL, for instance.

You should start to notice a pattern with respect to how the Elastic Search Client deals with callbacks – using an on method, you can register a callback for 'data', which essentially entails the response from the server; moreover, you can also register a listener for 'error', which as you can imagine, gets invoked if there is a problem.

Deleting an index is just as easy as creating one too:

Deleting an index
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<code class='javascript'><span class='line'><span class="nx">after</span> <span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>  <span class="nx">client</span><span class="p">.</span><span class="nx">deleteIndex</span><span class="p">(</span><span class="nx">indexName</span><span class="p">).</span><span class="nx">on</span> <span class="s1">'data'</span><span class="p">,</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">-></span>
</span><span class='line'>      <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">data</span>
</span><span class='line'>      <span class="nx">data</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="nx">ok</span>
</span><span class='line'>      <span class="nx">done</span><span class="p">()</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">exec</span><span class="p">()</span>
</span></code>

To index a document, you simply use the index function like so:

Related:
1 2 Page 1
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.