使用两个模型进行全文搜索

时间:2019-03-26 06:29:21

标签: python django postgresql full-text-search django-queryset

我有两个模型=IF(COUNTIFS(A$1:A1,">="&DATE(YEAR(A2),MONTH(A2)-6,DAY(A2)),C$1:C1,C2,B$1:B1,B2),"Reorder","New Order") Item

Owner

我在“项目名称”和“描述”字段中进行了全文搜索(基于Django文档)。 PostgreSQL版本是10。

class Item(models.Model):
    name = models.CharField(max_length=255)
    owner = models.ForeignKey(
        Owner, related_name='owner_items',
        on_delete=models.CASCADE,
    )
    is_featured = models.BooleanField(
        choices=CHOICES, default=BOOL_NO
    )
    # ...

我还要在方程式中引入search_vectors = ( SearchVector('name', weight='A', config='english') + SearchVector('description', weight='B', config='english') ) terms = [SearchQuery(term) for term in keyword.split()] search_query = functools.reduce(operator.or_, terms) search_rank = SearchRank( search_vectors, search_query, weights=[0.2, 0.4, 0.6, 1] ) qs = Item.objects.all().annotate( rank=search_rank ).filter(rank__gte=0.2).order_by('-rank') Owner字段,如果nameis_featured,也可以提高排名。

在执行此搜索之前,我拥有true实例模型。

1 个答案:

答案 0 :(得分:1)

您可以在name的类Owner中添加字段search_vector,也许使用不同的weight和相同的config (只是一个假设,因为您没有指定所有者模型定义或数据)。

使用is_featured来增强rank的方法可以注释1 (您可以使用其他值)(如果它是True,然后将其添加到SearchRank结果中。

from django.db import models
from django.db.models import Case, Value, When
from django.contrib.postgres.search import (
    SearchQuery, SearchRank, SearchVector,
)

search_vectors = (
    SearchVector('name', weight='A', config='english') +
    SearchVector('description', weight='B', config='english') +
    SearchVector('owner__name', weight='C', config='english')
)
terms = [SearchQuery(term) for term in keyword.split()]
search_query = functools.reduce(operator.or_, terms)
search_rank = SearchRank(
    search_vectors, search_query, weights=[0.2, 0.4, 0.6, 1]
)
qs = Item.objects.all().annotate(
    featured_boost=Case(
        When(is_featured=True, then=Value(1)),
        default=Value(0),
        output_field=models.IntegerField(),
    )
).annotate(
    rank=search_rank + featured_boost
).filter(rank__gte=0.2).order_by('-rank')