我正在尝试弄清楚如何将TrigramSimilarity
与unaccent
用于多个字段。
到目前为止,我有:
def filter_by_location(self, queryset, location):
log.info('Filtering location: "{location}"'.format(**locals()))
queryset = queryset.filter(
Q(accommodation__district__name__unaccent__trigram_similar=location) |
Q(accommodation__municipality__name__unaccent__trigram_similar=location) |
Q(accommodation__settlement__name__unaccent__trigram_similar=location)
)
但是我在documentation中读到了我可以通过similarity
订购(不确定上面的代码是否自动执行),所以我试着这样做:
queryset = queryset.filter(
Q(accommodation__district__name__unaccent__trigram_similar=location) |
Q(accommodation__municipality__name__unaccent__trigram_similar=location) |
Q(accommodation__settlement__name__unaccent__trigram_similar=location)
).annotate(
similarity=TrigramSimilarity(
'accommodation__district__name', location
) + TrigramSimilarity(
'accommodation__municipality__name', location
) + TrigramSimilarity(
'accommodation__settlement__name', location
),
).filter(similarity__gt=0.3).order_by('-similarity')
我很快意识到+
中的TrigramSimilarity
没有OR
,但我需要对所有这些不同的字段进行全文搜索。
我实现这一目的的正确语法是什么(使用OR
代替和AND
)将查询性能考虑在内?
由于
答案 0 :(得分:2)
我认为下面的代码可能会有所帮助,但我没有运行它:
queryset = queryset.annotate(
similarity = Greatest(
TrigramSimilarity('accommodation__district__name', location),
TrigramSimilarity('accommodation__municipality__name', location),
TrigramSimilarity('accommodation__settlement__name', location))
).filter(
Q(accommodation__district__name__unaccent__trigram_similar=location) |
Q(accommodation__municipality__name__unaccent__trigram_similar=location) |
Q(accommodation__settlement__name__unaccent__trigram_similar=location),
similarity__gt=0.3).order_by('-similarity')
Greatest
可以像下面这样导入:
from django.db.models.functions import Greatest