#!/usr/local/bin/perl -T use strict; use warnings; # (Change configuration variables as needed.) my $path_to_index = '/path/to/index'; use CGI; use List::Util qw( max min ); use POSIX qw( ceil ); use Encode qw( decode ); use KinoSearch::Search::IndexSearcher; use KinoSearch::Highlight::Highlighter; use KinoSearch::Search::QueryParser; use KinoSearch::Search::TermQuery; use KinoSearch::Search::ANDQuery; my $cgi = CGI->new; my $q = decode( "UTF-8", $cgi->param('q') || '' ); my $offset = decode( "UTF-8", $cgi->param('offset') || 0 ); my $category = decode( "UTF-8", $cgi->param('category') || '' ); my $page_size = 10; # Create an IndexSearcher and a QueryParser. my $searcher = KinoSearch::Search::IndexSearcher->new( index => $path_to_index, ); my $qparser = KinoSearch::Search::QueryParser->new( schema => $searcher->get_schema, ); # Build up a Query. my $query = $qparser->parse($q); if ($category) { my $category_query = KinoSearch::Search::TermQuery->new( field => 'category', term => $category, ); $query = KinoSearch::Search::ANDQuery->new( children => [ $query, $category_query ] ); } # Execute the Query and get a Hits object. my $hits = $searcher->hits( query => $query, offset => $offset, num_wanted => $page_size, ); my $hit_count = $hits->total_hits; # Arrange for highlighted excerpts to be created. my $highlighter = KinoSearch::Highlight::Highlighter->new( searcher => $searcher, query => $q, field => 'content' ); # Create result list. my $report = ''; while ( my $hit = $hits->next ) { my $score = sprintf( "%0.3f", $hit->get_score ); my $excerpt = $highlighter->create_excerpt($hit); $report .= qq|
$hit->{title}
$score
$excerpt
$hit->{url}
No matches for $escaped_q
|; } else { # Calculate the nums for the first and last hit to display. my $last_result = min( ( $offset + $page_size ), $total_hits ); my $first_result = min( ( $offset + 1 ), $last_result ); # Display the result nums, start paging info. $paging_info = qq|Results $first_result-$last_result of $total_hits for $escaped_q.
Results Page: |; # Calculate first and last hits pages to display / link to. my $current_page = int( $first_result / $page_size ) + 1; my $last_page = ceil( $total_hits / $page_size ); my $first_page = max( 1, ( $current_page - 9 ) ); $last_page = min( $last_page, ( $current_page + 10 ) ); # Create a url for use in paging links. my $href = $cgi->url( -relative => 1 ); $href .= "?q=" . CGI::escape($query_string); $href .= ";category=" . CGI::escape($category); $href .= ";offset=" . CGI::escape($offset); # Generate the "Prev" link. if ( $current_page > 1 ) { my $new_offset = ( $current_page - 2 ) * $page_size; $href =~ s/(?<=offset=)\d+/$new_offset/; $paging_info .= qq|<= Prev\n|; } # Generate paging links. for my $page_num ( $first_page .. $last_page ) { if ( $page_num == $current_page ) { $paging_info .= qq|$page_num \n|; } else { my $new_offset = ( $page_num - 1 ) * $page_size; $href =~ s/(?<=offset=)\d+/$new_offset/; $paging_info .= qq|$page_num\n|; } } # Generate the "Next" link. if ( $current_page != $last_page ) { my $new_offset = $current_page * $page_size; $href =~ s/(?<=offset=)\d+/$new_offset/; $paging_info .= qq|Next =>\n|; } # Close tag. $paging_info .= "
\n"; } return $paging_info; } # Build up the HTML "select" object for the "category" field. sub generate_category_select { my $cat = shift; my $select = qq| |; if ($cat) { $select =~ s/"$cat"/"$cat" selected/; } return $select; } # Print content to output. sub blast_out_content { my ( $query_string, $hit_list, $paging_info, $category_select ) = @_; my $escaped_q = CGI::escapeHTML($query_string); binmode( STDOUT, ":encoding(UTF-8)" ); print qq|Content-type: text/html; charset=UTF-8\n\n|; print qq|Powered by KinoSearch