Skip to content

Commit

Permalink
Merge pull request freelawproject#3455 from freelawproject/3334-fix-e…
Browse files Browse the repository at this point in the history
…lastic-pagination

3334 Fix ES search pagination limit
  • Loading branch information
mlissner authored Dec 11, 2023
2 parents 0ee26db + ae645b7 commit b30749e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 8 deletions.
8 changes: 2 additions & 6 deletions cl/lib/paginators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ class ESPaginator(Paginator):
Paginator for Elasticsearch hits(results).
"""

def __init__(self, *args, **kwargs):
def __init__(self, total_query_results, *args, **kwargs):
super(ESPaginator, self).__init__(*args, **kwargs)
self._count = (
self.object_list.hits.total.value
if hasattr(self.object_list, "hits")
else len(self.object_list)
)
self._count = total_query_results

@cached_property
def count(self):
Expand Down
70 changes: 70 additions & 0 deletions cl/search/tests/tests_es_recap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3201,3 +3201,73 @@ def test_recap_document_indexing_and_tasks_count(self) -> None:
self.assertEqual(r_doc.docket_child["parent"], docket_2.pk)

docket_2.delete()

def test_search_pagination_results_limit(self) -> None:
"""Confirm that the last page in the pagination is properly computed
based on the number of results returned by Elasticsearch.
"""
d_created = []
for i in range(21):
d = DocketFactory(
court=self.court,
)
d_created.append(d)

# Test pagination requests.
search_params = {
"type": SEARCH_TYPES.RECAP,
}

# 100 results, 5 pages.
with mock.patch(
"cl.search.views.build_es_main_query",
side_effect=lambda x, y: (
DocketDocument.search().query("match_all"),
100,
5,
1000,
),
):
r = self.client.get(
reverse("show_results"),
search_params,
)
self.assertIn("100 Results", r.content.decode())
self.assertIn("1 of 5", r.content.decode())

# 101 results, 6 pages.
with mock.patch(
"cl.search.views.build_es_main_query",
side_effect=lambda x, y: (
DocketDocument.search().query("match_all"),
101,
5,
1000,
),
):
r = self.client.get(
reverse("show_results"),
search_params,
)
self.assertIn("101 Results", r.content.decode())
self.assertIn("1 of 6", r.content.decode())

# 20,000 results, 1,000 pages.
with mock.patch(
"cl.search.views.build_es_main_query",
side_effect=lambda x, y: (
DocketDocument.search().query("match_all"),
20_000,
5,
1000,
),
):
r = self.client.get(
reverse("show_results"),
search_params,
)
self.assertIn("20,000 Results", r.content.decode())
self.assertIn("1 of 1,000", r.content.decode())

for d in d_created:
d.delete()
10 changes: 8 additions & 2 deletions cl/search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,11 @@ def do_es_search(
total_child_results,
) = build_es_main_query(search_query, cd)
paged_results, query_time, error = fetch_and_paginate_results(
get_params, s, rows_per_page=rows, cache_key=cache_key
get_params,
s,
total_query_results,
rows_per_page=rows,
cache_key=cache_key,
)
search_form = _clean_form(
get_params,
Expand Down Expand Up @@ -696,13 +700,15 @@ def do_es_search(
def fetch_and_paginate_results(
get_params: QueryDict,
search_query: Search,
total_query_results: int,
rows_per_page: int = settings.SEARCH_PAGE_SIZE,
cache_key: str = None,
) -> tuple[Page | list, int, bool]:
"""Fetch and paginate elasticsearch results.
:param get_params: The user get params.
:param search_query: Elasticsearch DSL Search object
:param total_query_results: The total number of results for the query.
:param rows_per_page: Number of records wanted per page
:param cache_key: The cache key to use.
:return: A three tuple, the paginated results, the ES query time and if
Expand Down Expand Up @@ -730,7 +736,7 @@ def fetch_and_paginate_results(

if error:
return [], query_time, error
paginator = ESPaginator(hits, rows_per_page)
paginator = ESPaginator(total_query_results, hits, rows_per_page)
try:
results = paginator.page(page)
except PageNotAnInteger:
Expand Down

0 comments on commit b30749e

Please sign in to comment.