1 package Koha
::QueryParser
::Driver
::PQF
;
3 # This file is part of Koha.
5 # Copyright 2012 C & P Bibliography Services
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use base
qw(OpenILS::QueryParser Class::Accessor);
25 use Module
::Load
::Conditional
qw(can_load);
26 use Koha
::QueryParser
::Driver
::PQF
::Util
;
27 use Koha
::QueryParser
::Driver
::PQF
::query_plan
;
28 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::facet
;
29 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::filter
;
30 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::modifier
;
31 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::node
;
32 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::node
::atom
;
33 use Koha
::QueryParser
::Driver
::PQF
::query_plan
::node
::atom
;
38 Koha::QueryParser::Driver::PQF - QueryParser driver for PQF
42 use Koha::QueryParser::Driver::PQF;
43 my $QParser = Koha::QueryParser::Driver::PQF->new(%args);
47 Main entrypoint into the QueryParser PQF driver. PQF is the Prefix Query
48 Language, the syntax used to serialize Z39.50 queries.
52 In order to simplify Bib-1 attribute mapping, this driver uses Class::Accessor
53 for accessing the following maps:
57 =item B<bib1_field_map> - search class/field Bib-1 mappings
59 =item B<bib1_modifier_map> - search modifier mappings
61 =item B<bib1_filter_map> - search filter mappings
63 =item B<bib1_relevance_bump_map> - relevance bump mappings
69 __PACKAGE__
->mk_accessors(qw(bib1_field_map bib1_modifier_map bib1_filter_map bib1_relevance_bump_map));
77 Overridden accessor method for Class::Accessor. (Do not call directly)
83 return $self->_map(@_);
88 Overridden mutator method for Class::Accessor. (Do not call directly)
94 return $self->_map(@_);
97 =head2 add_bib1_field_map
99 $QParser->add_bib1_field_map($class => $field => $server => \%attributes);
101 $QParser->add_bib1_field_map('author' => 'personal' => 'biblioserver' =>
104 Adds a search field<->bib1 attribute mapping for the specified server. The
105 %attributes hash contains maps Bib-1 Attributes to the appropropriate
106 values. Not all attributes must be specified.
110 sub add_bib1_field_map
{
111 my ($self, $class, $field, $server, $attributes) = @_;
113 $self->add_search_field( $class => $field );
114 return $self->_add_field_mapping($self->bib1_field_map, $class, $field, $server, $attributes);
117 =head2 add_bib1_modifier_map
119 $QParser->add_bib1_modifier_map($name => $server => \%attributes);
121 $QParser->add_bib1_modifier_map('ascending' => 'biblioserver' =>
124 Adds a search modifier<->bib1 attribute mapping for the specified server. The
125 %attributes hash contains maps Bib-1 Attributes to the appropropriate
126 values. Not all attributes must be specified.
130 sub add_bib1_modifier_map
{
131 my ($self, $name, $server, $attributes) = @_;
133 $self->add_search_modifier( $name );
135 return $self->_add_mapping($self->bib1_modifier_map, $name, $server, $attributes);
138 =head2 add_bib1_filter_map
140 $QParser->add_bib1_filter_map($name => $server => \%attributes);
142 $QParser->add_bib1_filter_map('date' => 'biblioserver' =>
143 { 'callback' => &_my_callback });
145 Adds a search filter<->bib1 attribute mapping for the specified server. The
146 %attributes hash maps Bib-1 Attributes to the appropropriate values and
147 provides a callback for the filter. Not all attributes must be specified.
151 sub add_bib1_filter_map
{
152 my ($self, $name, $server, $attributes) = @_;
154 $self->add_search_filter( $name, $attributes->{'callback'} );
156 return $self->_add_mapping($self->bib1_filter_map, $name, $server, $attributes);
159 =head2 add_relevance_bump
161 $QParser->add_relevance_bump($class, $field, $server, $multiplier, $active);
162 $QParser->add_relevance_bump('title' => 'exact' => 'biblioserver' => 34, 1);
164 Add a relevance bump to the specified field. When searching for a class without
165 any fields, all the relevance bumps for the specified class will be 'OR'ed
170 sub add_relevance_bump
{
171 my ($self, $class, $field, $server, $multiplier, $active) = @_;
172 my $attributes = { '9' => $multiplier, '2' => '102', 'active' => $active };
174 $self->add_search_field( $class => $field );
175 return $self->_add_field_mapping($self->bib1_relevance_bump_map, $class, $field, $server, $attributes);
181 my $pqf = $QParser->target_syntax($server, [$query]);
182 my $pqf = $QParser->target_syntax('biblioserver', 'author|personal:smith');
183 print $pqf; # assuming all the indexes are configured,
184 # prints '@attr 1=1003 @attr 4=6 "smith"'
186 Transforms the current or specified query into a PQF query string for the
192 my ($self, $server, $query) = @_;
194 $self->parse($query) if $query;
195 warn "QP query for $server: " . $self->query . "\n" if $self->debug;
196 $pqf = $self->parse_tree->target_syntax($server);
197 warn "PQF query: $pqf\n" if $self->debug;
204 =head2 date_filter_target_callback
206 $QParser->add_bib1_filter_map($server, { 'target_syntax_callback' => \&Koha::QueryParser::Driver::PQF::date_filter_target_callback, '1' => 'pubdate' });
208 Callback for date filters. Note that although the first argument is the QParser
209 object, this is technically not an object-oriented routine. This has no
210 real-world implications.
214 sub date_filter_target_callback
{
215 my ($QParser, $filter, $params, $negate, $server) = @_;
216 my $attr_string = $QParser->bib1_mapping_by_name( 'filter', $filter, $server )->{'attr_string'};
218 foreach my $datespec (@
$params) {
221 if ($datespec =~ m/(.*)-(.*)/) {
223 $datepqf .= $attr_string . ' @attr 2=4 "' . $1 . '"';
226 $datepqf .= $attr_string . ' @attr 2=2 "' . $2 . '"';
227 $datepqf = ' @and ' . $datepqf if $1;
230 $datepqf .= $attr_string . ' "' . $datespec . '"';
233 $pqf = ' @or ' . ($negate ?
'@not @attr 1=_ALLRECORDS @attr 2=103 "" ' : '') . $pqf if $pqf;
241 return $self->_map('bib1_field_map', $map);
243 Retrieves or sets a map.
248 my ($self, $name, $map) = @_;
249 $self->custom_data->{$name} ||= {};
250 $self->custom_data->{$name} = $map if ($map);
251 return $self->custom_data->{$name};
256 return $self->_add_mapping($map, $name, $server, $attributes)
258 Adds a mapping. Note that this is not used for mappings relating to fields.
263 my ($self, $map, $name, $server, $attributes) = @_;
265 my $attr_string = Koha
::QueryParser
::Driver
::PQF
::Util
::attributes_to_attr_string
($attributes);
266 $attributes->{'attr_string'} = $attr_string;
268 $map->{'by_name'}{$name}{$server} = $attributes;
269 $map->{'by_attr'}{$server}{$attr_string} = { 'name' => $name, %$attributes };
274 =head2 _add_field_mapping
276 return $self->_add_field_mapping($map, $class, $field, $server, $attributes)
278 Adds a mapping for field-related data.
282 sub _add_field_mapping
{
283 my ($self, $map, $class, $field, $server, $attributes) = @_;
284 my $attr_string = Koha
::QueryParser
::Driver
::PQF
::Util
::attributes_to_attr_string
($attributes);
285 $attributes->{'attr_string'} = $attr_string;
287 $map->{'by_name'}{$class}{$field}{$server} = $attributes;
288 $map->{'by_attr'}{$server}{$attr_string} = { 'classname' => $class, 'field' => $field, %$attributes };
293 =head2 bib1_mapping_by_name
295 my $attributes = $QParser->bib1_mapping_by_name($type, $name[, $subname], $server);
296 my $attributes = $QParser->bib1_mapping_by_name('field', 'author', 'personal', 'biblioserver');
297 my $attributes = $QParser->bib1_mapping_by_name('filter', 'pubdate', 'biblioserver');
299 Retrieve the Bib-1 attribute set associated with the specified mapping.
302 sub bib1_mapping_by_name
{
304 my ($self, $type, $name, $field) = @_;
306 return unless ($server && $name);
307 return unless ($type eq 'field' || $type eq 'modifier' || $type eq 'filter' || $type eq 'relevance_bump');
308 if ($type eq 'field' || $type eq 'relevance_bump') {
309 # Unfortunately field is a special case thanks to the class->field hierarchy
310 return $self->_map('bib1_' . $type . '_map')->{'by_name'}{$name}{$field}{$server} if $field;
311 return $self->_map('bib1_' . $type . '_map')->{'by_name'}{$name};
313 return $self->_map('bib1_' . $type . '_map')->{'by_name'}{$name}{$server};
317 =head2 bib1_mapping_by_attr
319 my $field = $QParser->bib1_mapping_by_attr($type, $server, \%attr);
320 my $field = $QParser->bib1_mapping_by_attr('field', 'biblioserver', {'1' => '1004'});
321 print $field->{'classname'}; # prints "author"
322 print $field->{'field'}; # prints "personal"
324 Retrieve the search field/modifier/filter used for the specified Bib-1 attribute set.
328 sub bib1_mapping_by_attr
{
329 my ($self, $type, $server, $attributes) = @_;
330 return unless ($server && $attributes);
332 my $attr_string = Koha
::QueryParser
::Driver
::PQF
::Util
::attributes_to_attr_string
($attributes);
334 return $self->bib1_mapping_by_attr_string($type, $server, $attr_string);
337 =head2 bib1_mapping_by_attr_string
339 my $field = $QParser->bib1_mapping_by_attr_string($type, $server, $attr_string);
340 my $field = $QParser->bib1_mapping_by_attr_string('field', 'biblioserver', '@attr 1=1004');
341 print $field->{'classname'}; # prints "author"
342 print $field->{'field'}; # prints "personal"
344 Retrieve the search field/modifier/filter used for the specified Bib-1 attribute string
349 sub bib1_mapping_by_attr_string
{
350 my ($self, $type, $server, $attr_string) = @_;
351 return unless ($server && $attr_string);
352 return unless ($type eq 'field' || $type eq 'modifier' || $type eq 'filter' || $type eq 'relevance_bump');
354 return $self->_map('bib1_' . $type . '_map')->{'by_attr'}{$server}{$attr_string};
357 =head2 clear_all_configuration
359 $QParser->clear_all_configuration
361 Clear all configuration. This is a highly destructive method. You may
366 sub clear_all_configuration
{
368 %OpenILS::QueryParser
::parser_config
= (
369 'OpenILS::QueryParser' => {
389 =head2 clear_all_mappings
391 $QParser->clear_all_mappings
393 Clear all bib-1 mappings.
397 sub clear_all_mappings
{
400 foreach my $name (qw(field modifier filter relevance_bump)) {
401 $self->custom_data->{'bib1_' . $name . '_map'} = { };
407 =head2 _canonicalize_field_map
409 Convert a field map into its canonical form for serialization. Used only for
410 fields and relevance bumps.
414 sub _canonicalize_field_map
{
415 my ( $map, $aliases ) = @_;
416 my $canonical_map = {};
418 foreach my $class ( keys %{ $map->{'by_name'} } ) {
419 $canonical_map->{$class} ||= {};
420 foreach my $field ( keys %{ $map->{'by_name'}->{$class} } ) {
423 'label' => ucfirst($field),
427 my $server ( keys %{ $map->{'by_name'}->{$class}->{$field} } )
429 $field_map->{'bib1_mapping'} ||= {};
430 $field_map->{'bib1_mapping'}->{$server} =
431 $map->{'by_name'}->{$class}->{$field}->{$server};
432 delete $field_map->{'bib1_mapping'}->{$server}->{'attr_string'}
434 $field_map->{'bib1_mapping'}->{$server}
439 $field_map->{'aliases'} = [];
440 foreach my $alias ( @
{ $aliases->{$class}->{$field} } ) {
441 push @
{ $field_map->{'aliases'} },
445 $canonical_map->{$class}->{$field} = $field_map;
448 return $canonical_map;
451 =head2 _canonicalize_map
453 Convert a map into its canonical form for serialization. Not used for fields.
457 sub _canonicalize_map
{
459 my $canonical_map = {};
461 foreach my $name ( keys %{ $map->{'by_name'} } ) {
462 $canonical_map->{$name} = {
463 'label' => ucfirst($name),
467 foreach my $server ( keys %{ $map->{'by_name'}->{$name} } ) {
468 $canonical_map->{$name}->{'bib1_mapping'}->{$server} =
469 $map->{'by_name'}->{$name}->{$server};
470 delete $canonical_map->{$name}->{'bib1_mapping'}->{$server}
473 $canonical_map->{$name}->{'bib1_mapping'}->{$server}
478 return $canonical_map;
481 =head2 serialize_mappings
483 my $yaml = $QParser->serialize_mappings;
484 my $json = $QParser->serialize_mappings('json');
486 Serialize Bib-1 mappings to YAML or JSON.
490 sub serialize_mappings
{
491 my ( $self, $format ) = @_;
495 $config->{'field_mappings'} =
496 _canonicalize_field_map
( $self->bib1_field_map,
497 $self->search_field_aliases );
498 $config->{'modifier_mappings'} =
499 _canonicalize_map
( $self->bib1_modifier_map );
500 $config->{'filter_mappings'} = _canonicalize_map
( $self->bib1_filter_map );
501 $config->{'relevance_bumps'} =
502 _canonicalize_field_map
( $self->bib1_relevance_bump_map );
504 if ( $format eq 'json' && can_load
( modules
=> { 'JSON' => undef } ) ) {
505 return JSON
::to_json
($config);
507 elsif ( can_load
( modules
=> { 'YAML::Any' => undef } ) ) {
508 return YAML
::Any
::Dump
($config);
515 $QParser->initialize( { 'bib1_field_mappings' => \%bib1_field_mappings,
516 'search_field_alias_mappings' => \%search_field_alias_mappings,
517 'bib1_modifier_mappings' => \%bib1_modifier_mappings,
518 'bib1_filter_mappings' => \%bib1_filter_mappings,
519 'relevance_bumps' => \%relevance_bumps });
521 Initialize the QueryParser mapping tables based on the provided configuration.
522 This method was written to play nice with YAML configuration files loaded by load_config.
527 my ( $self, $args ) = @_;
529 my $field_mappings = $args->{'field_mappings'};
530 my $modifier_mappings = $args->{'modifier_mappings'};
531 my $filter_mappings = $args->{'filter_mappings'};
532 my $relbumps = $args->{'relevance_bumps'};
533 my ( $server, $bib1_mapping );
534 foreach my $class ( keys %$field_mappings ) {
535 foreach my $field ( keys %{ $field_mappings->{$class} } ) {
536 if ( $field_mappings->{$class}->{$field}->{'enabled'} ) {
537 while ( ( $server, $bib1_mapping ) =
539 %{ $field_mappings->{$class}->{$field}->{'bib1_mapping'} } )
541 $self->add_bib1_field_map(
542 $class => $field => $server => $bib1_mapping );
545 @
{ $field_mappings->{$class}->{$field}->{'aliases'} } )
547 $self->add_search_field_alias( $class => $field => $alias );
552 foreach my $modifier ( keys %$modifier_mappings ) {
553 if ( $modifier_mappings->{$modifier}->{'enabled'} ) {
554 while ( ( $server, $bib1_mapping ) =
555 each %{ $modifier_mappings->{$modifier}->{'bib1_mapping'} } )
557 $self->add_bib1_modifier_map(
558 $modifier => $server => $bib1_mapping );
562 foreach my $filter ( keys %$filter_mappings ) {
563 if ( $filter_mappings->{$filter}->{'enabled'} ) {
564 while ( ( $server, $bib1_mapping ) =
565 each %{ $filter_mappings->{$filter}->{'bib1_mapping'} } )
567 if ( $bib1_mapping->{'target_syntax_callback'} eq
568 'date_filter_target_callback' )
570 $bib1_mapping->{'target_syntax_callback'} =
571 \
&Koha
::QueryParser
::Driver
::PQF
::date_filter_target_callback
;
573 $self->add_bib1_filter_map(
574 $filter => $server => $bib1_mapping );
578 foreach my $class ( keys %$relbumps ) {
579 foreach my $field ( keys %{ $relbumps->{$class} } ) {
580 if ( $relbumps->{$class}->{$field}->{'enabled'} ) {
581 while ( ( $server, $bib1_mapping ) =
582 each %{ $relbumps->{$class}->{$field}->{'bib1_mapping'} } )
584 $self->add_relevance_bump(
585 $class => $field => $server => $bib1_mapping,
597 $QParser->load_config($file_name);
599 Load a YAML file with a parser configuration. The YAML file should match the following format:
627 1: Date-of-acquisition
629 target_syntax_callback: date_filter_target_callback
647 my ($self, $file) = @_;
649 return unless ($file && -f
$file);
650 my $config = YAML
::Any
::LoadFile
($file);
651 return unless ($config);
652 $self->initialize($config);
660 This routine initializes the QueryParser driver with a reasonable set of
661 defaults. This is intended only for testing. Although such test stubs are
662 generally not included in Koha, this type of test stub is used by other
663 QueryParser implementations, and it seems sensible to maintain consistency
671 $self->default_search_class( 'keyword' );
673 $self->add_bib1_field_map('keyword' => 'abstract' => 'biblioserver' => { '1' => '62' } );
674 $self->add_search_field_alias( 'keyword' => 'abstract' => 'ab' );
675 $self->add_bib1_field_map('keyword' => '' => 'biblioserver' => { '1' => '1016' } );
676 $self->add_search_field_alias( 'keyword' => '' => 'kw' );
677 $self->add_bib1_field_map('author' => '' => 'biblioserver' => { '1' => '1003' } );
678 $self->add_search_field_alias( 'author' => '' => 'au' );
679 $self->add_bib1_field_map('author' => 'personal' => 'biblioserver' => { '1' => '1004' } );
680 $self->add_bib1_field_map('author' => 'corporate' => 'biblioserver' => { '1' => '1005' } );
681 $self->add_search_field_alias( 'author' => 'corporate' => 'cpn' );
682 $self->add_bib1_field_map('author' => 'conference' => 'biblioserver' => { '1' => '1006' } );
683 $self->add_search_field_alias( 'author' => 'conference' => 'cfn' );
684 $self->add_bib1_field_map('keyword' => 'local-classification' => 'biblioserver' => { '1' => '20' } );
685 $self->add_search_field_alias( 'keyword' => 'local-classification' => 'lcn' );
686 $self->add_search_field_alias( 'keyword' => 'local-classification' => 'callnum' );
687 $self->add_bib1_field_map('keyword' => 'bib-level' => 'biblioserver' => { '1' => '1021' } );
688 $self->add_bib1_field_map('keyword' => 'code-institution' => 'biblioserver' => { '1' => '56' } );
689 $self->add_bib1_field_map('keyword' => 'language' => 'biblioserver' => { '1' => '54' } );
690 $self->add_search_field_alias( 'keyword' => 'language' => 'ln' );
691 $self->add_bib1_field_map('keyword' => 'record-type' => 'biblioserver' => { '1' => '1001' } );
692 $self->add_search_field_alias( 'keyword' => 'record-type' => 'rtype' );
693 $self->add_search_field_alias( 'keyword' => 'record-type' => 'mc-rtype' );
694 $self->add_search_field_alias( 'keyword' => 'record-type' => 'mus' );
695 $self->add_bib1_field_map('keyword' => 'content-type' => 'biblioserver' => { '1' => '1034' } );
696 $self->add_search_field_alias( 'keyword' => 'content-type' => 'ctype' );
697 $self->add_bib1_field_map('keyword' => 'lc-card-number' => 'biblioserver' => { '1' => '9' } );
698 $self->add_search_field_alias( 'keyword' => 'lc-card-number' => 'lc-card' );
699 $self->add_bib1_field_map('keyword' => 'local-number' => 'biblioserver' => { '1' => '12' } );
700 $self->add_search_field_alias( 'keyword' => 'local-number' => 'sn' );
701 $self->add_bib1_filter_map( 'biblioserver', 'copydate', { 'target_syntax_callback' => \
&Koha
::QueryParser
::Driver
::PQF
::date_filter_target_callback
, '1' => '30', '4' => '4' });
702 $self->add_bib1_filter_map( 'biblioserver', 'pubdate', { 'target_syntax_callback' => \
&Koha
::QueryParser
::Driver
::PQF
::date_filter_target_callback
, '1' => 'pubdate', '4' => '4' });
703 $self->add_bib1_filter_map( 'biblioserver', 'acqdate', { 'target_syntax_callback' => \
&Koha
::QueryParser
::Driver
::PQF
::date_filter_target_callback
, '1' => 'Date-of-acquisition', '4' => '4' });
704 $self->add_bib1_field_map('keyword' => 'isbn' => 'biblioserver' => { '1' => '7' } );
705 $self->add_search_field_alias( 'keyword' => 'isbn' => 'nb' );
706 $self->add_bib1_field_map('keyword' => 'issn' => 'biblioserver' => { '1' => '8' } );
707 $self->add_search_field_alias( 'keyword' => 'issn' => 'ns' );
708 $self->add_bib1_field_map('keyword' => 'identifier-standard' => 'biblioserver' => { '1' => '1007' } );
709 $self->add_search_field_alias( 'keyword' => 'identifier-standard' => 'ident' );
710 $self->add_bib1_field_map('keyword' => 'upc' => 'biblioserver' => { '1' => 'UPC' } );
711 $self->add_search_field_alias( 'keyword' => 'upc' => 'upc' );
712 $self->add_bib1_field_map('keyword' => 'ean' => 'biblioserver' => { '1' => 'EAN' } );
713 $self->add_search_field_alias( 'keyword' => 'ean' => 'ean' );
714 $self->add_bib1_field_map('keyword' => 'music' => 'biblioserver' => { '1' => 'Music-number' } );
715 $self->add_search_field_alias( 'keyword' => 'music' => 'music' );
716 $self->add_bib1_field_map('keyword' => 'stock-number' => 'biblioserver' => { '1' => '1028' } );
717 $self->add_search_field_alias( 'keyword' => 'stock-number' => 'stock-number' );
718 $self->add_bib1_field_map('keyword' => 'material-type' => 'biblioserver' => { '1' => '1031' } );
719 $self->add_search_field_alias( 'keyword' => 'material-type' => 'material-type' );
720 $self->add_bib1_field_map('keyword' => 'place-publication' => 'biblioserver' => { '1' => '59' } );
721 $self->add_search_field_alias( 'keyword' => 'place-publication' => 'pl' );
722 $self->add_bib1_field_map('keyword' => 'personal-name' => 'biblioserver' => { '1' => 'Personal-name' } );
723 $self->add_search_field_alias( 'keyword' => 'personal-name' => 'pn' );
724 $self->add_bib1_field_map('keyword' => 'publisher' => 'biblioserver' => { '1' => '1018' } );
725 $self->add_search_field_alias( 'keyword' => 'publisher' => 'pb' );
726 $self->add_bib1_field_map('keyword' => 'note' => 'biblioserver' => { '1' => '63' } );
727 $self->add_search_field_alias( 'keyword' => 'note' => 'nt' );
728 $self->add_bib1_field_map('keyword' => 'record-control-number' => 'biblioserver' => { '1' => '1045' } );
729 $self->add_search_field_alias( 'keyword' => 'record-control-number' => 'rcn' );
730 $self->add_bib1_field_map('subject' => '' => 'biblioserver' => { '1' => '21' } );
731 $self->add_search_field_alias( 'subject' => '' => 'su' );
732 $self->add_search_field_alias( 'subject' => '' => 'su-to' );
733 $self->add_search_field_alias( 'subject' => '' => 'su-geo' );
734 $self->add_search_field_alias( 'subject' => '' => 'su-ut' );
735 $self->add_bib1_field_map('subject' => 'name-personal' => 'biblioserver' => { '1' => '1009' } );
736 $self->add_search_field_alias( 'subject' => 'name-personal' => 'su-na' );
737 $self->add_bib1_field_map('title' => '' => 'biblioserver' => { '1' => '4' } );
738 $self->add_search_field_alias( 'title' => '' => 'ti' );
739 $self->add_bib1_field_map('title' => 'cover' => 'biblioserver' => { '1' => '36' } );
740 $self->add_search_field_alias( 'title' => 'cover' => 'title-cover' );
741 $self->add_bib1_field_map('keyword' => 'host-item' => 'biblioserver' => { '1' => '1033' } );
742 $self->add_bib1_field_map('keyword' => 'video-mt' => 'biblioserver' => { '1' => 'Video-mt' } );
743 $self->add_bib1_field_map('keyword' => 'graphics-type' => 'biblioserver' => { '1' => 'Graphic-type' } );
744 $self->add_bib1_field_map('keyword' => 'graphics-support' => 'biblioserver' => { '1' => 'Graphic-support' } );
745 $self->add_bib1_field_map('keyword' => 'type-of-serial' => 'biblioserver' => { '1' => 'Type-Of-Serial' } );
746 $self->add_bib1_field_map('keyword' => 'regularity-code' => 'biblioserver' => { '1' => 'Regularity-code' } );
747 $self->add_bib1_field_map('keyword' => 'material-type' => 'biblioserver' => { '1' => 'Material-type' } );
748 $self->add_bib1_field_map('keyword' => 'literature-code' => 'biblioserver' => { '1' => 'Literature-Code' } );
749 $self->add_bib1_field_map('keyword' => 'biography-code' => 'biblioserver' => { '1' => 'Biography-code' } );
750 $self->add_bib1_field_map('keyword' => 'illustration-code' => 'biblioserver' => { '1' => 'Illustration-code' } );
751 $self->add_bib1_field_map('title' => 'series' => 'biblioserver' => { '1' => '5' } );
752 $self->add_search_field_alias( 'title' => 'series' => 'title-series' );
753 $self->add_search_field_alias( 'title' => 'series' => 'se' );
754 $self->add_bib1_field_map('title' => 'uniform' => 'biblioserver' => { '1' => 'Title-uniform' } );
755 $self->add_search_field_alias( 'title' => 'uniform' => 'title-uniform' );
756 $self->add_bib1_field_map('subject' => 'authority-number' => 'biblioserver' => { '1' => 'Koha-Auth-Number' } );
757 $self->add_search_field_alias( 'subject' => 'authority-number' => 'an' );
758 $self->add_bib1_field_map('keyword' => 'control-number' => 'biblioserver' => { '1' => '9001' } );
759 $self->add_bib1_field_map('keyword' => 'biblionumber' => 'biblioserver' => { '1' => '9002', '5' => '100' } );
760 $self->add_bib1_field_map('keyword' => 'totalissues' => 'biblioserver' => { '1' => '9003' } );
761 $self->add_bib1_field_map('keyword' => 'cn-bib-source' => 'biblioserver' => { '1' => '9004' } );
762 $self->add_bib1_field_map('keyword' => 'cn-bib-sort' => 'biblioserver' => { '1' => '9005' } );
763 $self->add_bib1_field_map('keyword' => 'itemtype' => 'biblioserver' => { '1' => '9006' } );
764 $self->add_search_field_alias( 'keyword' => 'itemtype' => 'mc-itemtype' );
765 $self->add_bib1_field_map('keyword' => 'cn-class' => 'biblioserver' => { '1' => '9007' } );
766 $self->add_bib1_field_map('keyword' => 'cn-item' => 'biblioserver' => { '1' => '9008' } );
767 $self->add_bib1_field_map('keyword' => 'cn-prefix' => 'biblioserver' => { '1' => '9009' } );
768 $self->add_bib1_field_map('keyword' => 'cn-suffix' => 'biblioserver' => { '1' => '9010' } );
769 $self->add_bib1_field_map('keyword' => 'suppress' => 'biblioserver' => { '1' => '9011' } );
770 $self->add_bib1_field_map('keyword' => 'id-other' => 'biblioserver' => { '1' => '9012' } );
771 $self->add_bib1_field_map('keyword' => 'date-entered-on-file' => 'biblioserver' => { '1' => 'date-entered-on-file' } );
772 $self->add_bib1_field_map('keyword' => 'extent' => 'biblioserver' => { '1' => 'Extent' } );
773 $self->add_bib1_field_map('keyword' => 'llength' => 'biblioserver' => { '1' => 'llength' } );
774 $self->add_bib1_field_map('keyword' => 'summary' => 'biblioserver' => { '1' => 'Summary' } );
775 $self->add_bib1_field_map('keyword' => 'withdrawn' => 'biblioserver' => { '1' => '8001' } );
776 $self->add_bib1_field_map('keyword' => 'lost' => 'biblioserver' => { '1' => '8002' } );
777 $self->add_bib1_field_map('keyword' => 'classification-source' => 'biblioserver' => { '1' => '8003' } );
778 $self->add_bib1_field_map('keyword' => 'materials-specified' => 'biblioserver' => { '1' => '8004' } );
779 $self->add_bib1_field_map('keyword' => 'damaged' => 'biblioserver' => { '1' => '8005' } );
780 $self->add_bib1_field_map('keyword' => 'restricted' => 'biblioserver' => { '1' => '8006' } );
781 $self->add_bib1_field_map('keyword' => 'cn-sort' => 'biblioserver' => { '1' => '8007' } );
782 $self->add_bib1_field_map('keyword' => 'notforloan' => 'biblioserver' => { '1' => '8008', '4' => '109' } );
783 $self->add_bib1_field_map('keyword' => 'ccode' => 'biblioserver' => { '1' => '8009' } );
784 $self->add_search_field_alias( 'keyword' => 'ccode' => 'mc-ccode' );
785 $self->add_bib1_field_map('keyword' => 'itemnumber' => 'biblioserver' => { '1' => '8010' } );
786 $self->add_bib1_field_map('keyword' => 'homebranch' => 'biblioserver' => { '1' => 'homebranch' } );
787 $self->add_search_field_alias( 'keyword' => 'homebranch' => 'branch' );
788 $self->add_bib1_field_map('keyword' => 'holdingbranch' => 'biblioserver' => { '1' => '8012' } );
789 $self->add_bib1_field_map('keyword' => 'location' => 'biblioserver' => { '1' => '8013' } );
790 $self->add_search_field_alias( 'keyword' => 'location' => 'mc-loc' );
791 $self->add_bib1_field_map('keyword' => 'acqsource' => 'biblioserver' => { '1' => '8015' } );
792 $self->add_bib1_field_map('keyword' => 'coded-location-qualifier' => 'biblioserver' => { '1' => '8016' } );
793 $self->add_bib1_field_map('keyword' => 'price' => 'biblioserver' => { '1' => '8017' } );
794 $self->add_bib1_field_map('keyword' => 'stocknumber' => 'biblioserver' => { '1' => '1062' } );
795 $self->add_search_field_alias( 'keyword' => 'stocknumber' => 'inv' );
796 $self->add_bib1_field_map('keyword' => 'stack' => 'biblioserver' => { '1' => '8018' } );
797 $self->add_bib1_field_map('keyword' => 'issues' => 'biblioserver' => { '1' => '8019' } );
798 $self->add_bib1_field_map('keyword' => 'renewals' => 'biblioserver' => { '1' => '8020' } );
799 $self->add_bib1_field_map('keyword' => 'reserves' => 'biblioserver' => { '1' => '8021' } );
800 $self->add_bib1_field_map('keyword' => 'local-classification' => 'biblioserver' => { '1' => '8022' } );
801 $self->add_bib1_field_map('keyword' => 'barcode' => 'biblioserver' => { '1' => '8023' } );
802 $self->add_search_field_alias( 'keyword' => 'barcode' => 'bc' );
803 $self->add_bib1_field_map('keyword' => 'onloan' => 'biblioserver' => { '1' => '8024' } );
804 $self->add_bib1_field_map('keyword' => 'datelastseen' => 'biblioserver' => { '1' => '8025' } );
805 $self->add_bib1_field_map('keyword' => 'datelastborrowed' => 'biblioserver' => { '1' => '8026' } );
806 $self->add_bib1_field_map('keyword' => 'copynumber' => 'biblioserver' => { '1' => '8027' } );
807 $self->add_bib1_field_map('keyword' => 'uri' => 'biblioserver' => { '1' => '8028' } );
808 $self->add_bib1_field_map('keyword' => 'replacementprice' => 'biblioserver' => { '1' => '8029' } );
809 $self->add_bib1_field_map('keyword' => 'replacementpricedate' => 'biblioserver' => { '1' => '8030' } );
810 $self->add_bib1_field_map('keyword' => 'itype' => 'biblioserver' => { '1' => '8031' } );
811 $self->add_search_field_alias( 'keyword' => 'itype' => 'mc-itype' );
812 $self->add_bib1_field_map('keyword' => 'ff8-22' => 'biblioserver' => { '1' => '8822' } );
813 $self->add_bib1_field_map('keyword' => 'ff8-23' => 'biblioserver' => { '1' => '8823' } );
814 $self->add_bib1_field_map('keyword' => 'ff8-34' => 'biblioserver' => { '1' => '8834' } );
816 $self->add_bib1_field_map('keyword' => 'audience' => 'biblioserver' => { '1' => '8822' } );
817 $self->add_search_field_alias( 'keyword' => 'audience' => 'aud' );
819 # Content and Literary form
820 $self->add_bib1_field_map('keyword' => 'fiction' => 'biblioserver' => { '1' => '8833' } );
821 $self->add_search_field_alias( 'keyword' => 'fiction' => 'fic' );
822 $self->add_bib1_field_map('keyword' => 'biography' => 'biblioserver' => { '1' => '8834' } );
823 $self->add_search_field_alias( 'keyword' => 'biography' => 'bio' );
826 $self->add_bib1_field_map('keyword' => 'format' => 'biblioserver' => { '1' => '8823' } );
827 # format used as a limit FIXME: needed?
828 $self->add_bib1_field_map('keyword' => 'l-format' => 'biblioserver' => { '1' => '8703' } );
830 $self->add_bib1_field_map('keyword' => 'illustration-code' => 'biblioserver' => { '1' => 'Illustration-code ' } );
833 $self->add_bib1_field_map('keyword' => 'lex' => 'biblioserver' => { '1' => '9903 r=r' } );
835 #Accelerated Reader Level
836 $self->add_bib1_field_map('keyword' => 'arl' => 'biblioserver' => { '1' => '9904 r=r' } );
838 #Accelerated Reader Point
839 $self->add_bib1_field_map('keyword' => 'arp' => 'biblioserver' => { '1' => '9013 r=r' } );
842 $self->add_bib1_field_map('keyword' => 'curriculum' => 'biblioserver' => { '1' => '9658' } );
845 $self->add_bib1_field_map('keyword' => 'popularity' => 'biblioserver' => { '1' => 'issues' } );
848 $self->add_bib1_field_map('keyword' => 'dt-bks' => 'biblioserver' => { '1' => '8700' } );
849 $self->add_bib1_field_map('keyword' => 'dt-vis' => 'biblioserver' => { '1' => '8700' } );
850 $self->add_bib1_field_map('keyword' => 'dt-sr' => 'biblioserver' => { '1' => '8700' } );
851 $self->add_bib1_field_map('keyword' => 'dt-cf' => 'biblioserver' => { '1' => '8700' } );
852 $self->add_bib1_field_map('keyword' => 'dt-map' => 'biblioserver' => { '1' => '8700' } );
854 $self->add_bib1_field_map('keyword' => 'name' => 'biblioserver' => { '1' => '1002' } );
855 $self->add_bib1_field_map('keyword' => 'item' => 'biblioserver' => { '1' => '9520' } );
856 $self->add_bib1_field_map('keyword' => 'host-item-number' => 'biblioserver' => { '1' => '8911' } );
857 $self->add_search_field_alias( 'keyword' => 'host-item-number' => 'hi' );
859 $self->add_bib1_field_map('keyword' => 'alwaysmatch' => 'biblioserver' => { '1' => '_ALLRECORDS', '2' => '103' } );
860 $self->add_bib1_field_map('subject' => 'complete' => 'biblioserver' => { '1' => '21', '3' => '1', '4' => '1', '5' => '100', '6' => '3' } );
862 $self->add_bib1_modifier_map('relevance' => 'biblioserver' => { '2' => '102' } );
863 $self->add_bib1_modifier_map('title-sort-za' => 'biblioserver' => { '7' => '2', '1' => '36', '' => '0', 'op' => '@or' } );
864 $self->add_bib1_modifier_map('title-sort-az' => 'biblioserver' => { '7' => '1', '1' => '36', '' => '0', 'op' => '@or' } );
865 $self->add_bib1_modifier_map('relevance_dsc' => 'biblioserver' => { '2' => '102' } );
866 $self->add_bib1_modifier_map('title_dsc' => 'biblioserver' => { '7' => '2', '1' => '4', '' => '0', 'op' => '@or' } );
867 $self->add_bib1_modifier_map('title_asc' => 'biblioserver' => { '7' => '1', '1' => '4', '' => '0', 'op' => '@or' } );
868 $self->add_bib1_modifier_map('author_asc' => 'biblioserver' => { '7' => '2', '1' => '1003', '' => '0', 'op' => '@or' } );
869 $self->add_bib1_modifier_map('author_dsc' => 'biblioserver' => { '7' => '1', '1' => '1003', '' => '0', 'op' => '@or' } );
870 $self->add_bib1_modifier_map('popularity_asc' => 'biblioserver' => { '7' => '2', '1' => '9003', '' => '0', 'op' => '@or' } );
871 $self->add_bib1_modifier_map('popularity_dsc' => 'biblioserver' => { '7' => '1', '1' => '9003', '' => '0', 'op' => '@or' } );
872 $self->add_bib1_modifier_map('call_number_asc' => 'biblioserver' => { '7' => '2', '1' => '8007', '' => '0', 'op' => '@or' } );
873 $self->add_bib1_modifier_map('call_number_dsc' => 'biblioserver' => { '7' => '1', '1' => '8007', '' => '0', 'op' => '@or' } );
874 $self->add_bib1_modifier_map('pubdate_asc' => 'biblioserver' => { '7' => '2', '1' => '31', '' => '0', 'op' => '@or' } );
875 $self->add_bib1_modifier_map('pubdate_dsc' => 'biblioserver' => { '7' => '1', '1' => '31', '' => '0', 'op' => '@or' } );
876 $self->add_bib1_modifier_map('acqdate_asc' => 'biblioserver' => { '7' => '2', '1' => '32', '' => '0', 'op' => '@or' } );
877 $self->add_bib1_modifier_map('acqdate_dsc' => 'biblioserver' => { '7' => '1', '1' => '32', '' => '0', 'op' => '@or' } );
879 $self->add_bib1_modifier_map('title_za' => 'biblioserver' => { '7' => '2', '1' => '4', '' => '0', 'op' => '@or' } );
880 $self->add_bib1_modifier_map('title_az' => 'biblioserver' => { '7' => '1', '1' => '4', '' => '0', 'op' => '@or' } );
881 $self->add_bib1_modifier_map('author_za' => 'biblioserver' => { '7' => '2', '1' => '1003', '' => '0', 'op' => '@or' } );
882 $self->add_bib1_modifier_map('author_az' => 'biblioserver' => { '7' => '1', '1' => '1003', '' => '0', 'op' => '@or' } );
883 $self->add_bib1_modifier_map('ascending' => 'biblioserver' => { '7' => '1' } );
884 $self->add_bib1_modifier_map('descending' => 'biblioserver' => { '7' => '2' } );
886 $self->add_bib1_field_map('title' => 'exacttitle' => 'biblioserver' => { '1' => '4', '4' => '1', '6' => '3' } );
887 $self->add_search_field_alias( 'title' => 'exacttitle' => 'ti,ext' );
888 $self->add_bib1_field_map('author' => 'exactauthor' => 'biblioserver' => { '1' => '1003', '4' => '1', '6' => '3' } );
889 $self->add_search_field_alias( 'author' => 'exactauthor' => 'au,ext' );
891 $self->add_bib1_field_map('subject' => 'headingmain' => 'authorityserver' => { '1' => 'Heading-Main' } );
892 $self->add_bib1_field_map('subject' => 'heading' => 'authorityserver' => { '1' => 'Heading' } );
893 $self->add_bib1_field_map('subject' => 'matchheading' => 'authorityserver' => { '1' => 'Match-heading' } );
894 $self->add_bib1_field_map('subject' => 'seefrom' => 'authorityserver' => { '1' => 'Match-heading-see-from' } );
895 $self->add_bib1_field_map('subject' => '' => 'authorityserver' => { '1' => 'Match-heading' } );
896 $self->add_bib1_field_map('keyword' => 'alwaysmatch' => 'authorityserver' => { '1' => '_ALLRECORDS', '2' => '103' } );
897 $self->add_bib1_field_map('keyword' => 'match' => 'authorityserver' => { '1' => 'Match' } );
898 $self->add_bib1_field_map('keyword' => 'thesaurus' => 'authorityserver' => { '1' => 'Subject-heading-thesaurus' } );
899 $self->add_bib1_field_map('keyword' => 'authtype' => 'authorityserver' => { '1' => 'authtype', '5' => '100' } );
900 $self->add_bib1_field_map('keyword' => '' => 'authorityserver' => { '1' => 'Any' } );
901 $self->add_search_field_alias( 'subject' => 'headingmain' => 'mainmainentry' );
902 $self->add_search_field_alias( 'subject' => 'heading' => 'mainentry' );
903 $self->add_search_field_alias( 'subject' => 'heading' => 'he' );
904 $self->add_search_field_alias( 'subject' => 'matchheading' => 'match-heading' );
905 $self->add_search_field_alias( 'keyword' => '' => 'any' );
906 $self->add_search_field_alias( 'keyword' => 'match' => 'match' );
907 $self->add_search_field_alias( 'subject' => 'seefrom' => 'see-from' );
908 $self->add_search_field_alias( 'keyword' => 'thesaurus' => 'thesaurus' );
909 $self->add_search_field_alias( 'keyword' => 'alwaysmatch' => 'all' );
910 $self->add_search_field_alias( 'keyword' => 'authtype' => 'authtype' );
911 $self->add_search_field_alias( 'keyword' => 'authtype' => 'at' );
913 $self->add_bib1_field_map('subject' => 'start' => 'authorityserver' => { '3' => '2', '4' => '1', '5' => '1' } );
914 $self->add_bib1_field_map('subject' => 'exact' => 'authorityserver' => { '4' => '1', '5' => '100', '6' => '3' } );
916 $self->add_bib1_modifier_map('HeadingAsc' => 'authorityserver' => { '7' => '1', '1' => 'Heading', '' => '0', 'op' => '@or' } );
917 $self->add_bib1_modifier_map('HeadingDsc' => 'authorityserver' => { '7' => '2', '1' => 'Heading', '' => '0', 'op' => '@or' } );
918 $self->add_bib1_modifier_map('AuthidAsc' => 'authorityserver' => { '7' => '1', '1' => 'Local-Number', '' => '0', 'op' => '@or' } );
919 $self->add_bib1_modifier_map('AuthidDsc' => 'authorityserver' => { '7' => '2', '1' => 'Local-Number', '' => '0', 'op' => '@or' } );
920 $self->add_bib1_modifier_map('Relevance' => 'authorityserver' => { '2' => '102' } );