def search_what(self, query): if not query: return self return (self.annotate(rank=search.SearchRank( F("search_vector"), search.SearchQuery(query, config="french_unaccent"), )).filter(search_vector=search.SearchQuery( query, config="french_unaccent")).order_by("-rank"))
def search(request): query = request.GET.get("q") page_number = request.GET.get("page") search_vector = (psql_search.SearchVector("title", weight="A") + psql_search.SearchVector("body", weight="A") + psql_search.SearchVector("summary", weight="B")) search_query = psql_search.SearchQuery(query) posts = (Post.published.annotate( rank=psql_search.SearchRank(search_vector, search_query)).filter( rank__gte=0.3).order_by("-rank")) paginator = Paginator(posts, os.environ.get("SEARCH_RESULTS_PER_PAGE", 6)) try: posts = paginator.page(number=page_number) except PageNotAnInteger: posts = paginator.page(number=1) # first page except EmptyPage: posts = paginator.page(number=paginator.num_pages) # last page return render( request, "portfolio/search.html", { "posts": posts, "active": "home", "query": query }, )
def get_search_results(query: str, user: models.User) -> QuerySet: """Gets search results for the user.. Args: query: The raw text query submitted by the user. user: The user who submitting the query. Returns: A list of entities ranked in order to its match to the query. """ search_vectors: List[search.SearchVector] = [ search.SearchVector('patient_profile__first_name', weight='B'), search.SearchVector('patient_profile__last_name', weight='A') ] combined_search_vector = search_vectors[0] for index, vector in enumerate(search_vectors): if index == 0: continue combined_search_vector += vector search_query: search.SearchQuery = search.SearchQuery(query) users: QuerySet[models.User] = models.User.objects.all() return users.annotate( rank=search.SearchRank(combined_search_vector, search_query)).filter( rank__gte=MATCHING_THRESHOLD).order_by('-rank')
def packages_search_filter(query, queryset, word_rule='&', quantity=10): # Split the query into whitespace-separated subqueries, each of which will # either be queried together or separately, depending on the options. nice_query = split(r'\s', query.strip()) models = queryset if not models: models = Package.objects.all() vector = search.SearchVector('name', weight='A') vector += search.SearchVector(Func(F('keywords'), Value(' '), function='array_to_string'), weight='B') vector += search.SearchVector('description', weight='B') search_query = search.SearchQuery(nice_query[0]) for ii in range(1, len(nice_query)): if word_rule == '&': search_query &= search.SearchQuery(nice_query[ii]) else: search_query |= search.SearchQuery(nice_query[ii]) rank = search.SearchRank(vector, search_query) annotated = models.annotate(rank=rank).order_by('-rank') # Grab any exact (case-insensitive) name match to the query. This is # necessary for very short package names. name_pass = annotated.filter(name__iexact=query) # Filter out all rank 0 results. rank_high_pass = annotated.filter(rank__gt=0) # Add the exact match at the front, if it exists. results = name_pass.union(rank_high_pass) # Restrict the number of results to the quantity argument. if quantity != -1: results = results[0:quantity] return results
def _add_keyword_relevance(self, qs): """Annotates query with search rank value. Search rank is calculated as result of `ts_rank` PostgreSQL function, which ranks vectors based on the frequency of their matching lexemes. Search rank is normalized by dividing it by itself + 1: """ ts_rank_fn = Func(F('search_vector'), psql_search.SearchQuery(self.filters['keywords']), RANK_NORMALIZATION, function=RANK_FUNCTION, output_field=db_fields.FloatField()) return qs.annotate(relevance=ts_rank_fn)
def _base_queryset(self): """Returns generic queryset used both for count and search.""" qs = models.Content.objects.order_by().filter( repository__provider_namespace__namespace__isnull=False, repository__provider_namespace__namespace__active=True) keywords = self.filters.get('keywords') if keywords: qs = qs.filter(search_vector=psql_search.SearchQuery(keywords)) ns_type = self.filters.get('contributor_type') if ns_type: qs = qs.filter( namespace__is_vendor=(ns_type == constants.NS_TYPE_PARTNER)) namespaces = self.filters.get('namespaces') if namespaces: filters = [ Q(namespace__name__icontains=name) for name in self.filters['namespaces'] ] qs = qs.filter(functools.reduce(operator.or_, filters)) names = self.filters.get('names') if names: filters = [Q(name__icontains=name) for name in names] qs = qs.filter(functools.reduce(operator.or_, filters)) tags = self.filters.get('tags') if tags: tags_qs = models.Content.objects.only('pk').filter( tags__name__in=tags) qs = qs.filter(pk__in=tags_qs) deprecated = self.filters.get('deprecated') if deprecated is not None: qs = qs.filter(repository__deprecated=deprecated) platforms = self.filters.get('platforms') if platforms: platforms_qs = models.Content.objects.only('pk').filter( platforms__name__in=platforms) qs = qs.filter(pk__in=platforms_qs) clouds = self.filters.get('cloud_platforms') if clouds: cloud_qs = models.Content.objects.only('pk').filter( cloud_platforms__name__in=clouds) qs = qs.filter(pk__in=cloud_qs) return qs
def add_keywords_filter(queryset, keywords): if not keywords: return queryset.annotate( search_rank=Value(0.0, output_field=db_fields.FloatField())) tsquery = six.moves.reduce( operator.and_, (psql_search.SearchQuery(kw) for kw in keywords)) search_rank_fn = Func( F('search_vector'), tsquery, RANK_NORMALIZATION, function=RANK_FUNCTION, output_field=db_fields.FloatField()) return (queryset.annotate(search_rank=search_rank_fn) .filter(search_vector=tsquery))
def _base_queryset(self): """Returns generic queryset used both for count and search.""" qs = models.Collection.objects.order_by() keywords = self.filters.get('keywords') if keywords: qs = qs.filter(search_vector=psql_search.SearchQuery(keywords)) ns_type = self.filters.get('contributor_type') if ns_type: qs = qs.filter( namespace__is_vendor=(ns_type == constants.NS_TYPE_PARTNER)) namespaces = self.filters.get('namespaces') if namespaces: filters = [ Q(namespace__name__icontains=name) for name in self.filters['namespaces'] ] qs = qs.filter(functools.reduce(operator.or_, filters)) names = self.filters.get('names') if names: filters = [Q(name__icontains=name) for name in names] qs = qs.filter(functools.reduce(operator.or_, filters)) tags = self.filters.get('tags') if tags: tags_qs = models.Collection.objects.only('pk').filter( tags__name__in=tags) qs = qs.filter(pk__in=tags_qs) deprecated = self.filters.get('deprecated') if deprecated is not None: qs = qs.filter(deprecated=deprecated) return qs