ranking search matrici

This commit is contained in:
2026-07-10 11:02:45 +02:00
parent e3f7637b64
commit 68f344bc06
+49 -18
View File
@@ -63,35 +63,66 @@ if (isset($_GET['macro_list'])) {
exit; exit;
} }
// Search (with optional MacroMatrice filter) - multi-term AND, position-independent // Search (with optional MacroMatrice filter) - multi-term AND, position-independent, ranked
$results = [];
// Spezza la query in termini separati (gestisce spazi multipli, rimuove vuoti)
$terms = array_values(array_filter( $terms = array_values(array_filter(
preg_split('/\s+/u', $q, -1, PREG_SPLIT_NO_EMPTY) preg_split('/\s+/u', $q, -1, PREG_SPLIT_NO_EMPTY)
)); ));
// Nessun termine digitato: comportamento invariato (alfabetico, taglio al limite)
if (empty($terms)) {
$results = [];
foreach ($matrici as $m) {
if ($macro !== '' && ($m['MacroMatrice'] ?? '') !== $macro) continue;
$results[] = ['id' => $m['IdMatrice'], 'text' => $m['NomeMatrice'] ?? ''];
if (count($results) >= $limit) break;
}
echo json_encode(['results' => $results]);
exit;
}
$firstTerm = $terms[0];
$scored = [];
foreach ($matrici as $m) { foreach ($matrici as $m) {
$nome = $m['NomeMatrice'] ?? ''; $nome = $m['NomeMatrice'] ?? '';
if ($macro !== '' && ($m['MacroMatrice'] ?? '') !== $macro) continue; if ($macro !== '' && ($m['MacroMatrice'] ?? '') !== $macro) continue;
if (empty($terms)) { $nomeLower = mb_strtolower($nome);
// Nessun termine digitato: mostra tutto fino al limite
$results[] = ['id' => $m['IdMatrice'], 'text' => $nome]; // AND: tutti i termini devono essere presenti (in qualsiasi posizione)
} else { $matchAll = true;
$nomeLower = mb_strtolower($nome); foreach ($terms as $t) {
$matchAll = true; if (mb_strpos($nomeLower, $t) === false) {
foreach ($terms as $t) { $matchAll = false;
if (mb_strpos($nomeLower, $t) === false) { break;
$matchAll = false;
break;
}
} }
if (!$matchAll) continue; }
$results[] = ['id' => $m['IdMatrice'], 'text' => $nome]; if (!$matchAll) continue;
// Punteggio di pertinenza (più basso = più rilevante, per ordinamento crescente)
if ($nomeLower === $q) {
$score = 0; // match esatto
} elseif (mb_strpos($nomeLower, $firstTerm) === 0) {
$score = 1; // il nome inizia col primo termine
} elseif (preg_match('/(^|\s)' . preg_quote($firstTerm, '/') . '/u', $nomeLower)) {
$score = 2; // primo termine a inizio di una parola
} else {
$score = 3; // termine presente ma non a inizio parola
} }
if (count($results) >= $limit) break; $scored[] = ['id' => $m['IdMatrice'], 'text' => $nome, '_s' => $score, '_n' => $nomeLower];
} }
// Ordina per punteggio, poi alfabetico (stabile e prevedibile)
usort($scored, function ($a, $b) {
if ($a['_s'] !== $b['_s']) return $a['_s'] - $b['_s'];
return strcmp($a['_n'], $b['_n']);
});
// Taglia al limite DOPO l'ordinamento e rimuovi i campi interni
$results = array_map(
fn($r) => ['id' => $r['id'], 'text' => $r['text']],
array_slice($scored, 0, $limit)
);
echo json_encode(['results' => $results]); echo json_encode(['results' => $results]);