Somewhat re-thought TrigramSearchManager.

This commit is contained in:
Schuyler Erle 2012-02-28 18:55:35 +05:30
parent b5fabf412c
commit 0cf8fae70b

View File

@ -43,26 +43,32 @@ SCHED = {
} }
class TrigramSearchManager(models.Manager): class TrigramSearchManager(models.Manager):
def __init__(self, trigram_columns, *args, **kwargs):
super(models.Manager, self).__init__(*args, **kwargs)
self.trigram_columns = trigram_columns
def set_threshold(self, threshold): def set_threshold(self, threshold):
"""Set the limit for trigram similarity matching.""" """Set the limit for trigram similarity matching."""
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("""SELECT set_limit(%f)""" % threshold) cursor.execute("""SELECT set_limit(%f)""" % threshold)
def find_approximate(self, match=0.5, **kwargs): def find_approximate(self, text, match=0.5):
self.set_threshold(match) self.set_threshold(match)
assert(len(kwargs) == 1) similarity_measure = "max(%s)" % ",".join(["similarity(%s, %%s)" % col for col in self.trigram_columns])
column, value = kwargs.items()[0] similarity_filter = " OR ".join(["%s %%%% %%s" % col for col in self.trigram_columns])
text_values = [text] * len(self.trigram_columns)
qset = self.get_query_set() qset = self.get_query_set()
# use the pg_trgm index via the % operator # use the pg_trgm index via the % operator
qset = qset.extra(select={"similarity":"similarity(" + column + ", %s)"}, qset = qset.extra(select={"similarity":similarity_measure,
select_params=[value], select_params=text_values,
where=[column + " %% %s"], where=similarity_filter,
params=[value], params=text_values,
order_by=["-similarity"]) order_by=["-similarity"])
return qset return qset
class Area(models.Model): class Area(models.Model):
objects = TrigramSearchManager() # name, name_mr objects = TrigramSearchManager("name", "name_mr", "display_name")
code = models.IntegerField() #primary_key=True) code = models.IntegerField() #primary_key=True)
slug = models.SlugField(null=True) slug = models.SlugField(null=True)
name = models.TextField(blank=True, max_length=255) name = models.TextField(blank=True, max_length=255)
@ -111,9 +117,8 @@ class Fare(models.Model):
def __unicode__(self): def __unicode__(self):
return str(self.slab) return str(self.slab)
class Stop(models.Model): class Stop(models.Model):
objects = TrigramSearchManager() # name, display, name_mr objects = TrigramSearchManager("name", "name_mr", "display_name")
code = models.IntegerField() code = models.IntegerField()
slug = models.SlugField(null=True) slug = models.SlugField(null=True)
name = models.TextField(blank=True, max_length=255) name = models.TextField(blank=True, max_length=255)