kopia lustrzana https://github.com/wagtail/wagtail
[Postgres_search] Adds a default ordering when ranking of objects is the same.
rodzic
5278e005a0
commit
894887e7da
|
@ -8,6 +8,8 @@ Changelog
|
|||
* Fix: Using `order_by_relevance=False` when searching with PostgreSQL now works (Mitchel Cabuloy)
|
||||
* Fix: Inline panel first and last sorting arrows correctly hidden in non-default tabs (Matt Westcott)
|
||||
* Fix: `WAGTAILAPI_LIMIT_MAX` now accepts None to disable limiting (jcronyn)
|
||||
* Fix: In PostgreSQL, new default ordering when ranking of objects is the same (Bertrand Bordage)
|
||||
|
||||
|
||||
1.12 LTS (21.08.2017)
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -22,6 +22,7 @@ Bug fixes
|
|||
* Using ``order_by_relevance=False`` when searching with PostgreSQL now works (Mitchel Cabuloy)
|
||||
* Inline panel first and last sorting arrows correctly hidden in non-default tabs (Matt Westcott)
|
||||
* ``WAGTAILAPI_LIMIT_MAX`` now accepts None to disable limiting (jcronyn)
|
||||
* In PostgreSQL, new default ordering when ranking of objects is the same (Bertrand Bordage)
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
|
|
|
@ -246,12 +246,13 @@ class PostgresSearchQuery(BaseSearchQuery):
|
|||
|
||||
def search_in_index(self, queryset, search_query, start, stop):
|
||||
index_entries = self.get_in_index_queryset(queryset, search_query)
|
||||
order_sql = ''
|
||||
values = ['typed_pk']
|
||||
if self.order_by_relevance:
|
||||
index_entries = index_entries.rank(search_query)
|
||||
values.append('rank')
|
||||
order_sql = 'ORDER BY index_entry.rank DESC'
|
||||
order_sql = 'index_entry.rank DESC, id ASC'
|
||||
else:
|
||||
order_sql = 'id ASC'
|
||||
index_sql, index_params = get_sql(
|
||||
index_entries.annotate_typed_pk()
|
||||
.values(*values)
|
||||
|
@ -262,7 +263,7 @@ class PostgresSearchQuery(BaseSearchQuery):
|
|||
SELECT obj.*
|
||||
FROM (%s) AS index_entry
|
||||
INNER JOIN (%s) AS obj ON obj."%s" = index_entry.typed_pk
|
||||
%s
|
||||
ORDER BY %s
|
||||
OFFSET %%s LIMIT %%s;
|
||||
""" % (index_sql, model_sql, get_pk_column(model), order_sql)
|
||||
limits = (start, None if stop is None else stop - start)
|
||||
|
|
|
@ -200,6 +200,30 @@ class BackendTests(WagtailTestUtils):
|
|||
set(unsorted_results),
|
||||
{self.testa, self.testb, self.testc.searchtest_ptr})
|
||||
|
||||
def test_same_rank_pages(self):
|
||||
"""
|
||||
Checks that results with a same ranking cannot be found multiple times
|
||||
across pages (see issue #3729).
|
||||
"""
|
||||
same_rank_objects = set()
|
||||
try:
|
||||
for i in range(10):
|
||||
obj = models.SearchTest.objects.create(title='Rank %s' % i)
|
||||
self.backend.add(obj)
|
||||
same_rank_objects.add(obj)
|
||||
self.refresh_index()
|
||||
|
||||
results = self.backend.search('Rank', models.SearchTest)
|
||||
results_across_pages = set()
|
||||
for i, obj in enumerate(same_rank_objects):
|
||||
results_across_pages.add(results[i:i + 1][0])
|
||||
self.assertSetEqual(results_across_pages, same_rank_objects)
|
||||
finally:
|
||||
for obj in same_rank_objects:
|
||||
self.backend.delete(obj)
|
||||
obj.delete()
|
||||
self.refresh_index()
|
||||
|
||||
def test_delete(self):
|
||||
# Delete one of the objects
|
||||
self.backend.delete(self.testa)
|
||||
|
|
Ładowanie…
Reference in New Issue