V
V
vikholodov2018-01-30 23:36:25
Django
vikholodov, 2018-01-30 23:36:25

How to speed up Sphinx search on Django?

The problem is searching for 3 or more words, if 1-2 words, then everything works instantly, if you enter more than 3, then postgresql starts working and eats 100% of the processor
. I use this package https://github.com/jorgecarleitao/django- sphinxql
Made indexes.py according to the instructions:

from sphinxql import indexes, fields
from core import models

class ProductIndex(indexes.Index):
    name_rus = fields.Text(model_attr='name_rus')
    name_poland = fields.Text(model_attr='name_poland')
    category_id = fields.Text(model_attr='category_id')

    class Meta:
        model = models.Product

Here is the search code itself, along with typeahead, there are no problems with it, it works quickly, but for the sake of completeness it will not hurt. The search goes through 2 fields, the name of the product in Russian and the name of the product in Polish (the headings are in Polish, but the search is carried out in the usual Latin alphabet from the keyboards of our compatriots). I tried to check for Cyrillic in order to search for only 1 field, it didn’t work ... Also, the search result will be filtered by category, I think you can narrow the search circle to the search process itself and reduce the load, but I can’t figure out how to do this in a compartment with a sphinx
def search(request):
    if request.method == 'GET':
        form = SearchForm(request.GET)
        if form.is_valid():
            name_rus = form.cleaned_data['search']
            try:
                product = Product.objects.get(Q(name_rus=name_rus)|Q(sku=name_rus))
                return redirect('product_item', product.slug)
            except:
                auto = Category.objects.filter(slug='avtotovaryi-0').get_descendants(include_self=False)
                lower = set('абвгдеёжзийклмнопрстуфхцчшщъыьэюя')
                if lower.intersection(name_rus.lower()) != set():
                    products_search = SearchQuerySet(ProductIndex).search('@name_rus '+name_rus)[0:4000]
                else:
                    products_search = SearchQuerySet(ProductIndex).search('@name_poland '+name_rus)[0:4000]    
                
                #products_search = ProductIndex.objects.search_filter(name_rus__icontains=name_rus, category_id__in=auto)[0:3000]
                #products_search = Product.objects.filter(category_id__in=auto, name_rus__icontains=name_rus)[0:3000]
                last_question = '?search=%s' % name_rus
                #categories = Category.objects.filter(categories_products__in=products_search).distinct()
                categories = Category.objects.filter(categories_products__in=products_search).distinct()

                paginator = Paginator(products_search, 40) 
                page = request.GET.get('page')
                products = paginator.get_page(page)
                return render(request, 'core/search.html', {'products':products, 'categories':categories, 'page':page, 'last_question':last_question, 'products_search':products_search})

    else: return HttpResponse('Ошибка поиска')

def typeahead(request):
    q = request.GET.get('q', '')
    prodlist = []
    objects = Product.objects.filter(Q(name_rus__icontains=q)|Q(sku=q))[0:10]
    for i in objects:
        new = {'q':i.name_rus}
        prodlist.append(new)

    return HttpResponse(json.dumps(prodlist), content_type="aplication/json")

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Puma Thailand, 2018-01-31
@vikholodov

And what does postgres have to do with it if you have a search through the sphinx, you just need to look at the active requests of all postgres and the sphinx has nothing to do with it

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question