This post is about whoosh as haystack backend, there are several backends to be used like: xapian which is written in c++, also java solr, elasticsearch...

Whoosh is a fast, featureful full-text indexing and searching library implemented in pure Python, in addition Every part of how Whoosh works can be extended or replaced to meet your needs exactly.

as described in the docs:

    Whoosh might be useful in the following circumstances:

  • Anywhere a pure-Python solution is desirable to avoid having to build/compile native libraries (or force users to build/compile them).
  • As a research platform (at least for programmers that find Python easier to read and work with than Java ;)
  • When an easy-to-use Pythonic interface is more important to you than raw speed.

You can download the source from https://github.com/saady/whoosh_demo

  pip install django
  pip install haystack
  pip install whoosh

let's create an app and call it "search".

  django-admin startapp search

In your settings files:

  INSTALLED_APPS = (
    ....
    'apps.search',
    'haystack',
  )

Haystack connections:

  HAYSTACK_CONNECTIONS = {
    'default': {
      'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
      'PATH': os.path.join(base(), 'whoosh_index')
    },
  }

Our search engine is going to help me to organize, index, and retrieve my gutenberg favorite books, therefore
my models are:

  from django.contrib.auth.models import User
  from django.db import models

  class Author(User):
    pass

  class Book(models.Model):
    title = models.CharField(max_length=300)
    author = models.ForeignKey(Author)
    isbn = models.CharField(max_length=300)
    resume = models.TextField()

    def __unicode__(self):
      return self.title

Django Migrations:

  ./manage.py makemigrations search
  ./manage.py migrate

Inside my app "search" I well add a file

  searche_indexes.py

That helps in handling my data about books and authors

  from haystack import indexes
  from .models import Book, Author

  class BookIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    author = indexes.CharField(model_attr='author')
    title = indexes.CharField(model_attr='title')
    isbn = indexes.CharField(model_attr='isbn')
    resume = indexes.CharField(model_attr='resume')

    def get_model(self):
      return Book

  class AuthorIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    first_name = indexes.CharField(model_attr='first_name')

    def get_model(self):
        return Author

My favorite book is Flatland by Edwin Abbott Abbott, which is available on http://www.gutenberg.org/ebooks/97.

now create those text files and add the attached tags (I am assuming that your templates are inside templates directory)

  

  templates/search/indexes/search/author_text.txt

  {{ object.first_name }}
  {{ object.last_name }}

  templates/search/indexes/search/book_text.txt

  {{ object.title }}
  {{ object.author.first_name }}
  {{ object.resume }}

  

now lets build the index:

  ./manage.py rebuild_index

now you have your index files.
Lets create a search.html page, where we can search for authors or books

  templates/search/search.html
  <h2>Search</h2>
  <form method="get" action=".">
    <table>
      {{ form.as_table }}
      <tr>
        <td></td>
        <td>
          <input type="submit" value="Search">
        </td>
      </tr>
    </table>
    {% if query %}
      <h3>Results</h3>
      {% for result in page.object_list %}
        <p>
          <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
        </p>
    {% empty %}
      <p>No results found.</p>
    {% endfor %}
    {% if page.has_previous or page.has_next %}
      <div>
        {% if page.has_previous %}
          <a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>
        {% endif %}
        |
        {% if page.has_next %}
          <a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>
        {% endif %}
      </div>
    {% endif %}
    {% else %}
      {# Show some example queries to run, maybe query syntax, something else? #}
    {% endif %}
  </form>

Now navigate to

  http://localhost:8000/search/

and start making your search queries.