django - 选择字段上的 Django SearchVector
问题描述
如果我有一个简单的 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
)
如何SearchVector
在 postgres 中使用以允许在标题和类别字段上进行搜索?例如,“Some Book Digital Art”将查询标题和类别字段。
问题是在数据库级别,选择字段存储为整数,而不是文本。
在创建搜索向量时,有没有办法可以将整数映射到相应的文本值?
解决方案
我能想到的第一个解决方案是使用条件表达式将类别文本添加到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)
此查询的结果将类似于:
<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)
推荐阅读
- android - 向 AOSP 中的框架/支持添加新的支持库
- python - 如何在按钮按下时更新屏幕?
- python - NameError:未定义名称“classroom_list”
- angular - 如何用玩笑模拟组件中使用的“嵌套”角度服务
- html - 仅使用 CSS(无 JS)将相对定位的 div 内的元素与溢出自动重叠
- node.js - 是否可以在 RTMP 协议中为每个数据包插入额外的数据?
- python - 在线程中更改 QObject 样式表时出错
- arduino - 检测先按下哪个按钮?
- compare - 如何比较 Mathematica 中缺失元素的两个解析方程
- linux - shell 脚本没有错误地执行