|
|
@@ -226,7 +226,6 @@ class SqlTools
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
public function buildSqlWhereSearch($q='', $search_fields=[], $min_str_length=1, $max_words=10, $all_words_required=false)
|
|
|
{
|
|
|
$db = $this->db;
|
|
|
@@ -300,5 +299,125 @@ class SqlTools
|
|
|
];
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ public function buildSqlWhereSearch_beta($q='', $search_fields=[], $min_str_length=1, $max_words=10, $all_words_required=false)
|
|
|
+ {
|
|
|
+ $db = $this->db;
|
|
|
+
|
|
|
+ $q = str_replace(['.', ',', '-', '_', ';', ':', '(', ')', '[', ']'], ' ', $q);
|
|
|
+ //$q_one = str_replace(' ', '', $q);
|
|
|
+ $q_len = strlen($q);
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ $search_fields = [
|
|
|
+ 'name',
|
|
|
+ ];
|
|
|
+ */
|
|
|
+ $fields_count = count($search_fields);
|
|
|
+
|
|
|
+
|
|
|
+ $words = explode(" ", $q);
|
|
|
+ $words_count = count($words);
|
|
|
+
|
|
|
+
|
|
|
+ if ($all_words_required) {
|
|
|
+ $search_where = "(1";
|
|
|
+ } else {
|
|
|
+ $search_where = "(0";
|
|
|
+ }
|
|
|
+
|
|
|
+ $fields_scores = [];
|
|
|
+
|
|
|
+ // pour chaque champ sql dans lequel on recherche...
|
|
|
+ foreach ($search_fields as $field_idx => $field) {
|
|
|
+ $field_pos = $field_idx + 1;
|
|
|
+
|
|
|
+ // score de position du champ sql parmis tous les champs où on va rechercher
|
|
|
+ $field_idx_score = 1 / $field_pos;
|
|
|
+
|
|
|
+ $words_scores = [];
|
|
|
+
|
|
|
+ // pour chaque mot de l'expression recherchée...
|
|
|
+ foreach ($words as $word_idx => $word) {
|
|
|
+ $word_len = strlen($word);
|
|
|
+ $word_pos = $word_idx + 1;
|
|
|
+
|
|
|
+ $w = $db->escape($word);
|
|
|
+ $w_like = $db->escape("%" . $word . "%");
|
|
|
+ $w_regex = $db->escape('\b' . preg_quote($word) . '\b');
|
|
|
+
|
|
|
+ // score de position parmi les mots de recherche
|
|
|
+ $word_idx_score = $word_pos / $words_count;
|
|
|
+
|
|
|
+ // score de longueur du mot par rapport à la longueur total de l'expression de recherche
|
|
|
+ $word_search_len_score = $word_len / $q_len;
|
|
|
+
|
|
|
+ // score de longueur par rapport a la longueur du champ sql
|
|
|
+ //$word_len = strlen($word);
|
|
|
+ $word_field_len_score = "(least($word_len / length($field), length($field) / $word_len))"; // longueur du mot (de recherche) rapport à la longueur du champ sql
|
|
|
+
|
|
|
+ // score de position de match dans la valeur du champ sql
|
|
|
+ $locate_max = "(greatest(0.1, length($field) - $word_len) )";
|
|
|
+ $word_match_pos_score = "(locate(" . $w . ", $field) / $locate_max)";
|
|
|
+
|
|
|
+ // matching
|
|
|
+ $word_matching_score = "(case when " . $field . " = " . $w . " then 1
|
|
|
+ when " . $field . " regexp " . $w_regex . " then 0.7
|
|
|
+ when " . $field . " like " . $w_like . " then 0.5
|
|
|
+ /*
|
|
|
+ when soundex(" . $field . ") = soundex(" . $w_like . ") then 0.3
|
|
|
+ when (abs(mid(soundex(" . $field . "), 2) - mid(soundex(" . $w_like . "), 2)) <= 5 and left(soundex(" . $field . "),1) = left(soundex(" . $w_like . "),1) ) then 0.1
|
|
|
+ */
|
|
|
+ else 0
|
|
|
+ end )";
|
|
|
+
|
|
|
+
|
|
|
+ $word_score = "($field_idx_score * $word_idx_score * $word_search_len_score * $word_field_len_score * $word_match_pos_score * $word_matching_score)";
|
|
|
+ $words_scores[] = $word_score;
|
|
|
+
|
|
|
+
|
|
|
+ if ($all_words_required) {
|
|
|
+ // TODO
|
|
|
+ $search_where .= " and (" . $word_matching_score . ")";
|
|
|
+
|
|
|
+ } else {
|
|
|
+ $search_where .= " or " . $word_matching_score;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $fields_scores[] = "(" . implode(" + ", $words_scores) . ")";
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ $search_where .= ")";
|
|
|
+ $search_score = "(" . implode(' + ', $fields_scores) . ")";
|
|
|
+
|
|
|
+
|
|
|
+ if (false) {
|
|
|
+ echo "SCORE:" . PHP_EOL;
|
|
|
+ $nb_scores = count($words_scores);
|
|
|
+ print_r($search_score);
|
|
|
+
|
|
|
+ echo PHP_EOL;
|
|
|
+
|
|
|
+ echo "WHERE:" . PHP_EOL;
|
|
|
+ print_r($search_where);
|
|
|
+
|
|
|
+ echo PHP_EOL;
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'select' => $search_score,
|
|
|
+ 'where' => $search_where,
|
|
|
+ ];
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|