No więc tak mam tabele detal której dane należy przetworzyć i wyniki zachować w innej tabeli. Tabela detal zawiera pola tytuł i artysta. Są to atrybuty typu VARCHAR. Detal wchodzi w skład listy. Detali w liście może być nawet do 7 000. Pobieram wszystkie detale danej listy (po kluczu obcym). A następnie wykonuje w for przetworzenie kolejnych detali. Przetworzenie polega na porównaniu każdego detalu (pola tabeli tytuł artysa) z tabelą zawierającą bazowe nagrania. Pola tytuł artysta mają być porównywane bez uwzględniania polskich znaków oraz ich wielkości. Pola są porównywane za pomocą metody n-gramów. W tym wypadku jest to trigram. Cały ciąg jest rozbijany na 3-literowe ciągi które trzeba porównać z rekordami w tabeli bazowej nagrań. Zawęziłem pole przeszukiwań do ciągów o zbliżonej długości znaków. Założeniem funkcji jest określenie procentowego podobieństwa detalu do nagrania bazowego. Jeśli przekroczy ono pewny próg nagrnie zostaje to tablicy która następnie jest zwracana z funkcji.
Funkcja usuwająca polskie znaki:
function usuwanie_polskich_znakow($str)
{
$polskie_znaki = array('ą','ć','ę','ł','ń','ó','ś','ź','ż', 'Ą','Ć','Ę','Ł','Ń','Ó','Ś','Ż','Ź',); $znaki = array('a','c','e','l','n','o','s','z','z', 'A','C','E','L','N','O','S','Z','Z');
return $str;
}
Funkcja dzieląca ciąg na trójki
function tworz_trigram($str)
{
for($i=0; $i < ($dlugosc_str-2); $i++)
$t_trigram[$i] = $str[$i].$str[$i+1].$str[$i+2];
return $t_trigram;
}
Funkcja stannowiąca wąskie gardło (część 1):
function trigram_imp($DBLink, $artysta_import, $tytul_import, $baza, $prog)
{
$podobienstwo = 0.00;
$t_trigram_porownywany = array(); $t_trigram_wzor = array(); $znalezione_rekordy = array(); $flag = true;
$artysta_import = usuwanie_polskich_znakow($artysta_import);
$tytul_import = usuwanie_polskich_znakow($tytul_import);
//--------------------------------------------------
$min_z = strlen($tytul_import)-2; if($min_z <=0)$min_z = 1;
$max_z = strlen($tytul_import) + 3;
//--------------------------------------------------
$min_z2 = strlen($artysta_import)-2; if($min_z2 <=0)$min_z2 = 1;
$max_z2 = strlen($artysta_import) + 3;
$select_wzor = "SELECT * FROM baza_trackow WHERE id_track_zmieniony IS NULL
AND char_length(tytul) >=".$min_z." AND char_length(tytul) <= ".$max_z.
" AND char_length(artysta) >=".$min_z2." AND char_length(artysta) <= ".$max_z2;
$t_wynik_zapytania = $DBLink->query($select_wzor);
$ilosc_rekordow_baza = $t_wynik_zapytania->num_rows;
$progi_procentowe = "SELECT wartosc FROM konfiguracje
WHERE ustawienie = 'prog_b' OR ustawienie = 'prog_c' ORDER BY ustawienie ";
$t_progi_procentowe = $DBLink->query($progi_procentowe);
$artysta_import = ' '.$artysta_import.' ';
$tytul_import = ' '.$tytul_import.' ';
$t_trigram_artysta_import = tworz_trigram($artysta_import);
$t_trigram_tytul_import = tworz_trigram($tytul_import);
czesc 2:
// pętla porównująca wyniki z bazy z porówywanym nagraniem na playliscie
for($i=0; $i < $ilosc_rekordow_baza; $i++)
{
$rekord = $t_wynik_zapytania ->fetch_assoc();
$str_wzor_artysta = usuwanie_polskich_znakow($rekord['artysta']);
$str_wzor_tytul = usuwanie_polskich_znakow($rekord['tytul']);
$str_wzor_artysta = ' '.$str_wzor_artysta.' ';
$str_wzor_tytul = ' '.$str_wzor_tytul.' ';
//artysta
$strlen_str_porownywany = strlen($artysta_import); $strlen_str_wzor = strlen($str_wzor_artysta);
// podzial stringu pobranego z bazy na trigramy
$t_trigram_wzor = tworz_trigram($str_wzor_artysta);
$t_trigram_porownywany = $t_trigram_artysta_import;
if($strlen_str_porownywany >= $strlen_str_wzor)
{
$ilosc_kombinacji = count($t_trigram_porownywany); $procent = (1 / $ilosc_kombinacji) * 100;
$ilosc_kombinacji = count($t_trigram_wzor); }
else if($strlen_str_porownywany < $strlen_str_wzor)
{
$ilosc_kombinacji_wzor = count($t_trigram_wzor); $procent = (1 / $ilosc_kombinacji_wzor) * 100;
$ilosc_kombinacji = count($t_trigram_porownywany); }
$podobienstwo = 0;
for($j=0; $j < $ilosc_kombinacji; $j++)
{
if($t_trigram_wzor[$j] == $t_trigram_porownywany[$j]){ $podobienstwo += $procent;}
}
$podobienstwoA = $podobienstwo;
$podobienstwo = 0;
//----------------------------------------------------------------------------------------
//----------------------------------------------- tytul ----------------------------------
czesc 3:
$strlen_str_porownywany = strlen($tytul_import); $strlen_str_wzor = strlen($str_wzor_tytul);
// podzial stringu pobranego z bazy na trigramy
$t_trigram_wzor = tworz_trigram($str_wzor_tytul);
$t_trigram_porownywany = $t_trigram_tytul_import;
if($strlen_str_porownywany >= $strlen_str_wzor)
{
$ilosc_kombinacji = count($t_trigram_porownywany); $procent = (1 / $ilosc_kombinacji) * 100;
$ilosc_kombinacji = count($t_trigram_wzor);
}
else if($strlen_str_porownywany < $strlen_str_wzor)
{
$ilosc_kombinacji_wzor = count($t_trigram_wzor); $procent = (1 / $ilosc_kombinacji_wzor) * 100;
$ilosc_kombinacji = count($t_trigram_porownywany); }
for($j=0; $j < $ilosc_kombinacji; $j++)
{
if($t_trigram_wzor[$j] == $t_trigram_porownywany[$j]){ $podobienstwo += $procent;}
}
$podobienstwoB = $podobienstwo;
$podobienstwo = 0;
// Zwraca rekordy zgrupowane kÄ,Ĺ,trych prÄ,Ĺ,g podobiensta przekroczyl A
// Jesli brak takich nagran to nic nie jest zwracane
$podobienstwo = ($podobienstwoA/2) + ($podobienstwoB/2);
if($podobienstwo >= $prog['prog_b'])
{
$rekord['podobienstwo'] = 'A';
if($flag)$znalezione_rekordy = Array(); $znalezione_rekordy[count($znalezione_rekordy)+1
] = $rekord; $flag = false;
}
else if($podobienstwo < $prog['prog_b'] && $podobienstwo >= $prog['prog_c'] && $flag = true)
{
$rekord['podobienstwo'] = 'B';
$znalezione_rekordy[count($znalezione_rekordy)+1
] = $rekord; }
}
return $znalezione_rekordy;
}