Nous continuons à internationaliser la recherche d'adresses en utilisant Sphinx ou Manticore. Maintenant Metaphone

Ceci est une continuation de la publication « Internationalisation de la recherche d'adresse de ville. Implémentation du Soundex en langue russe dans Sphinx Search », dans lequel j'ai expliqué comment implémenter le support des algorithmes phonétiques Soundex dans Sphinx Search, pour le texte écrit en cyrillique. Le support Soundex est déjà disponible pour le texte latin. Il en est de même avec Metphone, pour l'alphabet latin, mais pas pour l'alphabet cyrillique, mais nous essaierons de corriger ce fait ennuyeux à l'aide de la translittération, d'expressions régulières et d'un fichier.





Il s'agit d'une suite directe, dans laquelle nous analyserons comment implémenter le Metaphone d'origine, le Metaphone russe (dans le sens où la translittération n'est pas nécessaire), Caverphone, et nous ne pourrons pas faire de Double Metaphone.





L'implémentation convient aux plates-formes Sphinx Search et Manticore Search.





En fin de compte, voyons comment Metaphone perçoit le rakomakophone .





Image Docker





Préparé l'image docker tkachenkoivan / searchfonetic afin que vous puissiez "sentir" le résultat. Tous les index de cette publication et de la précédente ont été ajoutés à l'image, mais, attention, les noms des index de la publication précédente ne correspondent pas à ce qui est stocké dans l'image. Pourquoi? Parce qu'une bonne pensée vient après.





La description des algorithmes, tout de même, est tirée de la publication " Algorithmes phonétiques ". J'essaierai de reproduire le moins possible le texte qui y est écrit.





Métaphone d'origine

Il est implémenté de manière élémentaire, des expressions régulières de translittération sont créées:





	regexp_filter = (|) => a
	regexp_filter = (|) => b
	regexp_filter = (|) => v
      
      



Et allumez le métaphone :





morphology = metaphone
      
      



, Soundex. , , , Soundex , Soundex, – , .





, , , Metaphone + . .





Sphinx blend_chars. , Sphinx , , , , – , , , .., .. , , , , «&». «M&M’s» ? «&»? blend_chars



.





, blend_chars



:





blend_chars = U+0020
      
      



, - “ ”, , , . , , .





mysql> select * from metaphone where match('');
+------+--------------------------------------+-----------+---------------------------+
| id   | aoguid                               | shortname | offname                   |
+------+--------------------------------------+-----------+---------------------------+
| 1130 | e21aec85-0f63-4367-b9bb-1943b2b5a8fb |         |               |
+------+--------------------------------------+-----------+---------------------------+
      
      



, « », call keywords



:





mysql> call keywords (' ', 'metaphone');
+------+---------------+------------+
| qpos | tokenized     | normalized |
+------+---------------+------------+
| 1    | morisa toreza | MRSTRS     |
| 1    | morisa        | MRS        |
| 2    | toreza        | TRS        |
+------+---------------+------------+
      
      



, : «morisa», «toreza» «morisa toreza», Metaphone, «».





Metaphone Sphinx Search. , . , , :





regexp_filter = [ ] => 
      
      



« », , , .





, , , .





Caverphone , .





mysql> call keywords (' ', 'caverphone');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1    | mrsa trza | mrsa trza  |
| 1    | mrsa      | mrsa       |
| 2    | trza      | trza       |
+------+-----------+------------+

mysql> select * from caverphone where match('');
Empty set (0.00 sec)
      
      



Soundex ( ), Sphinx, , , , , «morisa» «toreza» , «morisa toreza» :





mysql> call keywords (' ', 'simple_soundex');
+------+---------------+---------------+
| qpos | tokenized     | normalized    |
+------+---------------+---------------+
| 1    | morisa toreza | morisa toreza |
| 1    | morisa        | m620          |
| 2    | toreza        | t620          |
+------+---------------+---------------+
      
      



blend_chars



– , . metaphone. ( ) – : , .





.





Double Metaphone

Metaphone , , , .





, , Metaphone . , , , , DoubleMetaphone.java. , «C», , .





, , – , , , Sphinx Manticore.





, Metaphone . , . Sphinx . .





, , Java, Commons Codec. – , . , – , .





, , , . – .





, , :





DoubleMetaphone dm = new DoubleMetaphone();
String metaphone1 = dm.doubleMetaphone("Text", false);
String metaphone2 = dm.doubleMetaphone("Text", true);
      
      



metaphone1



metaphone2



.





– .





, Commons Codec. , . Metaphone , , . , : , , .





Sphinx .





Metaphone

.





. , . « », « Metaphone».





, , , .





, , . , « », «», «» , :





mysql> call keywords (' ', 'rus_metaphone');
+------+--------------+--------------+
| qpos | tokenized    | normalized   |
+------+--------------+--------------+
| 1    |        |        |
| 2    |         |         |
+------+--------------+--------------+
      
      



. , , GitHub Gist manticore.conf.





  • :





regexp_filter = (?i)(|||) => 
regexp_filter = (?i)(||) => 
regexp_filter = (?i)(||) => 
regexp_filter = (?i)() => 
      
      



  • , , , , , :





regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
      
      



  • ,





regexp_filter = (?i)\b => 
regexp_filter = (?i)\b => 
regexp_filter = (?i)\b => 
regexp_filter = (?i)\b => 
regexp_filter = (?i)\b => 
regexp_filter = (?i)\b => 
      
      







regexp_filter = (?i)(||) => 
      
      



Caverphone

.





  • , :





regexp_filter = (A|a) => a
regexp_filter = (B|b) => b
      
      



, , , , .





  • e





regexp_filter = e\b =>
      
      



  • , , :





regexp_filter = \b(cough) => cou2f
regexp_filter = \b(rough) => rou2f
      
      







regexp_filter = (cq) => 2q
regexp_filter = (ci) => si
      
      



  • a, — 3





regexp_filter = (?i)\b(a|e|i|o|u|y) => A
regexp_filter = (?i)(a|e|i|o|u|y) => 3
      
      







regexp_filter = (j) => y
regexp_filter = \b(y3) => Y3

      
      



  • 2





regexp_filter = 2 => 
      
      



  • 3, A





regexp_filter = 3\b => A
      
      



  • 3





regexp_filter = 3 =>
      
      



10 .





:





mysql> select * from caverphone where match ('');
+------+--------------------------------------+-----------+------------------+
| id   | aoguid                               | shortname | offname          |
+------+--------------------------------------+-----------+------------------+
|    5 | 01339f2b-6907-4cb8-919b-b71dbed23f06 |         |          |
|  387 | 4b919f60-7f5d-4b9e-99af-a7a02d344767 |         |            |
+------+--------------------------------------+-----------+------------------+
      
      



«» «». , , , Daitch Mokotoff Soundex - «»:





mysql> select * from daitch_mokotoff_soundex where match ('');
+------+--------------------------------------+-----------+--------------+
| id   | aoguid                               | shortname | offname      |
+------+--------------------------------------+-----------+--------------+
|  387 | 4b919f60-7f5d-4b9e-99af-a7a02d344767 |         |        |
|  541 | 69b8220e-a42d-4fec-a346-1df56370c363 |         |        |
+------+--------------------------------------+-----------+--------------+
      
      



:





mysql> call keywords ('  ', 'caverphone');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1    | lnna      | lnna       |
| 2    | lnna      | lnna       |
| 3    | lna       | lna        |
+------+-----------+------------+


mysql> call keywords ('  ', 'daitch_mokotoff_soundex');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1    | 866       | 866        |
| 2    | 8616      | 8616       |
| 3    | 866       | 866        |
+------+-----------+------------+
      
      



, , , - . , .





: .

, , . Just for fun.





, rock the microphone?! , Metaphone . !





-, blend_chars, rock the microphone, :





blend_chars = U+0020
      
      



- metaphone, .





keywords



Sphinx:





mysql> call keywords ('', 'metaphone');
+------+-------------+------------+
| qpos | tokenized   | normalized |
+------+-------------+------------+
| 1    | rakomakofon | RKMKFN     |
+------+-------------+------------+
      
      



rock the microphone:





mysql> call keywords ('rock the microphone', 'metaphone');
+------+---------------------+------------+
| qpos | tokenized           | normalized |
+------+---------------------+------------+
| 1    | rock the microphone | RK0MKRFN   |
| 1    | rock                | RK         |
| 2    | the                 | 0          |
| 3    | microphone          | MKRFN      |
+------+---------------------+------------+
      
      



RK0MKRFN, RKMKFN, 2(!). the , RKMKRFN:





mysql> call keywords ('rock microphone', 'metaphone');
+------+-----------------+------------+
| qpos | tokenized       | normalized |
+------+-----------------+------------+
| 1    | rock microphone | RKMKRFN    |
| 1    | rock            | RK         |
| 2    | microphone      | MKRFN      |
+------+-----------------+------------+
      
      



RKMKRFN RKMKFN, 1! .





«the», stopwords , - blend_chars = U+0020



«the» . , 1, .





L'espoir qsuggest



ne s'est pas réalisé - il ne donnera aucun indice. Pourquoi? Vous pouvez remarquer que lorsque vous appelez, keywords



il y a deux colonnes tokenized



et normalized



, qsuggest



donne un indice sur la colonne tokenized



et mesure la distance de Levenshtein par rapport à elle, qsuggest



peu importe que là, dedans normalized



, la distance soit de 1.





Par conséquent, l'observation est drôle, mais pas pratique.








All Articles