【发布时间】:2022-01-20 22:14:07
【问题描述】:
我正在尝试构建一个基于 fuzzystrmatch postgres 扩展的 Func 类工具包。
例如,我有这个包装器,它接受一个表达式和一个搜索词并返回 levenshtein 距离:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression,
search_term=search_term,
**extras
)
这样调用,使用F Expression:
Author.objects.annotate(lev_dist=Levenshtein(F('name'),'JRR Tolkien').filter(lev_dist__lte=2)
但是,如果这里的 'name' 字段大于 255,则会引发错误:
源和目标都可以是任何非空字符串,最多 255 个字符。
当我使用 Substr 进行注释时,我可以截断名称:
Author.objects.annotate(clipped_name=Substr(F('name'),1,250))
但我似乎无法弄清楚如何将该逻辑放入 func 中,我将其放入 ExpressionWrapper 并按照 the docs 设置 output_field:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression=ExpressionWrapper(Substr(expression, 1, 250), output_field=TextField()),
search_term=search_term,
**extras
)
【问题讨论】:
标签: python sql django postgresql fuzzy-search