Browse Source

dev 2020-11

Max F 5 years ago
parent
commit
8c38948a85
3 changed files with 172 additions and 1 deletions
  1. 47 0
      src/App/Middlewares/EventHandler.php
  2. 5 0
      src/Database/Sql/SqlDb.php
  3. 120 1
      src/Database/Sql/SqlTools.php

+ 47 - 0
src/App/Middlewares/EventHandler.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace KarmaFW\App\Middlewares;
+
+use \KarmaFW\App;
+use \KarmaFW\Http\Request;
+use \KarmaFW\Http\Response;
+
+
+class EventHandler
+{    
+
+    public function __construct()
+    {
+
+    }
+
+
+    public function __invoke(Request $request, Response $response, callable $next)
+    {
+    	// TODO
+
+        $response = $next($request, $response);
+
+        return $response;
+    }
+
+}
+
+
+/*
+
+
+
+$dispatcher->addListener(
+    Event\ApplicationEvent::BEFORE_CALL_CONTROLLER,
+    [new ApplicationHandler(), 'tracking']
+);
+
+
+self::$eventDispatcher->dispatch(
+    ApplicationEvent::BEFORE_CALL_CONTROLLER,
+    new ApplicationEvent($request, new Response())
+);
+
+
+*/

+ 5 - 0
src/Database/Sql/SqlDb.php

@@ -286,6 +286,11 @@ class SqlDb
 		return $this->tools->buildSqlWhereSearch($q, $search_fields, $min_str_length, $max_words, $all_words_required);
 	}
 
+	public function buildSqlWhereSearch_beta($q='', $search_fields=[], $min_str_length=1, $max_words=10, $all_words_required=false)
+	{
+		return $this->tools->buildSqlWhereSearch_beta($q, $search_fields, $min_str_length, $max_words, $all_words_required);
+	}
+
 
 	public function parseDSN($var)
 	{

+ 120 - 1
src/Database/Sql/SqlTools.php

@@ -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,
+        ];
+
+    }
+
+
 }