Skip to content

Commit 1eab50a

Browse files
committed
improve SearchSimilarNames
1 parent 54f1f53 commit 1eab50a

File tree

1 file changed

+47
-19
lines changed

1 file changed

+47
-19
lines changed

controllers/controller.go

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,41 +89,69 @@ func GetName(c *gin.Context) {
8989
func SearchSimilarNames(c *gin.Context) {
9090
var names []models.NameType
9191

92-
//TODO :: maybe we need to implement the metaphone search in all variations
93-
9492
//Name to be searched
9593
name := c.Params.ByName("name")
9694
database.Db.Find(&names)
9795

98-
mtf := metaphone.Pack(name)
96+
similarNames, mtf := findSimilarNames(names, name, levenshtein)
97+
98+
//when the similar names result's in less than 5 we search for every similar name of all similar names founded previously
99+
if len(similarNames) < 5 {
100+
for _, n := range similarNames {
101+
similarNames, _ = findSimilarNames(names, n.Name, levenshtein)
102+
}
103+
}
104+
105+
nameV := orderByLevenshtein(similarNames)
106+
107+
c.JSON(200, gin.H{
108+
"Name": strings.ToUpper(name),
109+
"metaphone": mtf,
110+
"nameVariations": nameV,
111+
})
112+
113+
}
114+
115+
//findSimilarNames returns []models.NameVar and if necessary reduces' threshold to a minimum of 0.5
116+
func findSimilarNames(names []models.NameType, name string, threshold float32) ([]models.NameVar, string) {
117+
similarNames, mtf := findNames(names, name, threshold)
118+
119+
//in case of empty return the levenshtein constant is downgraded to the minimum of 0.5
120+
if len(similarNames) == 0 {
121+
similarNames, _ = findNames(names, name, threshold-0.1)
122+
if len(similarNames) == 0 {
123+
similarNames, _ = findNames(names, name, threshold-0.2)
124+
}
125+
if len(similarNames) == 0 {
126+
similarNames, _ = findNames(names, name, threshold-0.3)
127+
}
128+
}
129+
130+
return similarNames, mtf
131+
}
132+
133+
//findNames return []models.NameVar with all similar names and the metaphone code of searched string
134+
func findNames(names []models.NameType, name string, threshold float32) ([]models.NameVar, string) {
99135
var similarNames []models.NameVar
136+
137+
mtf := metaphone.Pack(name)
100138
for _, n := range names {
101139
if metaphone.IsMetaphoneSimilar(mtf, n.Metaphone) {
102-
smlt := metaphone.SimilarityBetweenWords(strings.ToLower(name), strings.ToLower(n.Name))
103-
if smlt >= levenshtein {
104-
similarNames = append(similarNames, models.NameVar{Name: n.Name, Levenshtein: smlt})
140+
similarity := metaphone.SimilarityBetweenWords(strings.ToLower(name), strings.ToLower(n.Name))
141+
if similarity >= threshold {
142+
similarNames = append(similarNames, models.NameVar{Name: n.Name, Levenshtein: similarity})
105143
varWords := strings.Split(n.NameVariations, "|")
106144
for _, vw := range varWords {
107145
if vw != "" {
108-
similarNames = append(similarNames, models.NameVar{Name: vw, Levenshtein: smlt})
146+
similarNames = append(similarNames, models.NameVar{Name: vw, Levenshtein: similarity})
109147
}
110148
}
111149
}
112-
}
113-
}
114150

115-
if len(names) == 0 {
116-
c.JSON(http.StatusNotFound, gin.H{"Not found": "metaphone not found", "metaphone": mtf})
117-
return
151+
}
118152
}
119153

120-
nameV := orderByLevenshtein(similarNames)
121-
122-
c.JSON(200, gin.H{
123-
"Name": strings.ToUpper(name),
124-
"metaphone": mtf,
125-
"nameVariations": nameV,
126-
})
154+
return similarNames, mtf
127155

128156
}
129157

0 commit comments

Comments
 (0)