Django, Haystack and Elasticsearch – Part 1

I’m wrapping up a little side project at the moment (more on that very soon) which required full-text search, autocomplete, and a few other bits of search related functionality.

After some research I landed upon the combination of Elasticsearch and the awesome Django application Haystack.

First step was to get Elasticsearch up and running locally on OS X…

1) Download latest zip fromĀ http://www.elasticsearch.org/overview/elkdownloads/. A good spot is:

/opt/elasticsearch-1.1.x

2) Create the following directories:

/opt/elasticsearch-1.1.x/data
/opt/elasticsearch-1.1.x/work
/opt/elasticsearch-1.1.x/logs

3) Add the following to your .profile (allows you to run Elasticsearch from the command prompt without the full path):

# elasticsearch
export ES_HOME=/opt/elasticsearch-1.1.x
PATH=$ES_HOME/bin:$PATH

view raw
.profile
hosted with ❤ by GitHub

4) Update the following values in the Elasticsearch config file:

# /opt/elasticsearch-1.1.x/config/elasticsearch.yml
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["127.0.0.1"]
cluster.name: elasticsearch
network.host: 127.0.0.1
http.port: 9200
path.conf: /opt/elasticsearch-1.1.x/config
path.data: /opt/elasticsearch-1.1.x/data
path.work: /opt/elasticsearch-1.1.x/work
path.logs: /opt/elasticsearch-1.1.x/logs

view raw
elasticsearch.yml
hosted with ❤ by GitHub

5) Ensure all requirements are installed (django-haystack, pyelasticsearch, requests, simplejson):

pip install django-haystack
pip install pyelasticsearch

view raw
install.sh
hosted with ❤ by GitHub

6) You should now be able to start Elasticsearch:

$ elasticsearch
[2014-05-14 08:15:05,257][INFO ][node ] [Aminedi] version[1.1.1], pid[46224], build[f1585f0/2014-04-16T14:27:12Z]
[2014-05-14 08:15:05,258][INFO ][node ] [Aminedi] initializing …
[2014-05-14 08:15:05,271][INFO ][plugins ] [Aminedi] loaded [], sites []
[2014-05-14 08:15:07,136][INFO ][node ] [Aminedi] initialized
[2014-05-14 08:15:07,136][INFO ][node ] [Aminedi] starting …
[2014-05-14 08:15:07,211][INFO ][transport ] [Aminedi] bound_address {inet[/127.0.0.1:9300]}, publish_address {inet[/127.0.0.1:9300]}
[2014-05-14 08:15:10,262][INFO ][cluster.service ] [Aminedi] new_master [Aminedi][X4diAes4TrOMTk4eAdbhnA][mbp.home][inet[/127.0.0.1:9300]], reason: zen-disco-join (elected_as_master)
[2014-05-14 08:15:10,284][INFO ][discovery ] [Aminedi] elasticsearch/X4diAes4TrOMTk4eAdbhnA
[2014-05-14 08:15:10,298][INFO ][http ] [Aminedi] bound_address {inet[/127.0.0.1:9200]}, publish_address {inet[/127.0.0.1:9200]}
[2014-05-14 08:15:10,784][INFO ][gateway ] [Aminedi] recovered [1] indices into cluster_state
[2014-05-14 08:15:10,785][INFO ][node ] [Aminedi] started

view raw
elasticsearch.sh
hosted with ❤ by GitHub

7) Add Haystack to your Django config:

# add to installed apps
INSTALLED_APPS = (
'haystack',
)
# haystack search using elasticsearch
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'haystack',
},
}
# http://django-haystack.readthedocs.org/en/latest/signal_processors.html
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# increase the default number of results (from 20)
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 40

view raw
config.py
hosted with ❤ by GitHub

8) After you’ve added your search indexes, you can use manage.py to rebuild the search index:

$ python manage.py rebuild_index