Skip to content

Commit

Permalink
Merge branch 'main' into block-users
Browse files Browse the repository at this point in the history
  • Loading branch information
mlissner authored Dec 18, 2024
2 parents 4deca86 + 9951ee8 commit 2173232
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 35 deletions.
34 changes: 14 additions & 20 deletions cl/lib/elasticsearch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,13 @@ def build_fulltext_query(
q_should.append(
Q(
"match_phrase",
caseName={"query": query_value, "boost": 2, "slop": 1},
**{
"caseName.exact": {
"query": query_value,
"boost": 2,
"slop": 1,
}
},
)
)

Expand Down Expand Up @@ -481,26 +487,14 @@ def build_text_filter(field: str, value: str) -> List:
if isinstance(value, str):
validate_query_syntax(value, QueryType.FILTER)

base_query_string = {
"query_string": {
"query": value,
"fields": [field],
"default_operator": "AND",
}
}
if "caseName" in field and '"' not in value:
# Use phrase with slop, and give it a boost to prioritize the
# phrase match to ensure that caseName filtering returns exactly
# this order as the first priority.
# Avoid applying slop to quoted queries, as they expect exact matches.
base_query_string["query_string"].update(
{
"type": "phrase",
"phrase_slop": "1",
"boost": "2", # Boosting the phrase match to ensure it's ranked higher than individual term matches
}
return [
Q(
"query_string",
query=value,
fields=[field],
default_operator="AND",
)
return [Q(base_query_string)]
]
return []


Expand Down
10 changes: 5 additions & 5 deletions cl/opinion_page/templates/opinion.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h3><span>Admin</span></h3>
class="btn btn-primary btn-xs">Cluster</a>
{% endif %}
{% if perms.search.change_opinion %}
{% for sub_opinion in cluster.sub_opinions.all|dictsort:"type" %}
{% for sub_opinion in cluster.sub_opinions.all %}
<a href="{% url 'admin:search_opinion_change' sub_opinion.pk %}"
class="btn btn-primary btn-xs">{{ sub_opinion.get_type_display|cut:"Opinion" }} opinion</a>
{% endfor %}
Expand Down Expand Up @@ -359,7 +359,7 @@ <h3>{{ cluster.docket.court }}</h3>
Download Original <span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for sub_opinion in cluster.sub_opinions.all|dictsort:"type" %}
{% for sub_opinion in cluster.sub_opinions.all %}
{% if sub_opinion.local_path %}
<li>
<a href="{{ sub_opinion.local_path.url }}"
Expand All @@ -370,7 +370,7 @@ <h3>{{ cluster.docket.court }}</h3>
</li>
{% endif %}
{% endfor %}
{% for sub_opinion in cluster.sub_opinions.all|dictsort:"type" %}
{% for sub_opinion in cluster.sub_opinions.all %}
{% if sub_opinion.download_url %}
{% if forloop.counter == 1 %}
<li role="separator" class="divider"></li>
Expand Down Expand Up @@ -408,7 +408,7 @@ <h4>Summary of Opinion</h4>
{# Only display tabs and make panels if more than one sub-opinion. #}
{% if opinion_count > 1 %}
<ul class="nav nav-tabs v-offset-below-1" role="tablist">
{% for sub_opinion in cluster.sub_opinions.all|dictsort:"type" %}
{% for sub_opinion in cluster.sub_opinions.all %}
<li role="presentation" {% if forloop.first %}class="active"{% endif %}>
<a href="#{{ sub_opinion.type }}{{ forloop.counter }}"
aria-controls="{{ sub_opinion.type }}{{ forloop.counter }}"
Expand All @@ -420,7 +420,7 @@ <h4>Summary of Opinion</h4>
{% endif %}

<div class="tab-content">
{% for sub_opinion in cluster.sub_opinions.all|dictsort:"type" %}
{% for sub_opinion in cluster.sub_opinions.all %}
<div {% if opinion_count > 1 %}
role="tabpanel"
class="tab-pane {% if forloop.first %}active{% endif %}"
Expand Down
11 changes: 10 additions & 1 deletion cl/opinion_page/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
Court,
Docket,
DocketEntry,
Opinion,
OpinionCluster,
Parenthetical,
RECAPDocument,
Expand Down Expand Up @@ -796,7 +797,15 @@ async def view_opinion_old(
unbound form.
"""
# Look up the court, cluster, title and note information
cluster: OpinionCluster = await aget_object_or_404(OpinionCluster, pk=pk)
cluster: OpinionCluster = await aget_object_or_404(
OpinionCluster.objects.prefetch_related(
Prefetch(
"sub_opinions",
queryset=Opinion.objects.order_by("ordering_key"),
)
),
pk=pk,
)
title = ", ".join(
[
s
Expand Down
9 changes: 8 additions & 1 deletion cl/search/api_views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from http import HTTPStatus

import waffle
from django.db.models import Prefetch
from rest_framework import pagination, permissions, response, viewsets
from rest_framework.exceptions import NotFound
from rest_framework.pagination import PageNumberPagination
Expand Down Expand Up @@ -220,7 +222,12 @@ class OpinionClusterViewSet(LoggingMixin, viewsets.ModelViewSet):
"date_modified",
]
queryset = OpinionCluster.objects.prefetch_related(
"sub_opinions", "panel", "non_participating_judges", "citations"
Prefetch(
"sub_opinions", queryset=Opinion.objects.order_by("ordering_key")
),
"panel",
"non_participating_judges",
"citations",
).order_by("-id")


Expand Down
7 changes: 4 additions & 3 deletions cl/search/tests/tests_es_opinion.py
Original file line number Diff line number Diff line change
Expand Up @@ -2231,7 +2231,8 @@ def test_uses_exact_version_for_case_name_field(self) -> None:
r = async_to_sync(self._test_article_count)(
search_params, 1, "case_name exact filter"
)
self.assertIn("<mark>Maecenas Howell</mark>", r.content.decode())
self.assertIn("<mark>Maecenas</mark>", r.content.decode())
self.assertIn("<mark>Howell</mark>", r.content.decode())

# case_name filter: Howells
search_params = {
Expand All @@ -2241,7 +2242,8 @@ def test_uses_exact_version_for_case_name_field(self) -> None:
r = async_to_sync(self._test_article_count)(
search_params, 1, "case_name exact filter"
)
self.assertIn("<mark>Maecenas Howells</mark>", r.content.decode())
self.assertIn("<mark>Maecenas</mark>", r.content.decode())
self.assertIn("<mark>Howells</mark>", r.content.decode())

# text query: Howell
search_params = {
Expand Down Expand Up @@ -2272,7 +2274,6 @@ def test_uses_exact_version_for_case_name_field(self) -> None:
class RelatedSearchTest(
ESIndexTestCase, CourtTestCase, PeopleTestCase, SearchTestCase, TestCase
):

@classmethod
def setUpTestData(cls) -> None:
super().setUpTestData()
Expand Down
25 changes: 22 additions & 3 deletions cl/search/tests/tests_es_recap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1795,8 +1795,9 @@ async def test_results_highlights(self) -> None:
"case_name": "SUBPOENAS SERVED ON",
}
r = await self._test_article_count(params, 1, "highlights caseName")
# Count child documents under docket.
self.assertIn("<mark>SUBPOENAS SERVED ON</mark>", r.content.decode())
self.assertIn("<mark>SUBPOENAS</mark>", r.content.decode())
self.assertIn("<mark>SERVED</mark>", r.content.decode())
self.assertIn("<mark>ON</mark>", r.content.decode())

# Highlight filter: description
params = {
Expand Down Expand Up @@ -2806,6 +2807,24 @@ def test_uses_exact_version_for_case_name_field(self) -> None:
r = async_to_sync(self._test_article_count)(cd, 1, "Disable stemming")
self.assertIn("<mark>Howells v. Indiana</mark>", r.content.decode())

# No quoted case_name filter: A match for 'Indiana Howell' is expected,
# as the order is not mandatory
cd = {
"type": SEARCH_TYPES.RECAP,
"case_name": "Indiana Howell",
}
r = async_to_sync(self._test_article_count)(cd, 1, "No phrase search.")
self.assertIn("<mark>Howell</mark>", r.content.decode())
self.assertIn("<mark>Indiana</mark>", r.content.decode())

# Quoted case_name filter: "Indiana v. Howells" match is not expected
# as order is mandatory
cd = {
"type": SEARCH_TYPES.RECAP,
"case_name": '"Indiana v. Howells"',
}
async_to_sync(self._test_article_count)(cd, 0, "Phrase search.")

# text query: Howell
cd = {
"type": SEARCH_TYPES.RECAP,
Expand Down Expand Up @@ -3718,7 +3737,7 @@ async def test_results_api_highlighted_fields(self) -> None:
"result": self.rd_api,
"V4": True,
"assignedTo": "<mark>George</mark> Doe II",
"caseName": "<mark>America vs API</mark> Lorem",
"caseName": "<mark>America</mark> <mark>vs</mark> <mark>API</mark> Lorem",
"cause": "<mark>401</mark> <mark>Civil</mark>",
"court_citation_string": "<mark>Appeals</mark>. CA9.",
"docketNumber": "<mark>1:24-bk-0000</mark>",
Expand Down
4 changes: 2 additions & 2 deletions cl/search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ def show_results(request: HttpRequest) -> HttpResponse:
mutable_GET["filed_before"] = date.today()

# Load the render_dict with good results that can be shown in the
# "Latest Cases" section
# "Latest Opinions" section
mutable_GET.update(
{
"order_by": "dateArgued desc",
"order_by": "dateFiled desc",
"type": SEARCH_TYPES.OPINION,
}
)
Expand Down

0 comments on commit 2173232

Please sign in to comment.