简体   繁体   中英

Why is index_queryset called every time from search view in django-Haystack?

I have followed the Getting Starting - Django Haystack example, swapping out their model for mine. In search_indexes.py, the method index_queryset has the comment "Used when the entire index for model is updated." however it is called every time I do a search from the view search/search.html

The method itself gets all the objects from the database and is very slow, so I assume this isn't the intended behavior.

search_indexes.py

import datetime
from haystack import indexes
from article.models import Article


class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    article_id = indexes.IntegerField(model_attr='id')
    title = indexes.CharField(model_attr='title')
    summary = indexes.CharField(model_attr='summary')
    content = indexes.CharField(model_attr='content')
    published_at = indexes.DateTimeField(model_attr='published_at')

def get_model(self):
    return Article

def index_queryset(self, using=None):
    return self.get_model().objects.filter(
        published_at__lte=datetime.datetime.now())

I captured the stack trace to see where it was being called from:

python2.7/site-packages/haystack/views.py(53)__call__()
-> return self.create_response()
python2.7/site-packages/haystack/views.py(133)create_response()
-> (paginator, page) = self.build_page()
python2.7/site-packages/haystack/views.py(110)build_page()
-> self.results[start_offset:start_offset + self.results_per_page]
python2.7/site-packages/haystack/query.py(272)__getitem__()
-> self._fill_cache(start, bound)
python2.7/site-packages/haystack/query.py(191)_fill_cache()
-> to_cache = self.post_process_results(results)
python2.7/site-packages/haystack/query.py(214)post_process_results()
-> objects = index.read_queryset(using=self.query._using)
python2.7/site-packages/haystack/indexes.py(144)read_queryset()
->   return self.index_queryset(using=using)
myApplication/article/search_indexes.py(20)index_queryset()
->   return self.get_model().objects.filter(

Note: I am using django version 1.7.10 and django-haystack version 2.4.1

This is intended behaviour - it is the docstring that is wrong. The function index_queryset basically returns the queryset that Haystack will use to obtain the search results (as well as to index documents).

You say:

The method itself gets all the objects from the database and is very slow

Actually it doesn't. All the method does is return a queryset. Querysets are lazy , so the method doesn't hit the database. The database only gets hit when something tried to access the results of the queryset.

This will happen after your search has been executed and Haystack returns the results. At this point the queryset will be further filtered to return the objects that matched the search. If this is slow then it may indicate a more fundamental performance issue with your model structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM