Python Django/PostgreSQL全文搜索-在AWS RDS PostgreSQL上使用SearchVector与SearchVectorField时,搜索结果不同
我正在尝试使用DjangoPython Django/PostgreSQL全文搜索-在AWS RDS PostgreSQL上使用SearchVector与SearchVectorField时,搜索结果不同,python,django,python-3.x,postgresql,amazon-web-services,Python,Django,Python 3.x,Postgresql,Amazon Web Services,我正在尝试使用DjangoSearchVectorField来支持全文搜索。然而,当我在模型上使用SearchVectorField与在视图中实例化SearchVector类时,得到的搜索结果不同。该问题与AWS RDS PostgreSQL实例无关。两者在我的笔记本电脑上的表现都是一样的 让我试着用一些代码来解释它: # models.py class Tweet(models.Model): def __str__(self): return self.tweet_
SearchVectorField
来支持全文搜索。然而,当我在模型上使用SearchVectorField
与在视图中实例化SearchVector
类时,得到的搜索结果不同。该问题与AWS RDS PostgreSQL实例无关。两者在我的笔记本电脑上的表现都是一样的
让我试着用一些代码来解释它:
# models.py
class Tweet(models.Model):
def __str__(self):
return self.tweet_id
tweet_id = models.CharField(max_length=25, unique=True)
text = models.CharField(max_length=1000)
text_search_vector = SearchVectorField(null=True, editable=False)
class Meta:
indexes = [GinIndex(fields=['text_search_vector'])]
我用一个搜索向量填充了所有行,并在数据库上建立了一个触发器,以使字段保持最新
# views.py
query = SearchQuery('chance')
vector = SearchVector('text')
on_the_fly = Tweet.objects.annotate(
rank=SearchRank(vector, query)
).filter(
rank__gte=0.001
)
from_field = Tweet.objects.annotate(
rank=SearchRank(F('text_search_vector'), query)
).filter(
rank__gte=0.001
)
# len(on_the_fly) == 32
# len(from_field) == 0
飞行中的查询集使用SearchVector
实例,返回32个结果。使用SearchVectorField
的from_字段
queryset返回0个结果
空结果提示我跳入shell进行调试。下面是我的python manage.py shell
环境中命令行的一些输出:
>>> qs = Tweet.objects.filter(
... tweet_id__in=[949763170863865857, 961432484620787712]
... ).annotate(
... vector=SearchVector('text')
... )
>>>
>>> for tweet in qs:
... print(f'Doc text: {tweet.text}')
... print(f'From db: {tweet.text_search_vector}')
... print(f'From qs: {tweet.vector}\n')
...
Doc text: @Espngreeny Run your 3rd and long play and compete for a chance on third down.
From db: '3rd':4 'chanc':12 'compet':9 'espngreeni':1 'long':6 'play':7 'run':2 'third':14
From qs: '3rd':4 'a':11 'and':5,8 'chance':12 'compete':9 'down':15 'espngreeny':1 'for':10 'long':6 'on':13 'play':7 'run':2 'third':14 'your':3
Doc text: No chance. It was me complaining about Girl Scout cookies. <url-removed-for-stack-overflow>
From db: '/aggcqwddbh':13 'chanc':2 'complain':6 'cooki':10 'girl':8 'scout':9 't.co':12 't.co/aggcqwddbh':11
From qs: '/aggcqwddbh':13 'about':7 'chance':2 'complaining':6 'cookies':10 'girl':8 'it':3 'me':5 'no':1 'scout':9 't.co':12 't.co/aggcqwddbh':11 'was':4
qs=Tweet.objects.filter(
…tweet_id____in=[949763170863865857,961432484620787712]
…)。注释(
…vector=SearchVector('text')
... )
>>>
>>>对于qs中的tweet:
... 打印(f'Doc text:{tweet.text}')
... 打印(f'From db:{tweet.text\u search\u vector}')
... 打印(f'来自qs:{tweet.vector}\n')
...
博士文字:@Espngreeny运行您的第三次和长期发挥,并争取一个机会,第三次下降。
来自db:3rd:4'chanc:12'compet:9'espngreeni:1'long:6'play:7'run:2'third:14
从qs开始:“第三”:4“a”:11“和”:5,8“机会”:12“竞争”:9“失败”:15“绿色”:1“代表”:10“长”:6“开”:13“玩”:7“跑”:2“第三”:14“你的”:3
没有机会。是我在抱怨女童子军饼干。
来自db:'/aggcqwddbh':13'chanc':2'complaint':6'cooki':10'girl':8'scout':9't.co':12't.co/aggcqwddbh':11
来自qs:“/aggcqwddbh”:13“关于”:7“机会”:2“抱怨”:6“饼干”:10“女孩”:8“它”:3“我”:5“不”:1“侦察员”:9“t.co”:12“t.co/aggcqwddbh”:11“是”:4
在比较数据库中的值和通过Django生成的值时,可以看到搜索向量看起来非常不同
有人知道为什么会这样吗?谢谢 将用户提供的术语转换为数据库与搜索向量进行比较的搜索查询对象。默认情况下,用户提供的所有单词都会通过传递,然后它会查找所有结果项的匹配项。
有两个问题需要解决,首先给出词干算法的语言信息
query = SearchQuery('chance' , config="english")
二是更换这条线
rank=SearchRank(F('text_search_vector'), query)
与
关于
text\u search\u vector
中缺少的单词,这是删除称为的常用单词的标准过程,将F('text\u search\u vector')
替换为'text\u search\u vector'
谢谢,您的建议似乎很有帮助。有一个问题我还是搞不清楚。使用SearchQuery('chance',config='english')
动态运行搜索时,我得到0个结果。如果我删除config
参数,我会得到一个更类似于数据库的结果。另一方面查询不带config
的数据库会导致一个空查询集,而包含它会返回逻辑结果。你能解释一下这种区别吗?我记得在设置db触发器时设置了config='english'
,这可能是相关的吗?@Naqib如果用字符串列名替换F对象,例如,如果要用权重对两个SearchVectorFields进行全文搜索,如何在一个SearchQuery中组合两个SearchVectorFields?
rank=SearchRank('text_search_vector', query)