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 __init__(self, qd): self.category, self.subcategory = parse_cats(qd.get('category', '')) st = qd.get('status', '') if st.isdigit(): self.status = int(st) else: self.status = None self.sort = qd.get('sort', None) self.order = qd.get('order', None) mx = qd.get('max', '') if mx.isdigit(): self.max = int(mx) else: self.max = 20 self.query = qd.get('query', '').lower() self.sv = search.SearchVector('name','description')
def update(self): lines = self.entry.lines.all() text_vector = pg_search.SearchVector(models.Value( strip_tags(self.entry.note), output_field=models.TextField()), weight='C', config='english') for tag in self.entry.tags.all(): text_vector += pg_search.SearchVector(models.Value( tag.name, output_field=models.TextField()), weight='A', config='english') for tag in self.entry.event.tags.all(): text_vector += pg_search.SearchVector(models.Value( tag.name, output_field=models.TextField()), weight='C', config='english') if lines.exists(): speaker_vectors = [] for line in lines: text_vector += pg_search.SearchVector(models.Value( strip_tags(line.text), output_field=models.TextField()), weight='B', config='english') speaker_vectors.append( pg_search.SearchVector(models.Value( strip_tags(line.speaker), output_field=models.TextField()), weight='A', config='english')) text_vector += pg_search.SearchVector(models.Value( strip_tags(line.speaker), output_field=models.TextField()), weight='D', config='english') speaker_vector = speaker_vectors[0] for sv in speaker_vectors[1:]: speaker_vector += sv self.speaker_vector = speaker_vector self.text_vector = text_vector self.save()
def auto_update_search_vector(sender: Any, instance: Any, *args: Any, **kwargs: Any) -> None: """Keep the index up-to-date automatically""" sender.objects.filter(pk=instance.pk).update( search_vector=s.SearchVector("text_feature"))