鉴于这些模型:
class Listing(models.Model):
features = models.ManyToManyField('Feature', related_name='listing_details')
comments = models.TextField()
class Feature(models.Model):
feature = models.CharField(max_length=100, unique=True)
如何在评论或其中一个相关功能中对包含文本的列表进行全文搜索?
我试过这个:
In[28]: Listing.objects.annotate(search=SearchVector('comments', 'features__feature')).filter(search='something').count()
Out[28]:
1215
所以,我知道并非所有这些记录都包含文字.
但是,在常规非全文查询带有相同数字的意义上,该数字是“正确的”:
In[33]: Listing.objects.filter(Q(comments__icontains='something') | Q(features__feature__icontains='something')).count()
Out[33]:
1215
我可以在注释字段或features__feature中只包含包含文本内容的Listing对象,如下所示:
In[34]: Listing.objects.filter(Q(comments__icontains='something') | Q(features__feature__icontains='something')).distinct().count()
Out[34]:
25
真正的问题归结为我如何通过全文搜索获得相同的25条记录?
最佳答案 我在
SearchVector和
StringAgg中使用了
ManyToManyField以避免奇怪的重复并且具有正确的结果.
在您的示例中,正确的查询应该是:
from django.contrib.postgres.aggregates import StringAgg
from django.contrib.postgres.search import SearchVector
Listing.objects.annotate(
search=SearchVector('comments') + SearchVector(StringAgg('features__feature', delimiter=' '))
).filter(search='something')