Django psql全文搜索未匹配非词干化单词

5
我正在使用Django 1.10.1和Postgres 9.4。我的测试服务器和开发环境中的psql服务器版本为9.4.9,而生产环境是一个9.4.7版本的RDS实例。
看起来我的SearchVectorField没有在生产环境中存储给定的搜索配置,虽然在测试和开发环境中已经存储,并且它似乎要么是版本问题(不太可能,因为版本差异以及它在测试/开发中的9.3版本中也可以工作),要么是因为生产环境是在RDS上而不是本地服务器上。
我正在使用自定义配置进行全文搜索,称为“unaccent”,如下所示:
      Token      |     Dictionaries      
-----------------+-----------------------
 asciihword      | english_stem
 asciiword       | english_stem
 email           | simple
 file            | simple
 float           | simple
 host            | simple
 hword           | unaccent,english_stem
 hword_asciipart | english_stem
 hword_numpart   | simple
 hword_part      | unaccent,english_stem
 int             | simple
 numhword        | simple
 numword         | simple
 sfloat          | simple
 uint            | simple
 url             | simple
 url_path        | simple
 version         | simple
 word            | unaccent,english_stem

Unaccent已在两个环境中安装并均可正常工作。

我将搜索数据存储在Writer模型的django.contrib.postgres.search.SearchVectorField中:

class Writer(models.Model):
    #...
    search = SearchVectorField(blank=True)

该列会根据以下搜索向量进行更新:

writer_search_vector = (SearchVector('first_name', 'last_name', 'display_name',
                                     config='unaccent', weight='A') +
                        SearchVector('raw_search_data', config='unaccent', weight='B'))

通过定期运行以下语句:
Writer.objects.update(search=search_utils.writer_search_vector)

但出于某种原因,配置在我的暂存服务器和开发环境中都可以成功存储,但在生产环境中不能。例如,这段代码在所有环境中都返回相同的结果:

In [3]: Writer.objects.annotate(searchy=SearchVector('last_name')).filter(searchy='kostenberger')
Out[3]: <QuerySet []>
In [4]: Writer.objects.annotate(searchy=SearchVector('last_name', config='unaccent')).filter(searchy='kostenberger')
Out[4]: <QuerySet [<Writer: Andreas J. Köstenberger>, <Writer: Margaret Elizabeth Köstenberger>]>

但在测试阶段,如果我使用存储的向量,则会得到以下正确的结果:

In [5]: Writer.objects.filter(search='kostenberger')
Out[5]: <QuerySet [<Writer: Andreas J. Köstenberger>, <Writer: Margaret Elizabeth Köstenberger>]>

在生产环境中,连接 RDS 实例时,我得到了以下错误的结果:

In [5]: Writer.objects.filter(search='kostenberger')
Out[5]: <QuerySet []>

然而,在生产环境中,去除重音符号(unaccent)的功能可以正常运行,但英语词干提取(english_stem)却不能,它可以匹配文本的词干版本(下面的文本),但无法匹配原始版本(上面的文本):

In [6]: Writer.objects.filter(search='kostenberg')
Out[6]: <QuerySet [<Writer: Margaret Elizabeth Köstenberger>, <Writer: Andreas J. Köstenberger>]>

请注意,此测试中两个环境中“Writer”的数据库表是相同的。
有什么想法,为什么在生产环境中存储的向量与正确配置不起作用,而如果我即时创建向量,则可以工作?
1个回答

3
在RDS Postgres上,您无法更改default_text_search_config参数。因此,您必须在每个查询中配置文本搜索:
from django.contrib.postgres.search import SearchRank, SearchQuery
…
search_query = SearchQuery(value='kostenberger', config='unaccent')
Writer.objects.filter(search=search_query)

1
就是这样了!谢谢,David Eyk!查询没有使用正确的配置设置,而我一直专注于tsvector本身。 - ryanmrubin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接