diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-29 12:20:49 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-09-29 12:20:49 +0200 |
commit | 9767c4cc9473dbc6eff402874363015fd70689b9 (patch) | |
tree | 4261b80b190a73447ec52edc2b07026fbdbcb11f /chimere | |
parent | 9aaf0bb69c66966644e91f5fc9d2986456654c73 (diff) | |
download | Chimère-9767c4cc9473dbc6eff402874363015fd70689b9.tar.bz2 Chimère-9767c4cc9473dbc6eff402874363015fd70689b9.zip |
Internal searches: fix categories and properties search index (manage many fields)
Diffstat (limited to 'chimere')
-rw-r--r-- | chimere/models.py | 77 | ||||
-rw-r--r-- | chimere/utils.py | 39 |
2 files changed, 88 insertions, 28 deletions
diff --git a/chimere/models.py b/chimere/models.py index 07a2967..0582d34 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -51,9 +51,7 @@ from django.utils.translation import ugettext_lazy as _ from chimere.widgets import HiddenPointChooserWidget, PointField, RouteField, \ SelectMultipleField, TextareaWidget, DatePickerWidget, PolygonField, \ JQueryAutoComplete -from chimere.utils import KMLManager, OSMManager, ShapefileManager, \ - GeoRSSManager, CSVManager, HtmlXsltManager, XMLXsltManager, JsonManager, \ - IcalManager +from chimere import utils class Page(models.Model): @@ -427,15 +425,15 @@ STATUS = (('S', _('Submited')), ('I', _('Imported'))) STATUS_DCT = dict(STATUS) -IMPORTERS = {'KML': KMLManager, - 'OSM': OSMManager, - 'SHP': ShapefileManager, - 'RSS': GeoRSSManager, - 'CSV': CSVManager, - 'JSON': JsonManager, - 'ICAL': IcalManager, - 'XSLT': HtmlXsltManager, - 'XXLT': XMLXsltManager +IMPORTERS = {'KML': utils.KMLManager, + 'OSM': utils.OSMManager, + 'SHP': utils.ShapefileManager, + 'RSS': utils.GeoRSSManager, + 'CSV': utils.CSVManager, + 'JSON': utils.JsonManager, + 'ICAL': utils.IcalManager, + 'XSLT': utils.HtmlXsltManager, + 'XXLT': utils.XMLXsltManager } IMPORTER_CHOICES = (('KML', 'KML'), @@ -543,9 +541,9 @@ OVERLAY_CHOICES = ( class Overlay(models.Model): - ''' + """ Static overlay on the map - ''' + """ name = models.CharField(_("Name"), max_length=150) overlay_type = models.CharField(_("Importer type"), max_length=4, choices=OVERLAY_CHOICES) @@ -785,10 +783,6 @@ class GeographicItem(models.Model): return False @classmethod - def properties(cls): - return [pm for pm in PropertyModel.objects.filter(available=True)] - - @classmethod def all_properties(cls): return [pm for pm in PropertyModel.objects.all()] @@ -870,6 +864,42 @@ class GeographicItem(models.Model): return cls.getGeoJSONs(q) return q + def update_search_vector(self, save=True): + """ + Update the search vector + :param save: True if you want to save the object immediately + :return: self + """ + search_vectors = [] + base_q = self.__class__.objects.filter(pk=self.pk) + for cat in self.categories.values('pk').all(): + q = copy.copy(base_q).filter(categories__pk=cat['pk']) + q = q.annotate( + search=SearchVector( + 'categories__name', + 'categories__keywords', + config=settings.CHIMERE_SEARCH_LANGUAGE + )) + search_vectors.append(q.all()[0].search) + for pm in self.properties.values('pk').all(): + q = copy.copy(base_q).filter(properties__pk=pm['pk']) + q = q.annotate( + search=SearchVector( + 'properties__search_value', + config=settings.CHIMERE_SEARCH_LANGUAGE + )) + search_vectors.append(q.all()[0].search) + q = base_q.annotate( + search=SearchVector( + 'name', 'description', 'keywords', + config=settings.CHIMERE_SEARCH_LANGUAGE + )) + search_vectors.append(q.all()[0].search) + self.search_vector = utils.merge_tsvectors(search_vectors) + if save: + self.save() + return self + def weighted_post_save(sender, **kwargs): if not kwargs['instance']: @@ -1118,16 +1148,7 @@ def geometry_post_save(pre_save_geom_values): if not getattr(instance, '_search_updated', None): instance._search_updated = True - q = instance.__class__.objects.filter(pk=instance.pk) - q = q.annotate( - search=SearchVector( - 'name', 'description', - 'keywords', - 'categories__keywords', - 'properties__search_value', - config=settings.CHIMERE_SEARCH_LANGUAGE - )) - instance.search_vector = q.all()[0].search + instance.update_search_vector(save=False) changed = True if changed: diff --git a/chimere/utils.py b/chimere/utils.py index ffa5789..2ed2fd3 100644 --- a/chimere/utils.py +++ b/chimere/utils.py @@ -1455,3 +1455,42 @@ class IcalManager(ImportManager): if created: new_item += 1 return (new_item, updated_item, msg) + + +def merge_tsvectors(vectors): + """ + Parse tsvector to merge them in one string + :param vectors: list of tsvector string + :return: merged tsvector + """ + result_dict = {} + for vector in vectors: + if not vector: + continue + + current_position = 0 + if result_dict: + for key in result_dict: + max_position = max(result_dict[key]) + if max_position > current_position: + current_position = max_position + + for dct_member in vector.split(" "): + key, positions = dct_member.split(':') + key = key[1:-1] # remove quotes + positions = [int(pos) + current_position + for pos in positions.split(',')] + if key in result_dict: + result_dict[key] += positions + else: + result_dict[key] = positions + + # {'lamelie': [1, 42, 5]} => {'lamelie': "1,42,5"} + result_dict = {k: ",".join([str(val) for val in result_dict[k]]) + for k in result_dict} + # {'lamelie': "1,5", "hagarde": "2", "regarde": "4"} => + # "lamelie':1,5 hagarde:2 regarde:4" + result = " ".join(["{}:{}".format(k, result_dict[k]) for k in result_dict]) + + return result + |