Amélioration des résultats de recherche

Fix #410
This commit is contained in:
Jean-Marie Favreau 2025-04-25 21:35:03 +02:00
parent 355c56243e
commit bff6631754
5 changed files with 49 additions and 24 deletions

View File

@ -5,8 +5,15 @@ import re
import django_filters
from django import forms
from django.contrib.gis.measure import D
from django.contrib.postgres.search import SearchHeadline, SearchQuery
from django.db.models import F, Q
from django.contrib.postgres.search import (
SearchVector,
SearchQuery,
SearchRank,
SearchHeadline,
TrigramSimilarity,
)
from django.db.models import Q, F, Func
from django.db.models.functions import Greatest, Lower
from django.http import QueryDict
from django.utils.translation import gettext_lazy as _
@ -18,6 +25,7 @@ from .models import (
RecurrentImport,
ReferenceLocation,
Tag,
remove_accents,
)
@ -531,18 +539,27 @@ class SimpleSearchEventFilter(django_filters.FilterSet):
return qs
def custom_filter(self, queryset, name, value):
value = remove_accents(value)
search_query = SearchQuery(value, config="french")
qs = queryset.filter(
Q(title__icontains=value)
| Q(category__name__icontains=value)
| Q(tags__icontains=[value])
| Q(exact_location__name__icontains=value)
| Q(description__icontains=value)
)
search_vector = SearchVector(
"title", weight="A", config="french"
) + SearchVector("description", weight="B", config="french")
# Full-text rank
qs = queryset.annotate(
rank=SearchRank(search_vector, search_query),
similarity=Greatest(
TrigramSimilarity(Func(Lower("title"), function="unaccent"), value),
TrigramSimilarity(
Func(Lower("description"), function="unaccent"), value
),
),
relevance=F("rank") + F("similarity"),
).filter(Q(rank__gte=0.5) | Q(similarity__gte=0.3))
for f in [
"title",
"category__name",
"exact_location__name",
"description",
]:
params = {
@ -556,7 +573,7 @@ class SimpleSearchEventFilter(django_filters.FilterSet):
)
}
qs = qs.annotate(**params)
return qs
return qs.order_by("-relevance")
class Meta:
model = Event

View File

@ -1,15 +1,17 @@
{% if paginator_filter.paginator.num_pages != 1 %}
{% if paginator_filter.paginator.num_pages != 1 and paginator_filter|length > 0 %}
<span>
{% if paginator_filter.has_previous %}
<a href="{{ paginator_filter.paginator.url_first_page }}" role="button">« premier</a>
<a href="{{ paginator_filter.url_previous_page }}" role="button">précédent</a>
{% endif %}
<span>Page {{ paginator_filter.number }} sur {{ paginator_filter.paginator.num_pages }}</span>
<span>Page {{ paginator_filter.number }}
{% if not nomax %}sur {{ paginator_filter.paginator.num_pages }}{% endif %}
</span>
{% if paginator_filter.has_next %}
<a href="{{ paginator_filter.url_next_page }}" role="button">suivant</a>
<a href="{{ paginator_filter.paginator.url_last_page }}" role="button">dernier »</a>
{% if paginator_filter.count < 9999999998 %}
<a href="{{ paginator_filter.paginator.url_last_page }}" role="button">dernier »</a>
{% endif %}
{% endif %}
</span>
{% else %}
Page 1 sur 1
{% endif %}

View File

@ -26,7 +26,7 @@
<a href="{% url 'event_search_full' %}">Recherche avancée {% picto_from_name "chevron-right" %}</a>
{% endif %}
</form>
{% if has_results or categories %}
{% if has_results or categories or tags or places or organisations or rimports %}
<div id="results">
{% if categories %}
<div class="message success">
@ -87,16 +87,13 @@
{% endfor %}
</div>
{% endif %}
<p>
{{ paginator_filter.paginator.count }} événement{{ paginator_filter.object_list.count | pluralize }} correspond{{ paginator_filter.object_list.count | pluralize:"ent" }} à la recherche.
</p>
<div>
{% for obj in paginator_filter %}
{% include "agenda_culturel/single-event/event-in-flat-list-inc.html" with event=obj %}
{% endfor %}
</div>
<footer>
{% include "agenda_culturel/paginator_filter.html" %}
{% include "agenda_culturel/paginator_filter.html" with nomax=1 %}
</footer>
</div>
{% endif %}

View File

@ -2,7 +2,6 @@ import emoji
from django.core.paginator import PageNotAnInteger, EmptyPage
from django.shortcuts import render
from . import PaginatorFilter
from ..filters import SearchEventFilter, SimpleSearchEventFilter
from ..models import (
Category,
@ -17,6 +16,8 @@ from django.db.models import Q, F, Func
def event_search(request, full=False):
from .utils import PaginatorFilterCountless
categories = None
tags = None
places = None
@ -79,7 +80,7 @@ def event_search(request, full=False):
name__icontains=request.GET["q"]
)
paginator = PaginatorFilter(filter, 10, request)
paginator = PaginatorFilterCountless(filter, 10, request)
page = request.GET.get("page")
try:

View File

@ -1,5 +1,6 @@
from django.core.paginator import EmptyPage, Paginator
from django.utils.translation import gettext_lazy as _
from django.utils.functional import cached_property
from django.db.models import Aggregate, FloatField
from ..models import Event
@ -75,3 +76,10 @@ class PaginatorFilter(Paginator):
page.url_next_page = self.request.get_full_path()
return page
class PaginatorFilterCountless(PaginatorFilter):
@cached_property
def count(self):
return 9999999999