Merge remote-tracking branch 'origin/new/bug_8636'
[koha.git] / Koha / SearchEngine / Solr / Index.pm
1 package Koha::SearchEngine::Solr::Index;
2 use Moose::Role;
3 with 'Koha::SearchEngine::IndexRole';
4
5 use Data::SearchEngine::Solr;
6 use Data::Dump qw(dump);
7 use List::MoreUtils qw(uniq);
8
9 use Koha::SearchEngine::Solr;
10 use C4::AuthoritiesMarc;
11 use C4::Biblio;
12 use Koha::RecordProcessor;
13
14 has searchengine => (
15     is => 'rw',
16     isa => 'Koha::SearchEngine::Solr',
17     default => sub { Koha::SearchEngine::Solr->new },
18     lazy => 1
19 );
20
21 sub optimize {
22     my ( $self ) = @_;
23     return $self->searchengine->_solr->optimize;
24 }
25
26 sub index_record {
27     my ($self, $recordtype, $recordids) = @_;
28
29     my $indexes = $self->searchengine->config->indexes;
30     my @records;
31
32     my $recordids_str = ref($recordids) eq 'ARRAY'
33                     ? join " ", @$recordids
34                     : $recordids;
35     warn "IndexRecord called with $recordtype $recordids_str";
36
37     for my $id ( @$recordids ) {
38         my $record;
39
40         $record = GetAuthority( $id )  if $recordtype eq "authority";
41         $record = GetMarcBiblio( $id ) if $recordtype eq "biblio";
42
43         if ($record_type eq 'biblio' && C4::Context->preference('IncludeSeeFromInSearches')) {
44             my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
45             $record = $normalizer->process($record);
46         }
47
48         next unless ( $record );
49
50         my $index_values = {
51             recordid => $id,
52             recordtype => $recordtype,
53         };
54
55         warn "Indexing $recordtype $id";
56
57         for my $index ( @$indexes ) {
58             next if $index->{ressource_type} ne $recordtype;
59             my @values;
60             eval {
61                 my $mappings = $index->{mappings};
62                 for my $tag_subf_code ( sort @$mappings ) {
63                     my ( $f, $sf ) = split /\$/, $tag_subf_code;
64                     for my $field ( $record->field( $f ) ) {
65                         if ( $field->is_control_field ) {
66                             push @values, $field->data;
67                         } else {
68                             my @sfvals = $sf eq '*'
69                                        ? map { $_->[1] } $field->subfields
70                                        : map { $_      } $field->subfield( $sf );
71
72                             for ( @sfvals ) {
73                                 $_ = NormalizeDate( $_ ) if $index->{type} eq 'date';
74                                 push @values, $_ if $_;
75                             }
76                         }
77                     }
78                 }
79                 @values = uniq (@values); #Removes duplicates
80
81                 $index_values->{$index->{type}."_".$index->{code}} = \@values;
82                 if ( $index->{sortable} ){
83                     $index_values->{"srt_" . $index->{type} . "_".$index->{code}} = $values[0];
84                 }
85                 # Add index str for facets if it's not exist
86                 if ( $index->{facetable} and @values > 0 and $index->{type} ne 'str' ) {
87                     $index_values->{"str_" . $index->{code}} = $values[0];
88                 }
89             };
90             if ( $@ ) {
91                 chomp $@;
92                 warn  "Error during indexation : recordid $id, index $index->{code} ( $@ )";
93             }
94         }
95
96         my $solrrecord = Data::SearchEngine::Item->new(
97             id    => "${recordtype}_$id",
98             score => 1,
99             values => $index_values,
100         );
101         push @records, $solrrecord;
102     }
103     $self->searchengine->add( \@records );
104 }
105
106 1;