0

I'm working with haystack + Whoosh and DJango to build a basic search engine. What I want to do is that each of my search results will have a "favourites" value (default is 0). And I want to sort these results by this integer with the results with the higher amount of favourites coming first. I've followed the guide on the Haystack tutorial and looked up other answers on the topic but I cannot seem to get it to work.

I have a models.py that looks like this:

class Recipe(models.Model):
primary_url = models.CharField(max_length=500, null=False, blank=False, primary_key=True)
title = models.CharField(max_length=500)

favourite_count = models.IntegerField(null=False, default= 0)

def __unicode__(self):
    return self.title

In my search_indexes.py, I gave the favourites attribute a name like so:

class RecipeIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    favourite_count = indexes.IntegerField(model_attr='favourite_count', stored=True)

    def get_model(self):
        return Recipe

    def index_queryset(self, using=None):
        #Used when entire index for model is updated
        return self.get_model().objects.all()

And finally my urls.py is set up like so:

sqs = SearchQuerySet().order_by('-favourite_count')

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^search/', search_view_factory(view_class=views.mySearchView, template='search/search.html', searchqueryset=sqs, form_class=views.myModelSearchForm))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Despite this, my results are not being sorted correctly. They are still in a random order despite my efforts. I know the urls.py is understanding my declaration for sqs as it throws an error if I mis-spell it:

KeyError: "No field named 'favrite_count'"

EDIT:

Here is views.mySearchView()

class mySearchView(SearchView):

def __call__(self, request):
    """
    Generates the actual response to the search.

    Relies on internal, overridable methods to construct the response.
    """
    self.request = request

    self.form = self.build_form()

    #print(self.get_query())

    querywords = self.get_query().split()

    resultwords = [word for word in querywords if word.lower() not in stopwords]

    result = ' '.join(resultwords)

    #print(result)

    self.query = result
    self.results = self.get_results()

    return self.create_response()

def get_results(self):
    """
    Fetches the results via the form.

    Returns an empty list if there's no query to search with.
    """

    #sortedQuerySet = sorted(self.form.search(), key=token_similarity)

    #return sortedQuerySet
    return self.form.search()

def extra_context(self):

    request = self.get_query()

    if request is not None and not "":
        related_recipes = []


        words = request.split(' ')

        if(len(words) > 1):

            for word in words:
                temp_list = SearchQuerySet().auto_query(word)[:8]
                for obj in temp_list:
                    if str(self.query).lower() not in str(obj.object.title).lower():
                        #print(str(self.query).lower()+" is not in "+ str(obj.object.title).lower())
                        #print('here')
                        if obj.object.primary_image_url != "test_url":
                            related_recipes.append(obj)
                if len(related_recipes) >= 8:
                            break

        #print(related_recipes)

        return {'related': related_recipes}

    else:

        return {}

EDIT 2:

SO taking my results as is, the order they are being sorted in with the line:

sqs = SearchQuerySet().order_by('-favourite_count')

is like this for the first page:

15
251
10
21
0
15
14
0
0
0
5
8
...

while changing it around to sqs = SearchQuerySet().order_by('favourite_count') gives back:

0
0
25
7
0
0
0
0
0
0
2
0
7
0
....

Again, the field in question I am sorting by is an IntegerField. Ordering by simple numbers should not be this difficult unless I am missing something.

GreenGodot
  • 6,030
  • 10
  • 37
  • 66
  • `favrite_count` is it a typo in the question or in the code itself? – AKS Apr 28 '16 at 16:11
  • It is a deliberate typo I made to show that the Application is reading my search index correctly. If I spell it "favourite_count" like it should be spelled, no error is thrown. – GreenGodot Apr 29 '16 at 08:40
  • I see. Could you add the implementation of `views.mySearchView` as well. – AKS Apr 29 '16 at 08:47
  • Added in the code as requested – GreenGodot Apr 29 '16 at 09:22
  • Actually, a thing I noticed. If I change the order_by call from in urls.py from '-favourite_count' to 'favourite_count', without the dash, the order of the results change. So it is being "ordered" but there is no obvious logic to it. I'll add another edit – GreenGodot Apr 29 '16 at 12:43

0 Answers0