Back
August 6, 2013
I probably don't need to elaborate much on the importance of search. Even if you know the structure of your data, the power of being able to type a simple term and find all pieces of data related to it is truly magical.
At Sold, search has dramatically increased our productivity. We use it for both user-facing and admin-facing roles. For customers posting an item to sell, we provide fuzzy autocomplete and search. For customer service, we are able to find and resolve issues within seconds due to the ease of finding all data related to anything the customer provides us.
Our stack mainly consists of node.js and MongoDB, and we use mongoose to model our data.
We developed an npm module called elmongo that allows us to easily integrate Elasticsearch with our mongoose data, giving us the full power of highly available, distributed search.
Here's how to go from zero to search in just a couple minutes:
If you have homebrew, you can install and run Elasticsearch with this one-liner:
brew install elasticsearch && elasticsearch
Or you can install Elasticsearch and run it in the background with this one-liner (assuming you have a ~/bin directory):
curl http://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.1.zip -o temp-es.zip && unzip temp-es.zip && rm temp-es.zip && mv elasticsearch-0.90.1 ~/bin/elasticsearch && ~/bin/elasticsearch/bin/elasticsearch
Make a simple query to make sure it's running:
curl -XGET localhost:9200
You should see something like:
{ "ok" : true, "status" : 200, "name" : "Grizzly", "version" : { "number" : "0.90.2", "snapshot_build" : false, "lucene_version" : "4.3.1" }, "tagline" : "You Know, for Search" }
If you have issues with installation, check the installation docs.
Install elmongo:
npm install elmongo
Now let's integrate our data with Elasticsearch.
Create a Mongoose schema and add the elmongo plugin:
var mongoose = require('mongoose'), elmongo = require('elmongo'), Schema = mongoose.Schema var Cat = new Schema({ name: String }) Cat.plugin(elmongo)
Add your existing data to the search index:
Cat.sync(function (err) { // all cats are now searchable in elasticsearch })
Now your Cat schema has all the power of Elasticsearch. Here's how you can search on the model:
Cat.search({ query: 'simba' }, function (err, results) { console.log('search results', results) })
You can perform fuzzy queries:
Cat.search({ query: 'Sphinxx', fuzziness: 0.5 }, function (err, results) { console.log('search results', results) })
Search only in specific fields:
Cat.search({ query: 'persian', fields: [ 'breed', 'name' ] }, function (err, results) { console.log('search results', results) })
Filter the results using a where clause:
Cat.search({ query: 'Siamese', where: { age: 10 } }, function (err, results) { console.log('search results', results) })
And more!
After the initial .sync(), any Cat models you create/edit/delete with mongoose will be up-to-date in Elasticsearch. Also, elmongo reindexes with zero downtime. This means that your data will always be available in Elasticsearch even if you're in the middle of reindexing.
Check out the elmongo repository here for the full documentation and usage examples.
Enjoy!