Merge pull request #793 from gpodder/remove-advertise
[mygpo.git] / mygpo / search / index.py
blob23d344e922244c9a6a4f42b1ae2cc5eb72706a70
1 """ Contains code for searching podcasts
3 Uses django.contrib.postgres.search for searching. See docs at
4 https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/search/
6 """
8 from django.conf import settings
10 from mygpo.podcasts.models import Podcast
12 from django.db.models import F, FloatField, ExpressionWrapper
13 from django.contrib.postgres.search import SearchQuery, SearchRank
14 from django.conf import settings
16 import logging
18 logger = logging.getLogger(__name__)
21 SEARCH_CUTOFF = settings.SEARCH_CUTOFF
24 def search_podcasts(query):
25 """Search for podcasts according to 'query'"""
26 if is_query_too_short(query):
27 logger.debug('Found no podcasts for "{query}". Query is too short', query=query)
28 return Podcast.objects.none()
30 logger.debug('Searching for "{query}" podcasts"', query=query)
32 query = SearchQuery(query)
34 results = (
35 Podcast.objects.annotate(rank=SearchRank(F("search_vector"), query))
36 .annotate(
37 order=ExpressionWrapper(
38 F("rank") * F("subscribers"), output_field=FloatField()
41 .filter(rank__gte=SEARCH_CUTOFF)
42 .order_by("-order")[:100]
43 .prefetch_related("slugs")
46 logger.debug(
47 'Found {count} podcasts for "{query}"', count=len(results), query=query
50 return results
53 def is_query_too_short(query):
54 return len(query.replace(" ", "")) <= settings.QUERY_LENGTH_CUTOFF