@@ -89,41 +89,69 @@ func GetName(c *gin.Context) {
8989func 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