Search code examples
pythondjangopython-3.xdjango-haystackwhoosh

Haystack with Whoosh not returning any results


I've installed Django-Haystack and Whoosh and set it all up following the haystack documentation, but no matter what I search for I always get "No results found." on the search page, despite the index apparently being OK.

When running "manage.py rebuild_index" it correctly states:

Indexing 12 assets
  indexed 1 - 12 of 12 (worker PID: 1234).

And when running this in a Django shell:

from whoosh.index import open_dir
ix = open_dir('mysite/whoosh_index')
from pprint import pprint
pprint(list(ix.searcher().documents()))

It correctly returns all details of the 12 indexed assets, so it looks like the index is fine, but no matter what I search for I cannot get any results, only "No results found"!

I have followed the advice in every other similar question on StackOverflow (and everywhere else that popped up on Google) to no avail.

Does anyone have any suggestions?

Files used (edited for brevity):

settings.py

INSTALLED_APPS = [
....
'haystack',
'assetregister',
....
]

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

models.py

class Asset(models.Model):
    asset_id = models.AutoField(primary_key=True)
    asset_description = models.CharField(max_length=200)
    asset_details = models.TextField(blank=True)

search_indexes.py

from haystack import indexes
from .models import Asset

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

    def get_model(self):
        return Asset

    def no_query_found(self):
        # The .exclude is a hack from another stackoverflow question that prevents it returning an empty queryset
        return self.searchqueryset.exclude(content='foo')

    def index_queryset(self, using=None):
        return self.get_model().objects

/templates/search/indexes/assetregister/asset_text.txt

{{ object.asset_description }}
{{ object.asset_details }}

urls.py

urlpatterns = [
    url(r'^search/', include('haystack.urls')),
]

search.html

<h2>Search</h2>

<form method="get" action=".">
    <table>
        {{ form.as_table }}
        <tr>
            <td>&nbsp;</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.asset_description }}</a>
            </p>
        {% empty %}
            <p>No results found.</p>
        {% endfor %}

    {% else %}
        {# Show some example queries to run, maybe query syntax, something else? #}
    {% endif %}
</form>

And just in case it's useful, my "pip freeze":

Django==1.9.3
django-cleanup==0.4.2
django-haystack==2.5.0
django-pyodbc-azure==1.9.3.0
Pillow==3.2.0
pyodbc==3.0.10
Whoosh==2.7.4

Solution

  • For the benefit of any future people having this same problem, I found an unconventional solution...

    So I double checked everything according to the haystack documentation and it all looked OK. I found out about a pip package called "django-haystackbrowser" that, once installed correctly, allows you to view your index through the django admin interface.

    For some reason once I had viewed the index in the admin interface (and confirmed everything was already there as it should be) and then restarted the server using

    python manage.py runserver
    

    I finally started getting search results back!

    No idea what was causing the problem, and certainly no idea how just viewing the index using that package fixed it, but it now seems to be returning results as it should!