Django SearchVector on choices field[英] Django SearchVector on choices field

本文是小编为大家收集整理的关于Django SearchVector on choices field的处理方法,想解了Django SearchVector on choices field的问题怎么解决?Django SearchVector on choices field问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

如果我有一个简单的django模型,例如:

from model_utils import Choices

class Art(models.Model):
    CATEGORIES = Choices(
        (1, 'DIGITAL_ART', 'Digital Art'),
        (2, 'MULTIMEDIA', 'Multimedia'),
    )
    title = models.TextField()
    category = models.PositiveSmallIntegerField(
        db_index=True, choices=CATEGORIES, blank=True, null=True
    )

如何在Postgres中使用SearchVector允许在标题和类别字段上搜索?例如.因此,"某些书籍数字艺术"会在标题和类别字段上查询.

问题在于,在数据库级,选择字段是作为整数存储的,而不是文本.

创建我的搜索矢量时,我可以将整数映射到相应的文本值吗?

推荐答案

我可以认为的第一个解决方案是使用条件表达式将类别文本添加到 searchVector :

from django.db.models import Case, CharField, Value, When
from django.contrib.postgres.search import SearchVector


Art.objects.annotate(
    category_text=Case(
        When(category=1, then=Value('Digital Art')),
        When(category=2, then=Value('Multimedia')),
        default=Value(''),
        output_field=CharField()
    ),
    search=SearchVector('title') + SearchVector('category_text')
).filter(
    search='Some Book Digital Art'
).values_list('title', flat=True)

此查询的resuklt将与:

相似
<QuerySet ['Some Book']>

和为PostgreSQL生成的SQL类似:

SELECT "arts_art"."title"
FROM "arts_art"
WHERE (
  to_tsvector(COALESCE("arts_art"."title", '')) ||
  to_tsvector(COALESCE(
    CASE
      WHEN ("arts_art"."category" = 1) THEN 'Digital Art'
      WHEN ("arts_art"."category" = 2) THEN 'Multimedia'
      ELSE ''
    END, '')
  )
) @@ (plainto_tsquery('Some Book Digital Art')) = TRUE

更新

您可以从选择列表自动构建查询:

from django.db.models import Case, CharField, Value, When
from django.contrib.postgres.search import SearchVector

CATEGORIES = (
    (1, 'Digital Art'),
    (2, 'Multimedia'),
)

Art.objects.annotate(
    category_text=Case(
        *[When(category=c, then=Value(v)) for c, v in CATEGORIES],
        default=Value(''),
        output_field=CharField()
    ),
    search=SearchVector('title') + SearchVector('category_text')
).filter(
    search='Some Book Digital Art'
).values_list('title', flat=True)

本文地址:https://www.itbaoku.cn/post/1764213.html