如何解决带有部分句子匹配更新的 Django 文本搜索到 django3
我正在尝试在 Django postgres 中应用部分搜索,与此处描述的完全相同 django-text-search-with-partial-sentence-match 我发现有一个很好的解决方案
from psycopg2.extensions import adapt
from django.contrib.postgres.search import SearchQuery
class PrefixedPhraseQuery(SearchQuery):
"""
Alter the tsquery executed by SearchQuery
"""
def as_sql(self,compiler,connection):
# Or <-> available in Postgres 9.6
value = adapt('%s:*' % ' & '.join(self.value.split()))
if self.config:
config_sql,config_params = compiler.compile(self.config)
template = 'to_tsquery({}::regconfig,{})'\
.format(config_sql,value)
params = config_params
else:
template = 'to_tsquery({})'\
.format(value)
params = []
if self.invert:
template = '!!({})'.format(template)
return template,params
它适用于 python 3.6,但不适用于 3.9。 不同的是,比 3.6 SearchQuery 继承自 Value:
class SearchQuery(SearchQueryCombinable,Value):
output_field = SearchQueryField()
SEARCH_TYPES = {
'plain': 'plainto_tsquery','phrase': 'phraseto_tsquery','raw': 'to_tsquery',}
def __init__(self,value,output_field=None,*,config=None,invert=False,search_type='plain'):
self.config = config
self.invert = invert
if search_type not in self.SEARCH_TYPES:
raise ValueError("Unknown search_type argument '%s'." % search_type)
self.search_type = search_type
super().__init__(value,output_field=output_field)
在 python 3.9 中 SearchQuery 继承自 Func:
class SearchQuery(SearchQueryCombinable,Func):
output_field = SearchQueryField()
SEARCH_TYPES = {
'plain': 'plainto_tsquery','websearch': 'websearch_to_tsquery',}
def __init__(self,search_type='plain'):
self.function = self.SEARCH_TYPES.get(search_type)
if self.function is None:
raise ValueError("Unknown search_type argument '%s'." % search_type)
if not hasattr(value,'resolve_expression'):
value = Value(value)
expressions = (value,)
self.config = SearchConfig.from_parameter(config)
if self.config is not None:
expressions = (self.config,) + expressions
self.invert = invert
super().__init__(*expressions,output_field=output_field)
与 Value 不同的是,Func 中没有 self.value
class Func(SQLiteNumericMixin,Expression):
"""An SQL function call."""
function = None
template = '%(function)s(%(expressions)s)'
arg_joiner = ','
arity = None # The number of arguments the function accepts.
def __init__(self,*expressions,**extra):
if self.arity is not None and len(expressions) != self.arity:
raise TypeError(
"'%s' takes exactly %s %s (%s given)" % (
self.__class__.__name__,self.arity,"argument" if self.arity == 1 else "arguments",len(expressions),)
)
super().__init__(output_field=output_field)
self.source_expressions = self._parse_expressions(*expressions)
self.extra = extra
值看起来像那样
class Value(Expression):
"""Represent a wrapped value as a node within an expression."""
def __init__(self,output_field=None):
"""
Arguments:
* value: the value this expression represents. The value will be
added into the sql parameter list and properly quoted.
* output_field: an instance of the model field type that this
expression will return,such as IntegerField() or CharField().
"""
super().__init__(output_field=output_field)
self.value = value
有人帮我将代码示例调整为 python 3.9 或推荐任何类似搜索的解决方案吗?
解决方法
所以我们很清楚,您的问题不在于 Python 版本,而在于 Django 版本。
您要查找的应该是 self.source_expressions[0]
。
但是,如果我今天要重写它,我会首先查看 raw
search type (example) 并使用接近运算符 <->
({{3} }).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。