Полнотекстовый поиск в Django: как объединить несколько запросов и векторов? - PullRequest
2 голосов
/ 16 октября 2019

У меня есть форма с тремя входными данными: category, location и keywords.

Если все три поля заполнены в форме, соотношение результатов должно быть ADDиначе получит результаты только по location.

Я пытался объединить эти три входа для полнотекстового поиска Django, но он выбирает результаты, соответствующие только location.

Здесьмой код для views.py:

class SearchServices(generic.ListView):
    model = Service
    context_object_name = 'services'
    template_name = 'services/search.html'

    def get_queryset(self):
        qs = Service.objects

        if self.request.GET['location'] != '':
            lat_long = self.request.GET['location'].split(',')
            user_location = Point(float(lat_long[1]), float(lat_long[0]), srid=4326)

        keywords = self.request.GET['keywords']
        category = self.request.GET['category']

        query = SearchQuery(keywords) & SearchQuery(category)
        vector = SearchVector('title', 'description', StringAgg('tag__name', delimiter=' ')) + SearchVector(StringAgg('category__slug', delimiter=' '))
        if self.request.GET['location'] != '':
            qs = qs.filter(location__distance_lte=(user_location, D(km=2)))
        if category != '':
            qs = qs.annotate(search=vector).filter(search=query).distinct()
            qs = qs.annotate(rank=SearchRank(vector, query)).order_by('-rank')
        qs = qs.annotate(distance=Distance('location', user_location)).order_by('distance')

        return qs

Буду весьма признателен за любые указания относительно того, что я здесь делаю неправильно.

1 Ответ

0 голосов
/ 24 октября 2019

Я думаю, что ваша проблема связана с неопределенным user_location в вашей последней строке аннотации. Попробуйте что-то вроде этого:

class SearchServices(generic.ListView):
    model = Service
    context_object_name = 'services'
    template_name = 'services/search.html'

    def get_queryset(self):
        qs = Service.objects.all()

        request_location = self.request.GET.get('location', '')
        request_keywords = self.request.GET.get('keywords', '')
        request_category = self.request.GET.get('category', '')

        query = SearchQuery(request_keywords) & SearchQuery(request_category)

        vector = SearchVector(
            'title',
            'description',
            StringAgg('tag__name', delimiter=' ')
        ) + SearchVector(
            StringAgg('category__slug', delimiter=' ')
        )

        if request_category != '':
            qs = qs.annotate(search=vector).filter(search=query).distinct()
            qs = qs.annotate(rank=SearchRank(vector, query)).order_by('-rank')

        if len(request_location.split(',')) == 2:
            lat_long = request_location.split(',')
            user_location = Point(float(lat_long[1]), float(lat_long[0]), srid=4326)
            qs = qs.filter(location__distance_lte=(user_location, D(km=2)))
            qs = qs.annotate(
                distance=Distance('location', user_location)
            ).order_by('distance')

        return qs
...