summaryrefslogtreecommitdiff
path: root/chimere
diff options
context:
space:
mode:
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
commit9767c4cc9473dbc6eff402874363015fd70689b9 (patch)
tree4261b80b190a73447ec52edc2b07026fbdbcb11f /chimere
parent9aaf0bb69c66966644e91f5fc9d2986456654c73 (diff)
downloadChimè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.py77
-rw-r--r--chimere/utils.py39
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
+