mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-29 17:36:49 +01:00
[Postgres search] Orders by ranking in a more reliable way.
PostgreSQL does not guarantee the outer queries having the same ordering as subqueries after joining other tables. For more details see: https://www.postgresql.org/message-id/4CA16EE8.5040406@postnewspapers.com.au
This commit is contained in:
parent
260257d9a5
commit
85bcd5a176
@ -248,13 +248,17 @@ class PostgresSearchQuery(BaseSearchQuery):
|
||||
index_entries = self.get_in_index_queryset(queryset, search_query)
|
||||
if self.order_by_relevance:
|
||||
index_entries = index_entries.rank(search_query)
|
||||
index_sql, index_params = get_sql(index_entries.pks())
|
||||
index_sql, index_params = get_sql(
|
||||
index_entries.annotate_typed_pk()
|
||||
.values('typed_pk', 'rank')
|
||||
)
|
||||
model_sql, model_params = get_sql(queryset)
|
||||
model = queryset.model
|
||||
sql = """
|
||||
SELECT obj.*
|
||||
FROM (%s) AS index_entry
|
||||
INNER JOIN (%s) AS obj ON obj."%s" = index_entry.typed_pk
|
||||
ORDER BY index_entry.rank DESC
|
||||
OFFSET %%s LIMIT %%s;
|
||||
""" % (index_sql, model_sql, get_pk_column(model))
|
||||
limits = (start, None if stop is None else stop - start)
|
||||
|
@ -35,14 +35,16 @@ class IndexQuerySet(QuerySet):
|
||||
def rank(self, search_query):
|
||||
return self.add_rank(search_query).order_by('-rank')
|
||||
|
||||
def pks(self):
|
||||
def annotate_typed_pk(self):
|
||||
cast_field = self.model._meta.pk
|
||||
if isinstance(cast_field, BigAutoField):
|
||||
cast_field = BigIntegerField()
|
||||
elif isinstance(cast_field, AutoField):
|
||||
cast_field = IntegerField()
|
||||
return (self.annotate(typed_pk=Cast('object_id', cast_field))
|
||||
.values_list('typed_pk', flat=True))
|
||||
return self.annotate(typed_pk=Cast('object_id', cast_field))
|
||||
|
||||
def pks(self):
|
||||
return self.annotate_typed_pk().values_list('typed_pk', flat=True)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
|
Loading…
Reference in New Issue
Block a user