3

I am a new bee. I read the whole django haystack tutorial, I am trying to make the search operation faster and looking the ways to optimize. I am using whoosh with haystack. SearchQuerySet().all (search engine is whoosh) operation is taking lot of time to load results. My SearchIndex class is

class NoteIndex(indexes.SearchIndex, indexes.Indexable):
      text = indexes.CharField(document=True, use_template=True) 
      product_name = indexes.CharField(model_attr='product_name')
      product_name_ar = indexes.CharField(model_attr='product_name_ar')
      product_price=indexes.IntegerField(model_attr='product_price')
      product_price_old=indexes.IntegerField(model_attr='product_price_old')
      product_price_percentage=indexes.IntegerField(model_attr='percentage')
      product_price_amount_difference=indexes.IntegerField(model_attr='amount_difference')
      product_vendor_url=indexes.CharField(model_attr='product_vendor_url')
      product_image=indexes.CharField(model_attr='product_image')
      #foreign key references begin here
      product_vendor_name=indexes.CharField(model_attr='product_vendor__vendor_name', null=True)
      product_vendor_alias=indexes.CharField(model_attr='product_vendor__vendor_alias', null=True)
      product_vendor_logo=indexes.CharField(model_attr='product_vendor__vendor_logo', null=True)
      product_vendor_odeliver=indexes.CharField(model_attr='product_vendor__vendor_odeliver', null=True)
      product_vendor_website=indexes.CharField(model_attr='product_vendor__vendor_website', null=True)
      content_auto=indexes.EdgeNgramField(model_attr='product_name')



    def get_model(self): 
        return ProductDeals

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

the data template for the text field id

    {{ object.product_name }}
    {{ object.product_name_ar }}

i.e. only product_name and product_name_ar are going to be used for search operation. My question is regarding other fields, some of the fields(product_price, product_price_old, product_price_percentage, etc) are used to filter the results and other fields are used only to display information to the user. I have added the foreign key fields in the index to avoid hitting the database to make search faster. Accoriding the django haystack documentation by default all the Index fields are Indexed=True(the field is indexed) and Stored=True(field will be stored). I am assuming that my search operation is slow because of indexing and storing these many fields. In this context my questions are the following(which i could not understand from the documentation)

  1. if this is my index class, what is the optimum way to set fields to make search faster.
  2. does making Indexed=False for other fields makes any difference in speeding up the process(since these fields will be searched for to index)

my question is similar to the one asked here, but the answer was not helpful for my case, and I cannot comment because of insufficient points.

additional code as requested view:

class ProductsSearchView(SearchView):
"""My custom search view."""
#overriding parent properites
#SearchMixin Class properities
'''template_name = 'search/search.html'
load_all = True
form_class = ModelSearchForm
queryset = SearchQuerySet()
context_object_name = None
paginate_by = RESULTS_PER_PAGE
paginate_orphans = 0
paginator_class = Paginator
page_kwarg = 'page'
form_name = 'form'
search_field = 'q'
object_list = None'''
template_name='ksaprice_app/product_search.html'
context_object_name='context_var'
paginate_by=20
paginator_class = Paginator
#instantiating the form in the view
form_class=forms.ProductsSearchForm
# vendor_list=Vendor.objects.all().values_list('vendor_name')
# #to create list of unique vendors
# vendor_list_set = set(vendor_list)
# #converting set to list 
# vendor_list_unique=list(vendor_list_set)
# vendor_list_filtered=[]
vendor_unique_list=[]
sort_list=None
def __init__(self):
    super(ProductsSearchView, self).__init__()
    #extending initi here
    #self.sort_list={'relevance':'relevance','price_low_to_high':'price high to low', 'price_high_to_low':'price high to low', 'discount_high_to_low':'discount high to low', 'discount_low_to_high':'discount low to high'}
    self.sort_list=['relevance','discount % high to low','discount % low to high','discount amount high to low','discount amount low to high','price high to low' ,'price low to high']

def get_queryset(self):
    queryset = super(ProductsSearchView, self).get_queryset()
    #by here the search query is getting executed
    self.vendor_filter=self.request.GET.get('select_vendor', 'all')
    self.search_query=self.request.GET.get('q', "")
    self.sort_by=self.request.GET.get('sort_by', "relevance")
    if self.vendor_filter!='all':
        filtered_queryset=queryset.filter(product_vendor_name=self.vendor_filter)
        #ordering when a particular vendor is selected
        if self.sort_by!='relevance':
            if self.sort_by=="discount % high to low":
                #for descending self.sort_by
                sort_with="-"+"product_price_percentage"
            elif self.sort_by=="discount % low to high":
                #for ascending self.sort_by
                sort_with="product_price_percentage"
            elif self.sort_by=="discount amount high to low":
                #descending
                sort_with="-"+"product_price_amount_difference"
            elif self.sort_by=="discount amount low to high":
                #ascending
                sort_with="product_price_amount_difference"
            elif self.sort_by=="price high to low":
                sort_with="-"+"product_price"
            elif self.sort_by=="price low to high":
                sort_with="product_price"
            elif self.sort_by=="popularity":
                #add logic later
                #sort_with="product_price"
                pass
            ordered_filtered_queryset=filtered_queryset.order_by(sort_with)
            return ordered_filtered_queryset
        return filtered_queryset
    elif self.vendor_filter=='all':
        #ordering when all the vendors are selected i.e. default
        if self.sort_by!='relevance':
            if self.sort_by=="discount % high to low":
                #for descending self.sort_by
                sort_with="-"+"product_price_percentage"
            elif self.sort_by=="discount % low to high":
                #for ascending self.sort_by
                sort_with="product_price_percentage"
            elif self.sort_by=="discount amount high to low":
                #descending
                sort_with="-"+"product_price_amount_difference"
            elif self.sort_by=="discount amount low to high":
                #ascending
                sort_with="product_price_amount_difference"
            elif self.sort_by=="price high to low":
                sort_with="-"+"product_price"
            elif self.sort_by=="price low to high":
                sort_with="product_price"
            elif self.sort_by=="popularity":
                #add logic later
                #sort_with="product_price"
                pass
            ordered_queryset=queryset.order_by(sort_with)
            return ordered_queryset
        elif self.sort_by=='relevance':
            #return query set without order and vendor
            return queryset

template:

  <div class="row">
{# {% for discount in context_var.products %} #}
{% for discount in context_var %}
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            <!--<img src="{{static_url}}images/vendor/{{ discount.product_vendor__vendor_logo }}" class="img-responsive" alt="Image">-->
            <img src="{% static "images/vendor_top/" %}{{ discount.product_vendor_logo }}" class="img-responsive" alt="Image">
            <img src="{% static "images/products/" %}{{ discount.product_vendor_alias }}/full/{{ discount.product_image }}" class="img-responsive" alt="Image">
        </div>
    </div>
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            {{ discount.product_name }}
        </div>
    </div>

    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="row">
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
            <h5>{{ discount.product_price }}</h5>
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
            <strike>
            <h5>{{ discount.product_price_old }}</h5>
            </strike>
            </div>
        </div>

        </div>
        </div>
                <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="row">
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
            <h5>{{ discount.product_vendor_odeliver }}</h5>
            </div>
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
            <h5>{{ discount.product_price_percentage }}</h5>
            <!--<h5>{{ discount.product_price_amount_difference }}</h5>-->

            </div>
        </div>

        </div>
        </div>
        </div>




    <!-- if last column in row -->
    {% if forloop.counter|divisibleby:"4" and not forloop.last %}
    </div><div class="row">
Community
  • 1
  • 1
Javed
  • 5,904
  • 4
  • 46
  • 71
  • When you say its slow, how much its slow? How many records you have indexed? and show how you are querying the results in view and rendering in template? – Aamir Rind Dec 10 '15 at 13:04
  • @AamirAdnan added the code of template and view.. – Javed Dec 10 '15 at 13:38

0 Answers0