603c83368ef18bfa6000f5fcd09d7902978dccae
[koha.git] / Koha / SearchEngine / Solr / Search.pm
1 package Koha::SearchEngine::Solr::Search;
2
3 # This file is part of Koha.
4 #
5 # Copyright 2012 BibLibre
6 # Copyright 2012 KohaAloha
7 #
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21 use Moose::Role;
22 with 'Koha::SearchEngine::SearchRole';
23
24 use Data::Dump qw(dump);
25 use XML::Simple;
26
27 use Data::SearchEngine::Solr;
28 use Data::Pagination;
29 use Data::SearchEngine::Query;
30 use Koha::SearchEngine::Solr;
31
32 has searchengine => (
33     is => 'rw',
34     isa => 'Koha::SearchEngine::Solr',
35     default => sub { Koha::SearchEngine::Solr->new },
36     lazy => 1
37 );
38
39 sub search {
40     my ( $self, $q, $filters, $params ) = @_;
41
42     $q         ||= '*:*';
43     $filters   ||= {};
44     my $page   = defined $params->{page}   ? $params->{page}   : 1;
45     my $count  = defined $params->{count}  ? $params->{count}  : 999999999;
46     my $sort   = defined $params->{sort}   ? $params->{sort}   : 'score desc';
47     my $facets = defined $params->{facets} ? $params->{facets} : 0;
48
49     # Construct fl from $params->{fl}
50     # If "recordid" or "id" not exist, we push them
51     my $fl = join ",",
52         defined $params->{fl}
53             ? (
54                 @{$params->{fl}},
55                 grep ( /^recordid$/, @{$params->{fl}} ) ? () : "recordid",
56                 grep ( /^id$/, @{$params->{fl}} ) ? () : "id"
57               )
58             : ( "recordid", "id" );
59
60     my $recordtype;
61     $recordtype = ref($filters->{recordtype}) eq 'ARRAY'
62                     ? $filters->{recordtype}[0]
63                     : $filters->{recordtype}
64                 if defined $filters && defined $filters->{recordtype};
65
66     if ( $facets ) {
67         $self->searchengine->options->{"facet"}          = 'true';
68         $self->searchengine->options->{"facet.mincount"} = 1;
69         $self->searchengine->options->{"facet.limit"}    = 10; # TODO create a new systempreference C4::Context->preference("numFacetsDisplay")
70         my @facetable_indexes = map { 'str_' . $_->{code} } @{$self->searchengine->config->facetable_indexes};
71         $self->searchengine->options->{"facet.field"}    = \@facetable_indexes;
72     }
73     $self->searchengine->options->{sort} = $sort;
74     $self->searchengine->options->{fl} = $fl;
75
76     # Construct filters
77     $self->searchengine->options->{fq} = [
78         map {
79             my $idx = $_;
80             ref($filters->{$idx}) eq 'ARRAY'
81                 ?
82                     '('
83                     . join( ' AND ',
84                         map {
85                             my $filter_str = $_;
86                             utf8::decode($filter_str);
87                             my $quotes_existed = ( $filter_str =~ m/^".*"$/ );
88                             $filter_str =~ s/^"(.*)"$/$1/; #remove quote around value if exist
89                             $filter_str =~ s/[^\\]\K"/\\"/g;
90                             $filter_str = qq{"$filter_str"} # Add quote around value if not exist
91                                 if not $filter_str =~ /^".*"$/
92                                     and $quotes_existed;
93                             qq{$idx:$filter_str};
94                         } @{ $filters->{$idx} } )
95                     . ')'
96                 : "$idx:$filters->{$idx}";
97         } keys %$filters
98     ];
99
100     my $sq = Data::SearchEngine::Query->new(
101         page  => $page,
102         count => $count,
103         query => $q,
104     );
105
106     # Get results
107     my $results = eval { $self->searchengine->search( $sq ) };
108
109     # Get error if exists
110     if ( $@ ) {
111         my $err = $@;
112
113         $err =~ s#^[^\n]*\n##; # Delete first line
114         if ( $err =~ "400 URL must be absolute" ) {
115             $err = "Your system preference 'SolrAPI' is not set correctly";
116         }
117         elsif ( not $err =~ 'Connection refused' ) {
118             my $document = XMLin( $err );
119             $err = "$$document{body}{h2} : $$document{body}{pre}";
120         }
121         $results->{error} = $err;
122     }
123     return $results;
124 }
125
126 sub dosmth {'bou' }
127
128 1;