diff --git a/peachjam/models/core_document_model.py b/peachjam/models/core_document_model.py index a6c2c56c8..77530aefe 100644 --- a/peachjam/models/core_document_model.py +++ b/peachjam/models/core_document_model.py @@ -679,6 +679,11 @@ def get_cited_work_frbr_uris(self): return work_frbr_uris + def search_penalty(self): + """Optionally provide a penalty for this document in search results. This cannot be zero or None.""" + # provide a very small number instead of zero + return 0.0000001 + def file_location(instance, filename): if not instance.document.pk: diff --git a/peachjam/models/generic_document.py b/peachjam/models/generic_document.py index a597eaf83..9f24a235b 100644 --- a/peachjam/models/generic_document.py +++ b/peachjam/models/generic_document.py @@ -86,6 +86,13 @@ class Meta(CoreDocument.Meta): def __str__(self): return self.title + def search_penalty(self): + # non-principal (ie. amendment) works get a slight search penalty so that principal works + # tend to appear above them in search results + if self.metadata_json and self.metadata_json.get("principal", None) is False: + return 10.0 + return super().search_penalty() + def apply_labels(self): # label to indicate that this legislation is repealed label, _ = Label.objects.get_or_create( diff --git a/peachjam_search/documents.py b/peachjam_search/documents.py index 15b0036e5..d3ab97fd4 100644 --- a/peachjam_search/documents.py +++ b/peachjam_search/documents.py @@ -92,6 +92,9 @@ class SearchableDocument(Document): nature_pt = fields.KeywordField() ranking = RankField(attr="work.ranking") + # a negative boost to search results; this must be a positive number, but is treated as a penalty + # it is applied linearly, simply reducing the score by this amount + penalty = RankField(attr="search_penalty", positive_score_impact=False) pages = fields.NestedField( properties={ diff --git a/peachjam_search/views.py b/peachjam_search/views.py index cddc3de56..b131ed085 100644 --- a/peachjam_search/views.py +++ b/peachjam_search/views.py @@ -62,6 +62,10 @@ def construct_search(self, request, view, search_backend): class RankFeatureBackend(BaseSearchQueryBackend): @classmethod def construct_search(cls, request, view, search_backend): + # apply penalty as a linear change to the score + # DISABLED until the penalty field is populated + # queries = [Q("rank_feature", field="penalty", boost=1.0, linear={})] + queries = [] if pj_settings().pagerank_boost_value: rank = Q( @@ -69,8 +73,9 @@ def construct_search(cls, request, view, search_backend): field="ranking", boost=pj_settings().pagerank_boost_value, ) - return [rank] - return [] + queries.append(rank) + + return queries class NestedPageQueryBackend(BaseSearchQueryBackend):