#!/usr/bin/perl -w
use strict;
use warnings;
use CGI qw(:standard escapeHTML);
use JSON;
use utf8;
binmode(STDOUT, ":utf8");
my $query = param('query') || '';
\( query =~ s/^\s+|\s+ \)//g; # Обрізати пробіли
# Валідація (посилена безпека)
if (!$query || length($query) < 3 || length($query) > 100 || $query =~ /[^\w\s]/) {
print header(-charset => 'UTF-8');
print start_html(-title => 'Пошук');
print "
Недійсний запит: мінімум 3 символи, тільки букви та пробіли.
";
print end_html();
exit;
}
my $index_file = '/path/to/search_index.json'; # Той самий шлях
# Читати JSON
open(my $json_fh, '<:utf8', $index_file) or die "Не можу прочитати індекс: $!";
local $/;
my $json_text = <$json_fh>;
close($json_fh);
my $index = decode_json($json_text);
print header(-charset => 'UTF-8');
print start_html(-title => "Результати пошуку за '$query'");
print "Результати за запитом '" . escapeHTML($query) . "':
\n";
# Розбити запит на слова
my @query_words = map { lc($_) } grep { length >= 3 } split(/\s+/, $query);
# Знайти перетин для всіх слів (просте AND)
my %results;
for my $word (@query_words) {
next unless $index->{$word};
for my $page (@{ $index->{$word} }) {
$results{ $page->{path} }->{title} = $page->{title};
$results{ $page->{path} }->{snippet} = $page->{snippet} unless $results{ $page->{path} }->{snippet};
$results{ $page->{path} }->{count}++; # Ранжування за кількістю збігів
}
}
# Сортувати за кількістю збігів (ранжування)
my @sorted_paths = sort { $results{$b}->{count} <=> $results{$a}->{count} } keys %results;
for my $path (@sorted_paths) {
my $title = escapeHTML($results{$path}->{title});
my $snippet = escapeHTML($results{$path}->{snippet});
print "- $title ($snippet)
\n";
}
print "
\n" . (@sorted_paths ? "" : "Нічого не знайдено.
");
print end_html();