Exemple #1
0
 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"))
Exemple #2
0
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
        },
    )
Exemple #3
0
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
Exemple #5
0
    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)
Exemple #6
0
    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))
Exemple #8
0
    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