Skip to content

Commit

Permalink
show provisions in search results
Browse files Browse the repository at this point in the history
  • Loading branch information
longhotsummer committed Apr 19, 2024
1 parent ece67ef commit 13c7421
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 4 deletions.
22 changes: 21 additions & 1 deletion peachjam/js/components/FindDocuments/SearchResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@
<span v-if="page.highlight['pages.body']" v-html="page.highlight['pages.body'].join(' ... ')" />
</div>
</div>
<div v-if="item.provisions.length">
<SearchResultProvision
v-for="provision in item.provisions"
:key="provision.id"
:item="provision"
:parents="provisionParents(provision)"
:expression-frbr-uri="item.expressionFrbrUri"
/>
</div>
<div v-else class="ms-3">
<span
class="snippet"
Expand All @@ -70,11 +79,13 @@

<script>
import JsonTable from './JsonTable.vue';
import SearchResultProvision from './SearchResultProvision.vue';
export default {
name: 'SearchResult',
components: {
JsonTable
JsonTable,
SearchResultProvision
},
props: {
item: {
Expand Down Expand Up @@ -125,6 +136,15 @@ export default {
return Array.isArray(item.authors) ? ', '.join(item.authors) : item.authors;
}
return '';
},
provisionParents (provision) {
// zip item.parent_titles and item.parent_ids
return provision.parent_titles.map((title, index) => {
return {
title: title,
id: provision.parent_ids[index]
};
});
}
}
};
Expand Down
27 changes: 27 additions & 0 deletions peachjam/js/components/FindDocuments/SearchResultProvision.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<div class="ms-3 mb-2">
<div v-if="parents.length">
<a :href="`${expressionFrbrUri}#${parents[0].id}`">{{ parents[0].title }}</a>
<SearchResultProvision
:item="item"
:parents="parents.slice(1)"
:expression-frbr-uri="expressionFrbrUri"
/>
</div>
<div v-else>
<a :href="`${expressionFrbrUri}#${item.id}`">{{ item.title }}</a>
<div class="ms-3" v-if="item.highlight['provisions.body']" v-html="item.highlight['provisions.body'].join(' ... ')" />
</div>
</div>
</template>

<script>
export default {
name: 'SearchResultProvision',
props: {
item: { type: Object, default: () => {} },
expressionFrbrUri: { type: String, default: '' },
parents: { type: Array, default: () => [] }
}
};
</script>
4 changes: 2 additions & 2 deletions peachjam_search/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class SearchableDocument(Document):
pages = fields.NestedField(
properties={
"page_num": fields.IntegerField(),
"body": fields.TextField(analyzer="standard", fields={"exact": Text()}),
"body": fields.TextField(fields={"exact": Text()}),
}
)

Expand All @@ -115,7 +115,7 @@ class SearchableDocument(Document):
"id": fields.KeywordField(),
"parent_titles": fields.TextField(),
"parent_ids": fields.KeywordField(),
"body": fields.TextField(analyzer="standard", fields={"exact": Text()}),
"body": fields.TextField(fields={"exact": Text()}),
}
)

Expand Down
15 changes: 15 additions & 0 deletions peachjam_search/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class SearchableDocumentSerializer(DocumentSerializer):
id = CharField(source="meta.id")
highlight = SerializerMethodField()
pages = SerializerMethodField()
provisions = SerializerMethodField()
court = SerializerMethodField()
nature = SerializerMethodField()
order_outcome = SerializerMethodField()
Expand Down Expand Up @@ -66,6 +67,20 @@ def get_pages(self, obj):
pages.append(info)
return pages

def get_provisions(self, obj):
"""Serialize nested provision hits and highlights."""
provisions = []
if hasattr(obj.meta, "inner_hits"):
for provision in obj.meta.inner_hits.provisions.hits.hits:
info = provision._source.to_dict()
info["highlight"] = (
provision.highlight.to_dict()
if hasattr(provision, "highlight")
else {}
)
provisions.append(info)
return provisions

def get_court(self, obj):
return obj["court" + self.language_suffix]

Expand Down
48 changes: 47 additions & 1 deletion peachjam_search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def filter_queryset(self, request, queryset, view):
should_queries.extend(self.build_basic_queries(request, view))
should_queries.extend(self.build_content_phrase_queries(request, view))
should_queries.extend(self.build_nested_page_queries(request, view))
should_queries.extend(self.build_nested_provision_queries(request, view))

return queryset.query(
"bool",
Expand Down Expand Up @@ -159,6 +160,51 @@ def build_nested_page_queries(self, request, view):
)
]

def build_nested_provision_queries(self, request, view):
"""Does a nested provision search, and includes highlights."""
search_term = " ".join(self.get_search_query_params(request))
if not search_term:
return []

return [
Q(
"nested",
path="provisions",
query=Q(
"bool",
should=[
MatchPhrase(provisions__body={"query": search_term, "slop": 2}),
SimpleQueryString(
query=search_term,
fields=["provisions.body"],
quote_field_suffix=".exact",
**view.simple_query_string_options,
),
SimpleQueryString(
query=search_term,
fields=["provisions.title^4", "provisions.parent_titles^2"],
**view.simple_query_string_options,
),
],
),
inner_hits={
"_source": [
"provisions.title",
"provisions.id",
"provisions.parent_titles",
"provisions.parent_ids",
],
"highlight": {
"fields": {"provisions.body": {}},
"pre_tags": ["<mark>"],
"post_tags": ["</mark>"],
"fragment_size": 80,
"number_of_fragments": 2,
},
},
)
]


class SearchView(TemplateView):
template_name = "peachjam_search/search.html"
Expand Down Expand Up @@ -304,7 +350,7 @@ class DocumentSearchViewSet(BaseDocumentViewSet):
}

# TODO perhaps better to explicitly include specific fields
source = {"excludes": ["pages", "content", "flynote", "case_summary"]}
source = {"excludes": ["pages", "content", "flynote", "case_summary", "provisions"]}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down

0 comments on commit 13c7421

Please sign in to comment.