Continuamos a internacionalizar a pesquisa de endereços usando Sphinx ou Manticore. Agora Metaphone

Esta é uma continuação da publicação “ Internacionalização da Pesquisa de Endereços de Cidades. Implementando o Soundex em russo no Sphinx Search ”, no qual discuti como implementar o suporte para os algoritmos fonéticos Soundex no Sphinx Search, para texto escrito em cirílico. O suporte Soundex já está disponível para texto em latim. É o mesmo com Metphone, para o alfabeto latino, mas não para o alfabeto cirílico, mas vamos tentar corrigir esse fato irritante com a ajuda de transliteração, expressões regulares e um arquivo.





Esta é uma continuação direta, na qual iremos analisar como implementar a Metaphone original, Russian Metaphone (no sentido de que a transliteração não é necessária), Caverphone, e não seremos capazes de fazer Double Metaphone.





A implementação é adequada para as plataformas Sphinx Search e Manticore Search.





No final, vamos ver como Metaphone percebe o rakomakophone .





Imagem Docker





Preparou a imagem docker tkachenkoivan / searchfonetic para que você pudesse "sentir" o resultado. Todos os índices desta publicação e da anterior foram adicionados à imagem, mas, atenção, os nomes dos índices da publicação anterior não correspondem ao que está armazenado na imagem. Por quê? Porque um bom pensamento vem depois.





A descrição dos algoritmos, mesmo assim, foi retirada da publicação " algoritmos fonéticos ". Tentarei duplicar o mínimo possível o texto nele escrito.





Metaphone Original

É implementado de forma elementar, as expressões regulares para transliteração são criadas:





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



E ligue o metafone :





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, .





A esperança qsuggest



não se concretizou - não dará pistas. Por quê? Você pode notar que quando você chama keywords



há duas colunas tokenized



e normalized



, qsuggest



dá uma dica sobre a coluna tokenized



e mede a distância de Levenshtein em relação a ela, qsuggest



não importa que lá, em normalized



, a distância seja 1.





Portanto, a observação é engraçada, mas não prática.








All Articles