首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >部分关键字搜索和排序

部分关键字搜索和排序
EN

Stack Overflow用户
提问于 2019-04-03 00:16:22
回答 1查看 269关注 0票数 0

使用Django和Postgres,我有一个投资持有模型,如下所示:

代码语言:javascript
复制
class Holding(BaseModel):    
    name = models.CharField(max_length=255, db_index=True)
    symbol = models.CharField(max_length=16, db_index=True)
    fund_codes = ArrayField(models.CharField(max_length=16), blank=True, default=list)
    ...

其中包含大约70,000美元/加拿大股权,共同基金的列表。我想建立一个自动完成搜索功能,优先考虑1) symbolfund_codes的精确匹配排名,然后是2)在symbol上的接近匹配,然后3)持有name的全文搜索。

如果我有一个向symbolfund_codes添加更多权重的搜索向量

代码语言:javascript
复制
from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank
from django.db.models import F, Func, Value

vector = SearchVector('name', weight='D') + \
         SearchVector('symbol', weight='A') + \
         SearchVector(Func(F('fund_codes'), Value(' '), function='array_to_string'), weight='A')

然后,搜索“MA”

代码语言:javascript
复制
Investment.objects \
    .annotate(document=vector, rank=SearchRank(vector, query)) \
    .filter(document__icontains='MA') \
    .order_by('-rank') \
    .values_list('name', 'fund_codes', 'symbol', 'rank',)

没有给出我想要的结果。我需要MA (万事达卡)作为首选列表,然后MAS (Masco公司),等等…然后是在name字段中包含'MA‘的列表。

我还研究了如何通过以下方式覆盖SearchQuery

代码语言:javascript
复制
class MySearchQuery(SearchQuery):
    def as_sql(self, compiler, connection):
        params = [self.value]
        if self.config:
            config_sql, config_params = compiler.compile(self.config)
            template = 'to_tsquery({}::regconfig, %s)'.format(config_sql)
            params = config_params + [self.value]
        else:
            template = 'to_tsquery(%s)'
        if self.invert:
            template = '!!({})'.format(template)
        return template, params

但仍然得不到我想要的结果。对于如何在此用例中实现搜索功能,有什么建议吗?也许可以将精确的搜索查询和全文搜索查询连接起来?

EN

回答 1

Stack Overflow用户

发布于 2019-05-28 02:30:14

你需要做的就是传入规范化参数。这将为精确匹配的名称提供更高的排名。原始查询如下所示:

代码语言:javascript
复制
SELECT id, name, symbol, func_codes, 
ts_rank_cd(to_tsvector(func_codes), to_tsquery('MA'), 2 ) as rank 
FROM Holding
ORDER BY rank DESC
LIMIT 100;

注意,我传入了一个规范化参数https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING

在Django中怎么做?

我相信django还不支持传递规范化。我看到了一个开放的门票,但它是2年前的。也许还没有人在做这件事。

https://code.djangoproject.com/ticket/28194

您现在可以使用原始查询。有关方法,请参阅官方文档:https://docs.djangoproject.com/en/2.2/topics/db/sql/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55479316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档