为什么每次从 django-Haystack 的搜索视图调用 index_queryset?
Why is index_queryset called every time from search view in django-Haystack?
我按照 Getting Starting - Django Haystack 的例子,将他们的模型换成我的。
在 search_indexes.py 中,方法 index_queryset 有注释 "Used when the entire index for model is updated." 但是每次我从视图 search/search.html
进行搜索时都会调用它
该方法本身从数据库中获取所有对象并且速度非常慢,所以我认为这不是预期的行为。
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())
我捕获了堆栈跟踪以查看它是从哪里调用的:
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(
注意:我使用的是 django 版本 1.7.10 和 django-haystack 版本 2.4.1
这是预期的行为 - 错误的是文档字符串。函数 index_queryset
基本上 return 是 Haystack 将用来获取搜索结果(以及索引文档)的查询集。
你说:
The method itself gets all the objects from the database and is very slow
其实不是。该方法所做的只是 return 一个查询集。 Querysets are lazy,因此该方法不会访问数据库。只有当某些东西试图访问查询集的结果时,数据库才会受到攻击。
这将在您的搜索已执行并且 Haystack return 得到结果后发生。此时查询集将被进一步过滤为 return 匹配搜索的对象。如果这很慢,则可能表明您的模型结构存在更基本的性能问题。
我按照 Getting Starting - Django Haystack 的例子,将他们的模型换成我的。 在 search_indexes.py 中,方法 index_queryset 有注释 "Used when the entire index for model is updated." 但是每次我从视图 search/search.html
进行搜索时都会调用它该方法本身从数据库中获取所有对象并且速度非常慢,所以我认为这不是预期的行为。
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())
我捕获了堆栈跟踪以查看它是从哪里调用的:
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(
注意:我使用的是 django 版本 1.7.10 和 django-haystack 版本 2.4.1
这是预期的行为 - 错误的是文档字符串。函数 index_queryset
基本上 return 是 Haystack 将用来获取搜索结果(以及索引文档)的查询集。
你说:
The method itself gets all the objects from the database and is very slow
其实不是。该方法所做的只是 return 一个查询集。 Querysets are lazy,因此该方法不会访问数据库。只有当某些东西试图访问查询集的结果时,数据库才会受到攻击。
这将在您的搜索已执行并且 Haystack return 得到结果后发生。此时查询集将被进一步过滤为 return 匹配搜索的对象。如果这很慢,则可能表明您的模型结构存在更基本的性能问题。