我有两个模型 Item
和 Owner
:
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
)
# ...
我在项目名称和描述字段中进行全文搜索(基于 Django 文档)。 PostgreSQL 版本为 10。
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
、name
字段,如果 is_featured
是 真
。
在执行此搜索之前,我有 Owner
实例模型。
最佳答案
您可以在 search_vector
中添加来自类 Owner
的字段 name
,可能具有不同的 weight
和相同的 config
(这只是一个假设,因为您没有指定 Owner 模型定义或数据)。
使用 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')
关于python - 使用两个模型进行全文搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55351016/