開始点として新しい全文検索をdjango.contrib.postgres
SearchQuery
使用すると、拡張して、最後の単語の一部の検索を処理するバージョンを作成できます。
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
ts_query
構文については、Postgresのドキュメントを参照してください。
次に、次のようなクエリで使用できます。
vector = SearchVector(
'first_name',
'last_name',
'email',
config='simple')
query = PrefixedPhraseQuery(query, config='simple')
queryset = queryset\
.annotate(vector=vector)\
.filter(vector=query)
ルックアップを作成することもできます。startswith
の実装を参照してくださいSearchVectorExact
。
Django3+回答
これは、Djangoの最近のバージョンでははるかに簡単になっています。プレフィックスクエリをリクエストするために使用できるモードが追加されましたSearchQuery
。raw
query = SearchQuery("search & term & prefix:*", search_type="raw")
results = Model.objects\
.filter(_search_vector=query)\
.annotate(
rank=SearchRank(
F("_search_vector"),
query,
cover_density=True,
)
)
.order_by("-rank")
_search_vector
は、、SearchVectorField
またはモデルに注釈を付けることができます。