}
Check whether the specified heading-auth link is valid without reference
-to Zebra/Solr. Ideally this code would be in C4::Heading, but that won't be
+to Zebra. Ideally this code would be in C4::Heading, but that won't be
possible until we have de-cycled C4::AuthoritiesMarc, so this is the
safest place.
'required' => '1',
'min_ver' => '0.03',
},
- 'Data::Paginator' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '0.04',
- },
- 'Data::Pagination' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '0.44',
- },
- 'JSON::Any' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '1.28',
- },
- 'MooseX::Storage' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '0.30',
- },
- 'MooseX::Types' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '0.30',
- },
- 'String::RewritePrefix' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '0.006',
- },
- 'Time::Progress' => {
- 'usage' => 'Core',
- 'required' => '0',
- 'min_ver' => '1.7',
- },
'DBD::Mock' => {
'usage' => 'Core',
'required' => '1',
+++ /dev/null
-package Koha::SearchEngine;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-use C4::Context;
-use Koha::SearchEngine::Config;
-
-has 'name' => (
- is => 'ro',
- default => sub {
- C4::Context->preference('SearchEngine');
- }
-);
-
-has config => (
- is => 'rw',
- lazy => 1,
- default => sub {
- Koha::SearchEngine::Config->new;
- }
-# lazy => 1,
-# builder => '_build_config',
-);
-
-#sub _build_config {
-# my ( $self ) = @_;
-# Koha::SearchEngine::Config->new( $self->name );
-#);
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Config;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-
-use Moose::Util qw( apply_all_roles );
-
-sub BUILD {
- my $self = shift;
- my $syspref = C4::Context->preference("SearchEngine");
- apply_all_roles( $self, "Koha::SearchEngine::${syspref}::Config" );
-};
-1;
+++ /dev/null
-package Koha::SearchEngine::ConfigRole;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-
-requires 'indexes', 'index', 'ressource_types';
-
-1;
+++ /dev/null
-package Koha::SearchEngine::FacetsBuilder;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-
-use Moose::Util qw( apply_all_roles );
-
-sub BUILD {
- my $self = shift;
- my $syspref = C4::Context->preference("SearchEngine");
- apply_all_roles( $self, "Koha::SearchEngine::${syspref}::FacetsBuilder" );
-};
-1;
+++ /dev/null
-package Koha::SearchEngine::FacetsBuilderRole;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-
-requires 'build_facets';
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Index;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-
-use Moose::Util qw( apply_all_roles );
-
-sub BUILD {
- my $self = shift;
- my $syspref = 'Solr';
- apply_all_roles( $self, "Koha::SearchEngine::${syspref}::Index" );
-};
-1;
+++ /dev/null
-package Koha::SearchEngine::IndexRole;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-
-requires 'index_record';
-
-1;
+++ /dev/null
-package Koha::SearchEngine::QueryBuilder;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-
-use Moose::Util qw( apply_all_roles );
-
-sub BUILD {
- my $self = shift;
- my $syspref = C4::Context->preference("SearchEngine");
- apply_all_roles( $self, "Koha::SearchEngine::${syspref}::QueryBuilder" );
-};
-1;
+++ /dev/null
-package Koha::SearchEngine::QueryBuilderRole;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-
-requires 'build_query';
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Search;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-use C4::Context;
-
-use Moose::Util qw( apply_all_roles );
-
-sub BUILD {
- my $self = shift;
- my $syspref = C4::Context->preference("SearchEngine");
- apply_all_roles( $self, "Koha::SearchEngine::${syspref}::Search" );
-};
-1;
+++ /dev/null
-package Koha::SearchEngine::SearchRole;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-
-requires 'search';
-requires 'dosmth';
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-use Koha::SearchEngine::Config;
-
-extends 'Koha::SearchEngine', 'Data::SearchEngine::Solr';
-
-has '+url' => (
- is => 'ro',
- isa => 'Str',
-# default => sub {
-# C4::Context->preference('SolrAPI');
-# },
- lazy => 1,
- builder => '_build_url',
- required => 1
-);
-
-sub _build_url {
- my ( $self ) = @_;
- $self->config->SolrAPI;
-}
-
-has '+options' => (
- is => 'ro',
- isa => 'HashRef',
- default => sub {
- {
- wt => 'json',
- fl => '*,score',
- fq => 'recordtype:biblio',
- facets => 'true'
- }
- }
-
-);
-
-has indexes => (
- is => 'ro',
- lazy => 1,
- default => sub {
-# my $dbh => ...;
- },
-);
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr::Config;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Modern::Perl;
-use Moose::Role;
-use YAML;
-
-with 'Koha::SearchEngine::ConfigRole';
-
-has index_config => (
- is => 'rw',
- lazy => 1,
- builder => '_load_index_config_file',
-);
-
-has solr_config => (
- is => 'rw',
- lazy => 1,
- builder => '_load_solr_config_file',
-);
-
-has index_filename => (
- is => 'rw',
- lazy => 1,
- default => C4::Context->config("installdir") . qq{/etc/searchengine/solr/indexes.yaml},
-);
-has solr_filename => (
- is => 'rw',
- lazy => 1,
- default => C4::Context->config("installdir") . qq{/etc/searchengine/solr/config.yaml},
-);
-
-sub _load_index_config_file {
- my ( $self, $filename ) = @_;
- $self->index_filename( $filename ) if defined $filename;
- die "The config index file (" . $self->index_filename . ") for Solr is not exist" if not -e $self->index_filename;
-
- return YAML::LoadFile($self->index_filename);
-}
-
-sub _load_solr_config_file {
- my ( $self ) = @_;
- die "The solr config index file (" . $self->solr_filename . ") for Solr is not exist" if not -e $self->solr_filename;
-
- return YAML::LoadFile($self->solr_filename);
-}
-
-sub set_config_filename {
- my ( $self, $filename ) = @_;
- $self->index_config( $self->_load_index_config_file( $filename ) );
-}
-
-sub SolrAPI {
- my ( $self ) = @_;
- return $self->solr_config->{SolrAPI};
-}
-sub indexes { # FIXME Return index list if param not an hashref (string ressource_type)
- my ( $self, $indexes ) = @_;
- return $self->write( { indexes => $indexes } ) if defined $indexes;
- return $self->index_config->{indexes};
-}
-
-sub index {
- my ( $self, $code ) = @_;
- my @index = map { ( $_->{code} eq $code ) ? $_ : () } @{$self->index_config->{indexes}};
- return $index[0];
-}
-
-sub ressource_types {
- my ( $self ) = @_;
- my $config = $self->index_config;
- return $config->{ressource_types};
-}
-
-sub sortable_indexes {
- my ( $self ) = @_;
- my @sortable_indexes = map { $_->{sortable} ? $_ : () } @{ $self->index_config->{indexes} };
- return \@sortable_indexes;
-}
-
-sub facetable_indexes {
- my ( $self ) = @_;
- my @facetable_indexes = map { $_->{facetable} ? $_ : () } @{ $self->index_config->{indexes} };
- return \@facetable_indexes;
-}
-
-sub reload {
- my ( $self ) = @_;
- $self->index_config( $self->_load_index_config_file );
-}
-sub write {
- my ( $self, $values ) = @_;
- my $r;
- while ( my ( $k, $v ) = each %$values ) {
- $r->{$k} = $v;
- }
-
- if ( not grep /^ressource_type$/, keys %$values ) {
- $r->{ressource_types} = $self->ressource_types;
- }
-
- if ( not grep /^indexes$/, keys %$values ) {
- $r->{indexes} = $self->indexes;
- }
-
- eval {
- YAML::DumpFile( $self->index_filename, $r );
- };
- if ( $@ ) {
- die "Failed to dump the index config into the specified file ($@)";
- }
-
- $self->reload;
-}
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr::FacetsBuilder;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Modern::Perl;
-use Moose::Role;
-
-with 'Koha::SearchEngine::FacetsBuilderRole';
-
-sub build_facets {
- my ( $self, $results, $facetable_indexes, $filters ) = @_;
- my @facets_loop;
- for my $index ( @$facetable_indexes ) {
- my $index_name = $index->{type} . '_' . $index->{code};
- my $facets = $results->facets->{'str_' . $index->{code}};
- if ( @$facets > 1 ) {
- my @values;
- $index =~ m/^([^_]*)_(.*)$/;
- for ( my $i = 0 ; $i < scalar(@$facets) ; $i++ ) {
- my $value = $facets->[$i++];
- my $count = $facets->[$i];
- utf8::encode($value);
- my $lib =$value;
- push @values, {
- 'lib' => $lib,
- 'value' => $value,
- 'count' => $count,
- 'active' => ( $filters->{$index_name} and scalar( grep /"?\Q$value\E"?/, @{ $filters->{$index_name} } ) ) ? 1 : 0,
- };
- }
-
- push @facets_loop, {
- 'indexname' => $index_name,
- 'label' => $index->{label},
- 'values' => \@values,
- 'size' => scalar(@values),
- };
- }
- }
- return @facets_loop;
-}
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr::Index;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-# Copyright 2012 C & P Bibliography Services
-# Copyright 2012 PTFS-Europe Ltd.
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-with 'Koha::SearchEngine::IndexRole';
-
-use Data::SearchEngine::Solr;
-use Data::Dump qw(dump);
-use List::MoreUtils qw(uniq);
-
-use Koha::SearchEngine::Solr;
-use C4::AuthoritiesMarc;
-use C4::Biblio;
-use Koha::RecordProcessor;
-
-has searchengine => (
- is => 'rw',
- isa => 'Koha::SearchEngine::Solr',
- default => sub { Koha::SearchEngine::Solr->new },
- lazy => 1
-);
-
-sub optimize {
- my ( $self ) = @_;
- return $self->searchengine->_solr->optimize;
-}
-
-sub index_record {
- my ($self, $recordtype, $recordids) = @_;
-
- my $indexes = $self->searchengine->config->indexes;
- my @records;
-
- my $recordids_str = ref($recordids) eq 'ARRAY'
- ? join " ", @$recordids
- : $recordids;
- warn "IndexRecord called with $recordtype $recordids_str";
-
- for my $id ( @$recordids ) {
- my $record;
-
- $record = GetAuthority( $id ) if $recordtype eq "authority";
- $record = GetMarcBiblio( $id ) if $recordtype eq "biblio";
-
- if ($recordtype eq 'biblio' && C4::Context->preference('IncludeSeeFromInSearches')) {
- my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
- $record = $normalizer->process($record);
- }
-
- next unless ( $record );
-
- my $index_values = {
- recordid => $id,
- recordtype => $recordtype,
- };
-
- warn "Indexing $recordtype $id";
-
- for my $index ( @$indexes ) {
- next if $index->{ressource_type} ne $recordtype;
- my @values;
- eval {
- my $mappings = $index->{mappings};
- for my $tag_subf_code ( sort @$mappings ) {
- my ( $f, $sf ) = split /\$/, $tag_subf_code;
- for my $field ( $record->field( $f ) ) {
- if ( $field->is_control_field ) {
- push @values, $field->data;
- } else {
- my @sfvals = $sf eq '*'
- ? map { $_->[1] } $field->subfields
- : map { $_ } $field->subfield( $sf );
-
- for ( @sfvals ) {
- $_ = NormalizeDate( $_ ) if $index->{type} eq 'date';
- push @values, $_ if $_;
- }
- }
- }
- }
- @values = uniq (@values); #Removes duplicates
-
- $index_values->{$index->{type}."_".$index->{code}} = \@values;
- if ( $index->{sortable} ){
- $index_values->{"srt_" . $index->{type} . "_".$index->{code}} = $values[0];
- }
- # Add index str for facets if it's not exist
- if ( $index->{facetable} and @values > 0 and $index->{type} ne 'str' ) {
- $index_values->{"str_" . $index->{code}} = $values[0];
- }
- };
- if ( $@ ) {
- chomp $@;
- warn "Error during indexation : recordid $id, index $index->{code} ( $@ )";
- }
- }
-
- my $solrrecord = Data::SearchEngine::Item->new(
- id => "${recordtype}_$id",
- score => 1,
- values => $index_values,
- );
- push @records, $solrrecord;
- }
- $self->searchengine->add( \@records );
-}
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr::QueryBuilder;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Modern::Perl;
-use Moose::Role;
-
-with 'Koha::SearchEngine::QueryBuilderRole';
-
-sub build_advanced_query {
- my ($class, $indexes, $operands, $operators) = @_;
-
- my $q = '';
- my $i = 0;
- my $index_name;
-
- @$operands or return "*:*"; #push @$operands, "[* TO *]";
-
- # Foreach operands
- for my $kw (@$operands){
- $kw =~ s/(\w*\*)/\L$1\E/g; # Lower case on words with right truncation
- $kw =~ s/(\s*\w*\?+\w*\s*)/\L$1\E/g; # Lower case on words contain wildcard ?
- $kw =~ s/([^\\]):/$1\\:/g; # escape colons if not already escaped
- # First element
- if ($i == 0){
- if ( (my @x = eval {@$indexes} ) == 0 ){
- # There is no index, then query is in first operand
- $q = @$operands[0];
- last;
- }
-
- # Catch index name if it's not 'all_fields'
- if ( @$indexes[$i] ne 'all_fields' ) {
- $index_name = @$indexes[$i];
- }else{
- $index_name = '';
- }
-
- # Generate index:operand
- $q .= BuildTokenString($index_name, $kw);
- $i = $i + 1;
-
- next;
- }
- # And others
- $index_name = @$indexes[$i] if @$indexes[$i];
- my $operator = defined @$operators[$i-1] ? @$operators[$i-1] : 'AND';
- if ( uc ( $operator ) eq 'OR' ) {
- $q .= BuildTokenString($index_name, $kw, 'OR');
- } elsif ( uc ( $operator ) eq 'NOT' ) {
- $q .= BuildTokenString($index_name, $kw, 'NOT');
- } else {
- $q .= BuildTokenString($index_name, $kw, 'AND');
- }
- $i = $i + 1;
- }
-
- return $q;
-
-}
-
-sub BuildTokenString {
- my ($index, $string, $operator) = @_;
- my $r;
-
- if ($index ne 'all_fields' && $index ne ''){
- # Operand can contains an expression in brackets
- if (
- $string =~ / /
- and not ( $string =~ /^\(.*\)$/ )
- and not $string =~ /\[.*TO.*\]/ ) {
- my @dqs; #double-quoted string
- while ( $string =~ /"(?:[^"\\]++|\\.)*+"/g ) {
- push @dqs, $&;
- $string =~ s/\ *\Q$&\E\ *//; # Remove useless space before and after
- }
-
- my @words = defined $string ? split ' ', $string : undef;
- my $join = join qq{ AND } , map {
- my $value = $_;
- if ( $index =~ /^date_/ ) {
- #$value = C4::Search::Engine::Solr::buildDateOperand( $value ); TODO
- }
- ( $value =~ /^"/ and $value ne '""'
- and $index ne "emallfields"
- and $index =~ /(txt_|ste_)/ )
- ? qq{em$index:$value}
- : qq{$index:$value};
- } (@dqs, @words);
- $r .= qq{($join)};
- } else {
- if ( $index =~ /^date_/ ) {
- #$string = C4::Search::Engine::Solr::buildDateOperand( $string ); TODO
- }
-
- $r = "$index:$string";
- }
- }else{
- $r = $string;
- }
-
- return " $operator $r" if $operator;
- return $r;
-}
-
-sub build_query {
- my ($class, $query) = @_;
-
- return "*:*" if not defined $query;
-
- # Particular *:* query
- if ($query eq '*:*'){
- return $query;
- }
-
- $query =~ s/(\w*\*)/\L$1\E/g; # Lower case on words with right truncation
- $query =~ s/(\s*\w*\?+\w*\s*)/\L$1\E/g; # Lower case on words contain wildcard ?
-
- my @quotes; # Process colons in quotes
- while ( $query =~ /'(?:[^'\\]++|\\.)*+'/g ) {
- push @quotes, $&;
- }
-
- for ( @quotes ) {
- my $replacement = $_;
- $replacement =~ s/[^\\]\K:/\\:/g;
- $query =~ s/$_/$replacement/;
- }
-
- $query =~ s/ : / \\: /g; # escape colons if " : "
-
- my $new_query = $query;#C4::Search::Query::splitToken($query); TODO
-
- $new_query =~ s/all_fields://g;
-
- # Upper case for operators
- $new_query =~ s/ or / OR /g;
- $new_query =~ s/ and / AND /g;
- $new_query =~ s/ not / NOT /g;
-
- return $new_query;
-}
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Solr::Search;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-# Copyright 2012 KohaAloha
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-with 'Koha::SearchEngine::SearchRole';
-
-use Data::Dump qw(dump);
-use XML::Simple;
-
-use Data::SearchEngine::Solr;
-use Data::Pagination;
-use Data::SearchEngine::Query;
-use Koha::SearchEngine::Solr;
-
-has searchengine => (
- is => 'rw',
- isa => 'Koha::SearchEngine::Solr',
- default => sub { Koha::SearchEngine::Solr->new },
- lazy => 1
-);
-
-sub search {
- my ( $self, $q, $filters, $params ) = @_;
-
- $q ||= '*:*';
- $filters ||= {};
- my $page = defined $params->{page} ? $params->{page} : 1;
- my $count = defined $params->{count} ? $params->{count} : 999999999;
- my $sort = defined $params->{sort} ? $params->{sort} : 'score desc';
- my $facets = defined $params->{facets} ? $params->{facets} : 0;
-
- # Construct fl from $params->{fl}
- # If "recordid" or "id" not exist, we push them
- my $fl = join ",",
- defined $params->{fl}
- ? (
- @{$params->{fl}},
- grep ( /^recordid$/, @{$params->{fl}} ) ? () : "recordid",
- grep ( /^id$/, @{$params->{fl}} ) ? () : "id"
- )
- : ( "recordid", "id" );
-
- my $recordtype;
- $recordtype = ref($filters->{recordtype}) eq 'ARRAY'
- ? $filters->{recordtype}[0]
- : $filters->{recordtype}
- if defined $filters && defined $filters->{recordtype};
-
- if ( $facets ) {
- $self->searchengine->options->{"facet"} = 'true';
- $self->searchengine->options->{"facet.mincount"} = 1;
- $self->searchengine->options->{"facet.limit"} = 10; # TODO create a new systempreference C4::Context->preference("numFacetsDisplay")
- my @facetable_indexes = map { 'str_' . $_->{code} } @{$self->searchengine->config->facetable_indexes};
- $self->searchengine->options->{"facet.field"} = \@facetable_indexes;
- }
- $self->searchengine->options->{sort} = $sort;
- $self->searchengine->options->{fl} = $fl;
-
- # Construct filters
- $self->searchengine->options->{fq} = [
- map {
- my $idx = $_;
- ref($filters->{$idx}) eq 'ARRAY'
- ?
- '('
- . join( ' AND ',
- map {
- my $filter_str = $_;
- utf8::decode($filter_str);
- my $quotes_existed = ( $filter_str =~ m/^".*"$/ );
- $filter_str =~ s/^"(.*)"$/$1/; #remove quote around value if exist
- $filter_str =~ s/[^\\]\K"/\\"/g;
- $filter_str = qq{"$filter_str"} # Add quote around value if not exist
- if not $filter_str =~ /^".*"$/
- and $quotes_existed;
- qq{$idx:$filter_str};
- } @{ $filters->{$idx} } )
- . ')'
- : "$idx:$filters->{$idx}";
- } keys %$filters
- ];
-
- my $sq = Data::SearchEngine::Query->new(
- page => $page,
- count => $count,
- query => $q,
- );
-
- # Get results
- my $results = eval { $self->searchengine->search( $sq ) };
-
- # Get error if exists
- if ( $@ ) {
- my $err = $@;
-
- $err =~ s#^[^\n]*\n##; # Delete first line
- if ( $err =~ "400 URL must be absolute" ) {
- $err = "Your system preference 'SolrAPI' is not set correctly";
- }
- elsif ( not $err =~ 'Connection refused' ) {
- my $document = XMLin( $err );
- $err = "$$document{body}{h2} : $$document{body}{pre}";
- }
- $results->{error} = $err;
- }
- return $results;
-}
-
-sub dosmth {'bou' }
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Zebra;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose;
-
-extends 'Data::SearchEngine::Zebra';
-
-# the configuration file is retrieved from KOHA_CONF by default, provide it from there²
-has '+conf_file' => (
- is => 'ro',
- isa => 'Str',
- default => $ENV{KOHA_CONF},
- required => 1
-);
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Zebra::QueryBuilder;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Modern::Perl;
-use Moose::Role;
-use C4::Search;
-
-with 'Koha::SearchEngine::QueryBuilderRole';
-
-sub build_query {
- shift;
- C4::Search::buildQuery @_;
-}
-
-1;
+++ /dev/null
-package Koha::SearchEngine::Zebra::Search;
-
-# This file is part of Koha.
-#
-# Copyright 2012 BibLibre
-#
-# Koha is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Koha is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Koha; if not, see <http://www.gnu.org/licenses>.
-
-use Moose::Role;
-with 'Koha::SearchEngine::SearchRole';
-
-use Data::SearchEngine::Zebra;
-use Data::SearchEngine::Query;
-use Koha::SearchEngine::Zebra;
-use Data::Dump qw(dump);
-
-has searchengine => (
- is => 'rw',
- isa => 'Koha::SearchEngine::Zebra',
- default => sub { Koha::SearchEngine::Zebra->new },
- lazy => 1
-);
-
-sub search {
- my ($self,$query_string) = @_;
-
- my $query = Data::SearchEngine::Query->new(
- count => 10,
- page => 1,
- query => $query_string,
- );
-
- warn "search for $query_string";
-
- my $results = $self->searchengine->search($query);
-
- foreach my $item (@{ $results->items }) {
- my $title = $item->get_value('ste_title');
- #utf8::encode($title);
- print "$title\n";
- warn dump $title;
- }
-}
-
-sub dosmth {'bou' }
-
-1;
debug => 1,
});
-$template->param( SearchEngine => C4::Context->preference('SearchEngine') );
-
output_html_with_http_headers $query, $cookie, $template->output;
+++ /dev/null
-#!/usr/bin/perl
-
-# Copyright 2012 BibLibre SARL
-#
-# This file is part of Koha.
-#
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
-#
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-use Modern::Perl;
-use CGI;
-use C4::Koha;
-use C4::Output;
-use C4::Auth;
-use Koha::SearchEngine;
-
-my $input = new CGI;
-my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
- {
- template_name => 'admin/searchengine/solr/indexes.tt',
- query => $input,
- type => 'intranet',
-# authnotrequired => 0,
-# flagsrequired => { reserveforothers => "place_holds" }, #TODO
- }
-);
-
-my $ressource_type = $input->param('ressource_type') || 'biblio';
-my $se = Koha::SearchEngine->new;
-my $se_config = $se->config;
-
-my $indexes;
-if ( $input->param('op') and $input->param('op') eq 'edit' ) {
- my @code = $input->param('code');
- my @label = $input->param('label');
- my @type = $input->param('type');
- my @sortable = $input->param('sortable');
- my @facetable = $input->param('facetable');
- my @mandatory = $input->param('mandatory');
- my @ressource_type = $input->param('ressource_type');
- my @mappings = $input->param('mappings');
- my @indexes;
- my @errors;
- for ( 0 .. @code-1 ) {
- my $icode = $code[$_];
- my @current_mappings = split /\r\n/, $mappings[$_];
- if ( not @current_mappings ) {
- @current_mappings = split /\n/, $mappings[$_];
- }
- if ( not @current_mappings ) {
- push @errors, { type => 'no_mapping', value => $icode};
- }
-
- push @indexes, {
- code => $icode,
- label => $label[$_],
- type => $type[$_],
- sortable => scalar(grep(/^$icode$/, @sortable)),
- facetable => scalar(grep(/^$icode$/, @facetable)),
- mandatory => $mandatory[$_] eq '1' ? '1' : '0',
- ressource_type => $ressource_type[$_],
- mappings => \@current_mappings,
- };
- for my $m ( @current_mappings ) {
- push @errors, {type => 'malformed_mapping', value => $m}
- if not $m =~ /^\d(\d|\*|\.){2}\$.$/;
- }
- }
- $indexes = \@indexes if @errors;
- $template->param( errors => \@errors );
-
- $se_config->indexes(\@indexes) if not @errors;
-}
-
-my $ressource_types = $se_config->ressource_types;
-$indexes //= $se_config->indexes;
-
-my $indexloop;
-for my $rt ( @$ressource_types ) {
- my @indexes = map {
- $_->{ressource_type} eq $rt ? $_ : ();
- } @$indexes;
- push @$indexloop, {
- ressource_type => $rt,
- indexes => \@indexes,
- }
-}
-
-$template->param(
- indexloop => $indexloop,
-);
-
-output_html_with_http_headers $input, $cookie, $template->output;
rm -r $(TMP)/var/run
rm -r $(TMP)/var/lock
rm $(TMP)/var/log/koha/README
- rm $(TMP)/etc/koha/searchengine/solr/config.yaml
- rm $(TMP)/etc/koha/searchengine/solr/indexes.yaml
- rm $(TMP)/etc/koha/solr/indexes.yaml
rm -r \
$(TMP)/usr/share/koha/intranet/htdocs/intranet-tmpl/lib/tiny_mce
ln -s /usr/share/tinymce/www \
+++ /dev/null
-SolrAPI: 'http://localhost:8983/solr/solr'
+++ /dev/null
----
-indexes:
- - code: title
- facetable: 1
- label: Title
- mandatory: 1
- mappings:
- - 200$a
- - 210$a
- - 4..$t
- ressource_type: biblio
- sortable: 1
- type: ste
- - code: author
- facetable: 1
- label: Author
- mandatory: 0
- mappings:
- - 700$*
- - 710$*
- ressource_type: biblio
- sortable: 1
- type: str
- - code: subject
- facetable: 0
- label: Subject
- mandatory: 0
- mappings:
- - 600$a
- - 601$a
- ressource_type: biblio
- sortable: 0
- type: str
- - code: biblionumber
- facetable: 0
- label: Biblionumber
- mandatory: 1
- mappings:
- - 001$@
- ressource_type: biblio
- sortable: 0
- type: int
-ressource_types:
- - biblio
- - authority
+++ /dev/null
-ressource_types:
- - biblio
- - authority
-
-indexes:
- - code: title
- label: Title
- type: ste
- ressource_type: biblio
- sortable: 1
- mandatory: 1
- mappings:
- - 200$a
- - 210$a
- - 4..$t
- - code: author
- label: Author
- type: str
- ressource_type: biblio
- sortable: 1
- mandatory: 0
- mappings:
- - 700$*
- - 710$*
- - code: subject
- label: Subject
- type: str
- ressource_type: biblio
- sortable: 0
- mandatory: 0
- mappings:
- - 600$a
- - 601$a
('RoutingSerials','1',NULL,'If ON, serials routing is enabled','YesNo'),
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
-('SearchEngine','Zebra','Solr|Zebra','Search Engine','Choice'),
('SearchMyLibraryFirst','0',NULL,'If ON, OPAC searches return results limited by the user\'s library by default if they are logged in','YesNo'),
('SelfCheckHelpMessage','','70|10','Enter HTML to include under the basic Web-based Self Checkout instructions on the Help page','Textarea'),
('SelfCheckReceiptPrompt','1','NULL','If ON, print receipt dialog pops up when self checkout is finished','YesNo'),
SetVersion($DBversion);
}
+$DBversion = "3.17.00.XXX";
+if ( CheckVersion($DBversion) ) {
+ $dbh->do(q{
+ DELETE FROM systempreferences WHERE variable = 'SearchEngine'
+ });
+ print "Upgrade to $DBversion done (Bug 12538 - Remove SearchEngine syspref)\n";
+ SetVersion($DBversion);
+}
+
=head1 FUNCTIONS
<dd>Manage rules for automatically matching MARC records during record imports.</dd>
<dt><a href="/cgi-bin/koha/admin/oai_sets.pl">OAI sets configuration</a></dt>
<dd>Manage OAI Sets</dd>
- [% IF ( SearchEngine != 'Zebra' ) %]
- <dt><a href="/cgi-bin/koha/admin/searchengine/solr/indexes.pl">Search engine configuration</a></dt>
- <dd>Manage indexes, facets, and their mappings to MARC fields and subfields.</dd>
- [% END %]
</dl>
<h3>Acquisition parameters</h3>
yes: Allow
no: "Don't Allow"
- Mozilla persona for login
- Search Engine:
- -
- - pref: SearchEngine
- default: Zebra
- choices:
- Solr: Solr
- Zebra: Zebra
- - is the search engine used.
+++ /dev/null
-[% INCLUDE 'doc-head-open.inc' %]
-<title>Koha › Administration › Solr config</title>
-[% INCLUDE 'doc-head-close.inc' %]
-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/tablednd.js"></script>
-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.textarea-expander.js"></script>
-<script type="text/javascript">
- function clean_line( line ) {
- $(line).find('input[type="text"]').val("");
- $(line).find('input[type="checkbox"]').attr("checked", false);
- $(line).find('textarea').val("");
- $(line).find('select').find('option:first').attr("selected", "selected");
- }
-
- function clone_line( line ) {
- var new_line = $(line).clone();
- $(new_line).removeClass("nodrag nodrop");
- $(new_line).find('td:last-child>a').removeClass("add").addClass("delete").html(_("Delete"));
- $(new_line).find('[data-id]').each( function() {
- $(this).attr({ name: $(this).attr('data-id') }).removeAttr('data-id');
- } );
- $(new_line).find("select").each( function() {
- var attr = $(this).attr('name');
- var val = $(line).find('[data-id="' + attr + '"]').val();
- $(this).find('option[value="' + val + '"]').attr("selected", "selected");
- } );
- return new_line;
- }
-
- $(document).ready(function() {
- $('.delete').click(function() {
- $(this).parents('tr').remove();
- });
-
- $(".indexes").tableDnD( {
- onDragClass: "dragClass",
- } );
- $("textarea").TextAreaExpander();
- $('.add').click(function() {
- var table = $(this).closest('table');
- var ressource_type = $(table).attr('data-ressource_type');
- var code = $(table).find('input[data-id="code"]').val();
- var label = $(table).find('input[data-id="label"]').val();
- if ( code.length > 0 && label.length > 0 ) {
- var line = $(this).closest("tr");
- var mappings = $(line).find('textarea').val();
- var new_line = clone_line( line );
- $(new_line).find('textarea').val(mappings);
- $(new_line).find("input:checkbox").val(code);
- new_line.appendTo($('table[data-ressource_type="'+ressource_type+'"]>tbody'));
- $('.delete').click(function() {
- $(this).parents('tr').remove();
- });
- clean_line(line);
-
- $(table).tableDnD( {
- onDragClass: "dragClass",
- } );
- }
- });
- });
-</script>
-</head>
-<body id="admin_searchengine_indexes" class="admin">
-[% INCLUDE 'header.inc' %]
-[% INCLUDE 'cat-search.inc' %]
-
-<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> › Search engine configuration</div>
-
-<div id="doc3" class="yui-t1">
-
- <div id="bd">
- <div id="yui-main">
- <div class="yui-b">
- <h1>Search engine configuration</h1>
- <div class="warning">
- Warning: Any modification in these configurations will need a total reindexation to be fully taken into account !
- </div>
- [% IF ( errors ) %]
- <div class="error">
- Errors occurred, Modifications does not apply. Please check following values:
- <ul>
- [% FOREACH e IN errors %]
- <li>
- [% IF ( e.type == "malformed_mapping" ) %]
- The value "[% e.value %]" is not supported for mappings
- [% ELSIF ( e.type == "no_mapping" ) %]
- There is no mapping for the index [% e.value %]
- [% END %]
- </li>
- [% END %]
- </ul>
- </div>
- [% END %]
-
- <form method="post">
- <input type="hidden" name="op" value="edit" />
- [% FOREACH rt IN indexloop %]
- <h2>[% rt.ressource_type %]</h2>
- [% IF ( rt.ressource_type == 'authority' ) %]
- This part is not yet implemented
- [% END %]
- <table id="pouet" class="indexes" data-ressource_type="[% rt.ressource_type %]">
- <thead>
- <tr class="nodrag nodrop">
- <th>Code</th>
- <th>Label</th>
- <th>Type</th>
- <th>Sortable</th>
- <th>Facetable</th>
- <th>Mapping</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- [% FOREACH index IN rt.indexes %]
- <tr>
- <td>
- [% IF ( index.mandatory ) %]
- <input name="code" type="text" maxlength="25" value="[% index.code %]" disabled="disabled" />
- <input name="code" type="hidden" maxlength="25" value="[% index.code %]" />
- [% ELSE %]
- <input name="code" type="text" maxlength="25" value="[% index.code %]" />
- [% END %]
- <input name="mandatory" type="hidden" maxlength="1" value="[% index.mandatory %]" />
- <input name="ressource_type" type="hidden" value="[% index.ressource_type %]" />
- </td>
- <td><input name="label" type="text" maxlength="25" value="[% index.label %]" /></td>
- <td>
- [% IF ( index.mandatory ) %]
- <input type="hidden" name="type" value="[% index.type %]" />
- [% END %]
- [% IF ( index.mandatory ) %]
- <select name="type" disabled="disabled">
- [% ELSE %]
- <select name="type">
- [% END %]
- [% IF ( index.type == 'str' ) %]
- <option value="str" selected="selected">String</option>
- [% ELSE %]
- <option value="str">String</option>
- [% END %]
- [% IF ( index.type == 'ste' ) %]
- <option value="ste" selected="selected">Simple Text</option>
- [% ELSE %]
- <option value="ste">Simple Text</option>
- [% END %]
- [% IF ( index.type == 'txt' ) %]
- <option value="txt" selected="selected">Text</option>
- [% ELSE %]
- <option value="txt">Text</option>
- [% END %]
- [% IF ( index.type == 'int' ) %]
- <option value="int" selected="selected">Integer</option>
- [% ELSE %]
- <option value="int">Integer</option>
- [% END %]
- [% IF ( index.type == 'date' ) %]
- <option value="date" selected="selected">Date</option>
- [% ELSE %]
- <option value="date">Date</option>
- [% END %]
- </select>
- </td>
- <td>
- [% IF ( index.sortable ) %]
- <input name="sortable" type="checkbox" checked="checked" value="[% index.code %]" />
- [% ELSE %]
- <input name="sortable" type="checkbox" value="[% index.code %]" />
- [% END %]
- </td>
- <td>
- [% IF ( index.facetable ) %]
- <input name="facetable" type="checkbox" checked="checked" value="[% index.code %]" />
- [% ELSE %]
- <input name="facetable" type="checkbox" value="[% index.code %]" />
- [% END %]
- </td>
- <td>
- <textarea name="mappings" class="contentEditable">[% FOREACH m IN index.mappings %][% m %]
-[% END %]</textarea> <!-- Don't indent this line -->
- </td>
- <td>[% UNLESS ( index.mandatory ) %]<a class="delete">Delete</a>[% END %]</td>
- </tr>
- [% END %]
- </tbody>
- <tfoot>
- <tr class="nodrag nodrop">
- <td>
- <input data-id="code" type="text" maxlength="25" />
- <input data-id="ressource_type" type="hidden" value="[% rt.ressource_type %]" />
- <input data-id="mandatory" type="hidden" value="0" />
- </td>
- <td><input data-id="label" type="text" maxlength="25" /></td>
- <td>
- <select data-id="type">
- <option value="str">String</option>
- <option value="ste">Simple Text</option>
- <option value="txt">Text</option>
- <option value="int">Integer</option>
- <option value="date">Date</option>
- </select>
- </td>
- <td><input data-id="sortable" type="checkbox" /></td>
- <td><input data-id="facetable" type="checkbox" /></td>
- <td>
- <textarea data-id="mappings" class="contentEditable"></textarea>
- </td>
- <td><a class="add">Add</a></td>
- </tr>
- </tfoot>
- </table>
- [% END %]
- <p><input type="submit" value="Save" /></p>
- </form>
-</div>
-
-</div>
-<div class="yui-b">
-[% INCLUDE 'admin-menu.inc' %]
-</div>
-</div>
-[% INCLUDE 'intranet-bottom.inc' %]
+++ /dev/null
-[% IF facets_loop %]
- <div id="search-facets">
- <h4>Refine your search</h4>
- <ul>
- [% FOR facets IN facets_loop %]
- <li>
- [% facets.label %]
- <ul class="facets_list">
- [% FOR value IN facets.values %]
- <li>
- [% IF ( value.active ) %]
- [% value.lib %] ([% value.count %])
- [% SET url = "/cgi-bin/koha/opac-search.pl?" %]
- [% SET first = 1 %]
- [% FOR p IN follower_params %]
- [% IF p.var != 'filters' %]
- [% UNLESS first %]
- [% SET url = url _ '&' %]
- [% END %]
- [% SET first = 0 %]
- [% SET url = url _ p.var _ '=' _ p.val %]
- [% END %]
- [% END %]
- [% FOR f IN filters %]
- [% UNLESS f.var == facets.indexname && f.val == value.value %]
- [% SET url = url _ '&filters=' _ f.var _ ':"' _ f.val _ '"' %]
- [% END %]
- [% END %]
- [<a href="[% url |url %]">x</a>]
- [% ELSE %]
- [% SET url = "/cgi-bin/koha/opac-search.pl?" %]
- [% SET first = 1 %]
- [% FOR p IN follower_params %]
- [% IF p.var != 'filters' %]
- [% UNLESS first %]
- [% SET url = url _ '&' %]
- [% END %]
- [% SET first = 0 %]
- [% SET url = url _ p.var _ '=' _ p.val %]
- [% END %]
- [% END %]
- [% FOR f IN filters %]
- [% SET url = url _ '&filters=' _ f.var _ ':"' _ f.val _ '"' %]
- [% END %]
- [% SET url = url _ '&filters=' _ facets.indexname _ ':"' _ value.value _ '"' %]
-
- <a href="[% url |url %]">[% value.lib %]</a> ([% value.count %])
- [% END %]
- </li>
- [% END %]
- </ul>
- </li>
- [% END %]
- </ul>
-</div>
-[% END %]
+++ /dev/null
-[% IF ( PAGE_NUMBERS ) %]
- <div class="pages">
- [% IF ( previous_page ) %]
- <a class="nav" href="?[% FOREACH fp IN follower_params %][% fp.var |url %]=[% fp.val |url %]&[% END %]page=[% previous_page |url %]"><< Previous</a>
- [% END %]
- [% FOREACH PAGE_NUMBER IN PAGE_NUMBERS %]
- [% IF ( PAGE_NUMBER.current ) %]
- <span class="current">[% PAGE_NUMBER.page %]</span>
- [% ELSE %]
- <a class="nav" href="?[% FOREACH fp IN follower_params %][% fp.var |url %]=[% fp.val |url %]&[% END %]page=[% PAGE_NUMBER.page |url %]">[% PAGE_NUMBER.page %]</a>
- [% END %]
- [% END %]
- [% IF ( next_page ) %]
- <a class="nav" href="?[% FOREACH fp IN follower_params %][% fp.var |url %]=[% fp.val |url %]&[% END %]page=[% next_page |url %]">Next >></a>
- [% END %]
- </div>
-[% END %]
+++ /dev/null
-[% IF sort_by == "score asc" %]
- <option value="score asc" selected="selected">Relevance asc</option>
-[% ELSE %]
- <option value="score asc">Relevance asc</option>
-[% END %]
-[% IF sort_by == "score desc" %]
- <option value="score desc" selected="selected">Relevance desc</option>
-[% ELSE %]
- <option value="score desc">Relevance desc</option>
-[% END %]
-
-[% FOREACH ind IN sortable_indexes %]
- [% IF sort_by == "$ind.code asc" %]
- <option value="[% ind.code %] asc" selected="selected">[% ind.label %] asc</option>
- [% ELSE %]
- <option value="[% ind.code %] asc">[% ind.label %] asc</option>
- [% END %]
- [% IF sort_by == "$ind.code desc" %]
- <option value="[% ind.code %] desc" selected="selected">[% ind.label %] desc</option>
- [% ELSE %]
- <option value="[% ind.code %] desc">[% ind.label %] desc</option>
- [% END %]
-[% END %]
+++ /dev/null
-#!/usr/bin/perl
-
-# Copyright 2012 BibLibre SARL
-#
-# This file is part of Koha.
-#
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
-#
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-use Modern::Perl;
-use Data::Dumper;
-use Getopt::Long;
-use LWP::Simple;
-use XML::Simple;
-
-use C4::Context;
-use C4::Search;
-use Koha::SearchEngine::Index;
-
-$|=1; # flushes output
-
-if ( C4::Context->preference("SearchEngine") ne 'Solr' ) {
- warn "System preference 'SearchEngine' not equal 'Solr'.";
- warn "We can not indexing";
- exit(1);
-}
-
-#Setup
-
-my ( $reset, $number, $recordtype, $biblionumbers, $optimize, $info, $want_help );
-GetOptions(
- 'r' => \$reset,
- 'n:s' => \$number,
- 't:s' => \$recordtype,
- 'w:s' => \$biblionumbers,
- 'o' => \$optimize,
- 'i' => \$info,
- 'h|help' => \$want_help,
-);
-my $debug = C4::Context->preference("DebugLevel");
-my $index_service = Koha::SearchEngine::Index->new;
-my $solrurl = $index_service->searchengine->config->SolrAPI;
-
-my $ping = &ping_command;
-if (!defined $ping) {
- print "SolrAPI = $solrurl\n";
- print "Solr is Down\n";
- exit(1);
-}
-
-#Script
-
-&print_help if ($want_help);
-&print_info if ($info);
-if ($reset){
- if ($recordtype){
- &reset_index("recordtype:".$recordtype);
- } else {
- &reset_index("*:*");
- }
-}
-
-if (defined $biblionumbers){
- if (not defined $recordtype) { print "You must specify a recordtype\n"; exit 1;}
- &index_biblio($_) for split ',', $biblionumbers;
-} elsif (defined $recordtype) {
- &index_data;
- &optimise_index;
-}
-
-if ($optimize) {
- &optimise_index;
-}
-
-#Functions
-
-sub index_biblio {
- my ($biblionumber) = @_;
- $index_service->index_record($recordtype, [ $biblionumber ] );
-}
-
-sub index_data {
- my $dbh = C4::Context->dbh;
- $dbh->do('SET NAMES UTF8;');
-
- my $query;
- if ( $recordtype eq 'biblio' ) {
- $query = "SELECT biblionumber FROM biblio ORDER BY biblionumber";
- } elsif ( $recordtype eq 'authority' ) {
- $query = "SELECT authid FROM auth_header ORDER BY authid";
- }
- $query .= " LIMIT $number" if $number;
-
- my $sth = $dbh->prepare( $query );
- $sth->execute();
-
- $index_service->index_record($recordtype, [ map { $_->[0] } @{ $sth->fetchall_arrayref } ] );
-
- $sth->finish;
-}
-
-sub reset_index {
- &reset_command;
- &commit_command;
- $debug eq '2' && &count_all_docs eq 0 && warn "Index cleaned!"
-}
-
-sub commit_command {
- my $commiturl = "/update?stream.body=%3Ccommit/%3E";
- my $urlreturns = get $solrurl.$commiturl;
-}
-
-sub ping_command {
- my $pingurl = "/admin/ping";
- my $urlreturns = get $solrurl.$pingurl;
-}
-
-sub reset_command {
- my ($query) = @_;
- my $deleteurl = "/update?stream.body=%3Cdelete%3E%3Cquery%3E".$query."%3C/query%3E%3C/delete%3E";
- my $urlreturns = get $solrurl.$deleteurl;
-}
-
-sub optimise_index {
- $index_service->optimize;
-}
-
-sub count_all_docs {
- my $queryurl = "/select/?q=*:*";
- my $urlreturns = get $solrurl.$queryurl;
- my $xmlsimple = XML::Simple->new();
- my $data = $xmlsimple->XMLin($urlreturns);
- return $data->{result}->{numFound};
-}
-
-sub print_info {
- my $count = &count_all_docs;
- print <<_USAGE_;
-SolrAPI = $solrurl
-How many indexed documents = $count;
-_USAGE_
-}
-
-sub print_help {
- print <<_USAGE_;
-$0: reindex biblios and/or authorities in Solr.
-
-Use this batch job to reindex all biblio or authority records in your Koha database. This job is useful only if you are using Solr search engine.
-
-Parameters:
- -t biblio index bibliographic records
-
- -t authority index authority records
-
- -r clear Solr index before adding records to index - use this option carefully!
-
- -n 100 index 100 first records
-
- -n "100,2" index 2 records after 100th (101 and 102)
-
- -w 101 index biblio with biblionumber equals 101
-
- -o launch optimize command at the end of indexing
-
- -i gives solr install information: SolrAPI value and count all documents indexed
-
- --help or -h show this message.
-_USAGE_
-}
use C4::Context;
use List::MoreUtils q/any/;
-my $searchengine = C4::Context->preference("SearchEngine");
-if ( $searchengine =~ /^Solr$/ ) {
- warn "We use Solr";
- require 'opac/search.pl';
- exit;
-} elsif ( $searchengine =~ /^Zebra$/ ) {
-
-}
-
use C4::Output;
use C4::Auth qw(:DEFAULT get_session);
use C4::Languages qw(getLanguages);
+++ /dev/null
-#!/usr/bin/perl
-
-# Copyright 2012 BibLibre
-#
-# This file is part of Koha.
-#
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
-#
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-use Modern::Perl;
-
-use C4::Context;
-use CGI;
-use C4::Auth;
-use C4::Koha;
-use C4::Output;
-use Koha::SearchEngine::Search;
-use Koha::SearchEngine::QueryBuilder;
-use Koha::SearchEngine::FacetsBuilder;
-
-my $cgi = new CGI;
-
-my $template_name;
-my $template_type = "basic";
-if ( $cgi->param("idx") or $cgi->param("q") ) {
- $template_name = 'search/results.tt';
-} else {
- $template_name = 'search/advsearch.tt';
- $template_type = 'advsearch';
-}
-
-# load the template
-my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
- { template_name => $template_name,
- query => $cgi,
- type => "opac",
- authnotrequired => 1,
- }
-);
-
-my $format = $cgi->param("format") || 'html';
-
-
-
-
-# load the Type stuff
-my $itemtypes = GetItemTypes;
-
-my $page = $cgi->param("page") || 1;
-my $count = $cgi->param('count') || C4::Context->preference('OPACnumSearchResults') || 20;
-$count = 5;
-my $q = $cgi->param("q");
-my $builder = Koha::SearchEngine::QueryBuilder->new;
-$q = $builder->build_query( $q );
-my $search_service = Koha::SearchEngine::Search->new;
-
-# load the sorting stuff
-my $sort_by = $cgi->param('sort_by')
- || C4::Context->preference('OPACdefaultSortField') . ' ' . C4::Context->preference('OPACdefaultSortOrder');
-
-my $search_engine_config = Koha::SearchEngine->new->config;
-my $sortable_indexes = $search_engine_config->sortable_indexes;
-my ( $sort_indexname, $sort_order );
-( $sort_indexname, $sort_order ) = ($1, $2) if ( $sort_by =~ m/^(.*) (asc|desc)$/ );
-my $sort_by_indexname = eval {
- [
- map {
- $_->{code} eq $sort_indexname
- ? 'srt_' . $_->{type} . '_' . $_->{code} . ' ' . $sort_order
- : ()
- } @$sortable_indexes
- ]->[0]
-};
-
-# This array is used to build facets GUI
-my %filters;
-my @tplfilters;
-for my $filter ( $cgi->param('filters') ) {
- next if not $filter;
- my ($k, @v) = $filter =~ /(?: \\. | [^:] )+/xg;
- my $v = join ':', @v;
- push @{$filters{$k}}, $v;
- $v =~ s/^"(.*)"$/$1/; # Remove quotes around
- push @tplfilters, {
- 'var' => $k,
- 'val' => $v,
- };
-}
-push @{$filters{recordtype}}, 'biblio';
-
-my $results = $search_service->search(
- $q,
- \%filters,
- {
- page => $page,
- count => $count,
- sort => $sort_by_indexname,
- facets => 1,
- fl => ["ste_title", "str_author", 'int_biblionumber'],
- }
-);
-
-if ($results->{error}){
- $template->param(query_error => $results->{error});
- output_with_http_headers $cgi, $cookie, $template->output, 'html';
- exit;
-}
-
-
-# populate results with records
-my @r;
-for my $searchresult ( @{ $results->items } ) {
- my $biblionumber = $searchresult->{values}->{recordid};
-
- my $nr;
- while ( my ($k, $v) = each %{$searchresult->{values}} ) {
- my $nk = $k;
- $nk =~ s/^[^_]*_(.*)$/$1/;
- $nr->{$nk} = ref $v ? shift @{$v} : $v;
- }
- push( @r, $nr );
-}
-
-# build facets
-my $facets_builder = Koha::SearchEngine::FacetsBuilder->new;
-my @facets_loop = $facets_builder->build_facets( $results, $search_engine_config->facetable_indexes, \%filters );
-
-my $total = $results->{pager}->{total_entries};
-my $pager = Data::Pagination->new(
- $total,
- $count,
- 20,
- $page,
-);
-
-# params we want to pass for all actions require another query (pagination, sort, facets)
-my @follower_params = map { {
- var => 'filters',
- val => $_->{var}.':"'.$_->{val}.'"'
-} } @tplfilters;
-push @follower_params, { var => 'q', val => $q};
-push @follower_params, { var => 'sort_by', val => $sort_by};
-
-# Pager template params
-$template->param(
- previous_page => $pager->{'prev_page'},
- next_page => $pager->{'next_page'},
- PAGE_NUMBERS => [ map { { page => $_, current => $_ == $page } } @{ $pager->{'numbers_of_set'} } ],
- current_page => $page,
- follower_params => \@follower_params,
- total => $total,
- SEARCH_RESULTS => \@r,
- query => $q,
- count => $count,
- sort_by => $sort_by,
- sortable_indexes => $sortable_indexes,
- facets_loop => \@facets_loop,
- filters => \@tplfilters,
-);
-
-my $content_type = ( $format eq 'rss' or $format eq 'atom' ) ? $format : 'html';
-output_with_http_headers $cgi, $cookie, $template->output, $content_type;
return unless $m =~ s/[.]pm$//;
$m =~ s{^.*/Koha/}{Koha/};
$m =~ s{/}{::}g;
- return if $m =~ /Koha::SearchEngine/; # Koha::SearchEngine::* are experimental
use_ok($m) || BAIL_OUT("***** PROBLEMS LOADING FILE '$m'");
},
},
+++ /dev/null
-use Modern::Perl;
-use Test::More;
-use Koha::SearchEngine::Solr;
-#use Koha::SearchEngine::Zebra;
-use Koha::SearchEngine::Search;
-use t::lib::Mocks qw( mock_preference );
-
-my $se_index = Koha::SearchEngine::Solr->new;
-ok($se_index->isa('Data::SearchEngine::Solr'), 'Solr is a Solr data searchengine');
-
-#$se_index = Koha::SearchEngine::Zebra->new;
-#ok($se_index->isa('Data::SearchEngine::Zebra'), 'Zebra search engine');
-
-t::lib::Mocks::mock_preference('SearchEngine', 'Solr');
-$se_index = Koha::SearchEngine::Search->new;
-ok($se_index->searchengine->isa('Data::SearchEngine::Solr'), 'Solr search engine');
-
-#t::lib::Mocks::mock_preference('SearchEngine', 'Zebra');
-#$se_index = Koha::SearchEngine::Search->new;
-#ok($se_index->searchengine->isa('Data::SearchEngine::Zebra'), 'Zebra search engine');
-
-
-done_testing;
+++ /dev/null
-use Test::More;
-
-use t::lib::Mocks;
-
-t::lib::Mocks::mock_preference('SearchEngine', 'Solr');
-use Koha::SearchEngine::Search;
-my $search_service = Koha::SearchEngine::Search->new;
-isnt (scalar $search_service->search("fort"), 0, 'test search') ;
-
-#$search_service->search($query_service->build_query(@,@,@));
-
-done_testing;
+++ /dev/null
-use Test::More;
-use FindBin qw($Bin);
-
-use t::lib::::Mocks;
-
-use Koha::SearchEngine::Index;
-
-t::lib::Mocks::mock_preference('SearchEngine', 'Solr');
-my $index_service = Koha::SearchEngine::Index->new;
-system( qq{/bin/cp $FindBin::Bin/../indexes.yaml /tmp/indexes.yaml} );
-$index_service->searchengine->config->set_config_filename( "/tmp/indexes.yaml" );
-is ($index_service->index_record("biblio", [2]), 1, 'test search') ;
-is ($index_service->optimize, 1, 'test search') ;
-
-done_testing;
+++ /dev/null
-use Modern::Perl;
-use Test::More;
-use C4::Context;
-
-use Koha::SearchEngine;
-use Koha::SearchEngine::QueryBuilder;
-use t::lib::Mocks;
-
-my $titleindex = "title";
-my $authorindex = "author";
-#my $eanindex = "str_ean";
-#my $pubdateindex = "date_pubdate";
-
-my ($operands, $indexes, $operators);
-
-
-# === Solr part ===
-@$operands = ('cup', 'rowling');
-@$indexes = ('ti', 'au');
-@$operators = ('AND');
-
-t::lib::Mocks::mock_preference('SearchEngine', 'Solr');
-my $qs = Koha::SearchEngine::QueryBuilder->new;
-
-my $se = Koha::SearchEngine->new;
-is( $se->name, "Solr", "Test searchengine name eq Solr" );
-
-my $gotsolr = $qs->build_advanced_query($indexes, $operands, $operators);
-my $expectedsolr = "ti:cup AND au:rowling";
-is($gotsolr, $expectedsolr, "Test build_query Solr");
-
-
-# === Zebra part ===
-t::lib::Mocks::mock_preference('SearchEngine', 'Zebra');
-$se = Koha::SearchEngine->new;
-is( $se->name, "Zebra", "Test searchengine name eq Zebra" );
-$qs = Koha::SearchEngine::QueryBuilder->new;
-my ( $builterror, $builtquery, $simple_query, $query_cgi, $query_desc, $limit, $limit_cgi, $limit_desc, $stopwords_removed, $query_type ) = $qs->build_query($operators, $operands, $indexes);
-my $gotzebra = $builtquery;
-my $expectedzebra = qq{ti,wrdl= cup AND au,wrdl= rowling };
-is($gotzebra, $expectedzebra, "Test Zebra indexes in 'normal' search");
-
-
-done_testing;
+++ /dev/null
-use Modern::Perl;
-use Test::More;
-use FindBin qw($Bin);
-
-use C4::Context;
-use Koha::SearchEngine;
-use t::lib::Mocks;
-
-t::lib::Mocks::mock_preference('SearchEngine', 'Solr');
-my $se = Koha::SearchEngine->new;
-is( $se->name, "Solr", "Test searchengine name eq Solr" );
-
-my $config = $se->config;
-$config->set_config_filename( "$FindBin::Bin/../indexes.yaml" );
-my $ressource_types = $config->ressource_types;
-is ( grep ( /^biblio$/, @$ressource_types ), 1, "Ressource type biblio must to be defined" );
-is ( grep ( /^authority$/, @$ressource_types ), 1, "Ressource type authority must to be defined" );
-
-my $indexes = $config->indexes;
-is ( scalar(@$indexes), 3, "There are 3 indexes configured" );
-
-my $index1 = @$indexes[0];
-is ( $index1->{code}, 'title', "My index first have code=title");
-is ( $index1->{label}, 'Title', "My index first have label=Title");
-is ( $index1->{type}, 'ste', "My index first have type=ste");
-is ( $index1->{ressource_type}, 'biblio', "My index first have ressource_type=biblio");
-is ( $index1->{sortable}, '1', "My index first have sortable=1");
-is ( $index1->{mandatory}, '1', "My index first have mandatory=1");
-eq_array ( $index1->{mappings}, ["200\$a", "4..\$t"], "My first index have mappings=[200\$a,4..\$t]");
-
-system( qq{/bin/cp $FindBin::Bin/../indexes.yaml /tmp/indexes.yaml} );
-$config->set_config_filename( "/tmp/indexes.yaml" );
-$indexes = $config->indexes;
-my $new_index = {
- code => 'isbn',
- label => 'ISBN',
- type => 'str',
- ressource_type => 'biblio',
- sortable => 0,
- mandatory => 0
-};
-push @$indexes, $new_index;
-$config->indexes( $indexes );
-
-$indexes = $config->indexes;
-
-my $isbn_index = $config->index( 'isbn' );
-is( $isbn_index->{code}, 'isbn', 'Index isbn has been written' );
-
-my $sortable_indexes = $config->sortable_indexes;
-is ( @$sortable_indexes, 2, "There are 2 sortable indexes" );
-
-done_testing;
+++ /dev/null
-ressource_types:
- - biblio
- - authority
-
-indexes:
- - code: title
- label: Title
- type: ste
- ressource_type: biblio
- sortable: 1
- mandatory: 1
- mappings:
- - 200$a
- - 210$a
- - 4..$t
- - code: author
- label: Author
- type: str
- ressource_type: biblio
- sortable: 1
- mandatory: 0
- mappings:
- - 700$*
- - 710$*
- - code: subject
- label: Subject
- type: str
- ressource_type: biblio
- sortable: 0
- mandatory: 0
- mappings:
- - 600$a
- - 601$a