Réparé la recherche par mots-clés
authorEric Mc Sween <eric.mcsween@gmail.com>
Thu, 4 Nov 2010 18:54:23 +0000 (14:54 -0400)
committerEric Mc Sween <eric.mcsween@gmail.com>
Thu, 4 Nov 2010 18:54:23 +0000 (14:54 -0400)
J'ai aussi essayé d'optimiser les requêtes un peu...

auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/development.py
auf_savoirs_en_partage/savoirs/lib/recherche.py
auf_savoirs_en_partage/savoirs/models.py

index 0194404..75a6f82 100644 (file)
@@ -49,19 +49,24 @@ class ChercheurQuerySet(models.query.QuerySet):
     def search(self, text):
         q = None
         for word in text.split():
+            matching_pays = list(Pays.objects.filter(Q(nom__icontains=word) | Q(region__nom__icontains=word)).values_list('pk', flat=True))
+            matching_etablissements = list(Etablissement.objects.filter(Q(nom__icontains=word) | Q(pays__in=matching_pays)).values_list('pk', flat=True))
+            matching_publications = list(Publication.objects.filter(titre__icontains=word).values_list('pk', flat=True))
+            matching_groupes = list(Groupe.objects.filter(nom__icontains=word).values_list('pk', flat=True))
+            matching_disciplines = list(Discipline.objects.filter(nom__icontains=word).values_list('pk', flat=True))
             part = (Q(personne__nom__icontains=word) |
                     Q(personne__prenom__icontains=word) |
                     Q(theme_recherche__icontains=word) |
+                    Q(etablissement__in=matching_etablissements) |
                     Q(etablissement_autre_nom__icontains=word) |
-                    Q(etablissement__nom__icontains=word) |
-                    Q(etablissement__pays__nom__icontains=word) |
-                    Q(discipline__nom__icontains=word) |
-                    Q(publication1__titre__icontains=word) |
-                    Q(publication2__titre__icontains=word) |
-                    Q(publication3__titre__icontains=word) |
-                    Q(publication4__titre__icontains=word) |
-                    Q(these__titre__icontains=word) |
-                    Q(groupes__nom__icontains=word))
+                    Q(etablissement_autre_pays__in=matching_pays) |
+                    Q(discipline__in=matching_disciplines) |
+                    Q(publication1__in=matching_publications) |
+                    Q(publication2__in=matching_publications) |
+                    Q(publication3__in=matching_publications) |
+                    Q(publication4__in=matching_publications) |
+                    Q(these__in=matching_publications) |
+                    Q(groupes__in=matching_groupes))
             if q is None:
                 q = part
             else:
index 70d35bf..0f28876 100644 (file)
@@ -6,6 +6,6 @@ AUTH_PASSWORD_REQUIRED = False
 
 # Activer la debug toolbar...
 
-# MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
-# INSTALLED_APPS += ('debug_toolbar',)
+MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
+INSTALLED_APPS += ('debug_toolbar',)
 # DEBUG_TOOLBAR_CONFIG = dict(INTERCEPT_REDIRECTS=False)
index c7ef9dc..65804a8 100644 (file)
@@ -170,18 +170,21 @@ def build_search_regexp(query):
         part = re.escape(word.lower())
         # Les expressions régulières ne connaissent pas la version
         # en majuscules des caractères accentués.  :(
-        part = part.replace(u'à', u'[àÀ]')
-        part = part.replace(u'â', u'[âÂ]')
-        part = part.replace(u'é', u'[éÉ]')
-        part = part.replace(u'ê', u'[êÊ]')
-        part = part.replace(u'î', u'[îÎ]')
-        part = part.replace(u'ç', u'[çÇ]')
+        # Attention: re.escape aura ajouté un backslash devant tous les
+        # caractères accentués...
+        part = part.replace(u'\\à', u'[àÀ]')
+        part = part.replace(u'\\â', u'[âÂ]')
+        part = part.replace(u'\\é', u'[éÉ]')
+        part = part.replace(u'\\ê', u'[êÊ]')
+        part = part.replace(u'\\î', u'[îÎ]')
+        part = part.replace(u'\\ô', u'[ôÔ]')
+        part = part.replace(u'\\ç', u'[çÇ]')
 
         # Faire ceci après avoir traité les caractères accentués...
         part = part.replace('a', u'[aàâÀÂ]')
         part = part.replace('e', u'[eéèëêÉÊ]')
         part = part.replace('i', u'[iïîÎ]')
-        part = part.replace('o', u'[oô]')
+        part = part.replace('o', u'[oôÔ]')
         part = part.replace('u', u'[uûüù]')
         part = part.replace('c', u'[cç]')
 
index 31d5732..2ea3256 100644 (file)
@@ -41,7 +41,15 @@ class ActualiteManager(models.Manager):
 class ActualiteQuerySet(models.query.QuerySet):
 
     def search(self, text):
-        return self.filter(Q(titre__icontains=text) | Q(texte__icontains=text))
+        q = None
+        for word in text.split():
+            part = (Q(titre__icontains=word) | Q(texte__icontains=word) |
+                    Q(regions__nom__icontains=word) | Q(disciplines__nom__icontains=word))
+            if q is None:
+                q = part
+            else:
+                q = q & part
+        return self.filter(q).distinct() if q is not None else self
 
 class Actualite(models.Model):
     id = models.AutoField(primary_key=True, db_column='id_actualite')
@@ -81,7 +89,6 @@ class EvenementManager(models.Manager):
 class EvenementQuerySet(models.query.QuerySet):
 
     def search(self, text):
-        qs = self
         q = None
         for word in text.split():
             part = (Q(titre__icontains=word) | 
@@ -91,12 +98,13 @@ class EvenementQuerySet(models.query.QuerySet):
                     Q(type__icontains=word) |
                     Q(lieu__icontains=word) |
                     Q(description__icontains=word) |
-                    Q(contact__icontains=word))
+                    Q(contact__icontains=word) |
+                    Q(regions__nom__icontains=word))
             if q is None:
                 q = part
             else:
                 q = q & part
-        return qs.filter(q) if q is not None else qs
+        return self.filter(q).distinct() if q is not None else self
 
     def search_titre(self, text):
         qs = self
@@ -278,10 +286,11 @@ class RecordQuerySet(models.query.QuerySet):
         # demandés.
         q = None
         for word in words:
+            matching_pays = list(Pays.objects.filter(Q(nom__icontains=word) | Q(region__nom__icontains=word)).values_list('pk', flat=True))
             part = (Q(title__icontains=word) | Q(description__icontains=word) |
                     Q(creator__icontains=word) | Q(contributor__icontains=word) |
                     Q(subject__icontains=word) | Q(disciplines__nom__icontains=word) |
-                    Q(regions__nom__icontains=word) | Q(pays__nom__icontains=word))
+                    Q(regions__nom__icontains=word) | Q(pays__in=matching_pays))
             if q is None:
                 q = part
             else:
@@ -297,7 +306,6 @@ class RecordQuerySet(models.query.QuerySet):
                 select={'score': score_expr},
                 select_params=score_params
             ).order_by('-score')
-
         return qs
 
     def search_auteur(self, text):
@@ -322,11 +330,8 @@ class RecordQuerySet(models.query.QuerySet):
         """Ne garder que les ressources validées et qui sont soit dans aucun
            listset ou au moins dans un listset validé."""
         qs = self.filter(validated=True)
-        qs = qs.extra(where=['''((savoirs_record.id NOT IN (SELECT record_id FROM savoirs_record_listsets)) OR
-                                 ((SELECT MAX(l.validated) FROM savoirs_listset l
-                                   INNER JOIN savoirs_record_listsets rl ON rl.listset_id = l.spec
-                                   WHERE rl.record_id = savoirs_record.id) = TRUE))'''])
-        return qs
+        qs = qs.filter(Q(listsets__isnull=True) | Q(listsets__validated=True))
+        return qs.distinct()
 
 class Record(models.Model):