From 321b318be82ec3f1693f14d1883d42dcaf82fb93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joonas=20Kylm=C3=A4l=C3=A4?= Date: Fri, 13 Nov 2020 19:52:18 +0200 Subject: [PATCH] Bug 11175: Limit the amount of component parts returned There was already before this a limit of 100 results when using Elasticsearch but then the list of component parts was truncated silently. This change now limits the amount to hard coded limit of 300 which is still fast to render. Also when the 300 component part record limit is reached there is a link in the list now to list all the records via the cataloging search. To test: 1) Create 300+ component part records and see if the link to list all the component part records shows up 2) Make sure prove t/Koha/Util/Search.t passes --- C4/XSLT.pm | 21 +++++--- Koha/Biblio.pm | 26 +++------- Koha/Util/Search.pm | 57 ++++++++++++++++++++++ .../intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl | 6 +++ t/Koha/Util/Search.t | 42 ++++++++++++++++ 5 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 Koha/Util/Search.pm create mode 100755 t/Koha/Util/Search.t diff --git a/C4/XSLT.pm b/C4/XSLT.pm index bc4a59e528..c8c630a569 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -31,6 +31,7 @@ use C4::Circulation; use C4::Reserves; use Koha::AuthorisedValues; use Koha::ItemTypes; +use Koha::Util::Search; use Koha::XSLT::Base; use Koha::Libraries; @@ -266,11 +267,6 @@ sub XSLTParse4Display { $variables->{OpenURLResolverURL} = $biblio->get_openurl; } } - my $varxml = "\n"; - while (my ($key, $value) = each %$variables) { - $varxml .= "$value\n"; - } - $varxml .= "\n"; my $partsxml = ''; # possibly insert component records into Detail views @@ -280,9 +276,14 @@ sub XSLTParse4Display { ($showcomp eq 'staff' && $xslsyspref !~ m/OPAC/ ) || ($showcomp eq 'opac' && $xslsyspref =~ m/OPAC/ ) ) { my $biblio = Koha::Biblios->find( $biblionumber ); - if ( $biblio->components() ) { + my $max_results = 300; + + if ( $biblio->components($max_results) ) { + my $search_query = Koha::Util::Search::get_component_part_query($biblionumber); + $variables->{ComponentPartQuery} = $search_query; + my @componentPartRecordXML = (''); - for my $cb ( @{ $biblio->components() } ) { + for my $cb ( @{ $biblio->components($max_results) } ) { if( ref $cb eq 'MARC::Record'){ $cb = $cb->as_xml_record(); } else { @@ -298,6 +299,12 @@ sub XSLTParse4Display { } } + my $varxml = "\n"; + while (my ($key, $value) = each %$variables) { + $varxml .= "$value\n"; + } + $varxml .= "\n"; + $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml$varxml$partsxml\<\/record\>/; if ($fixamps) { # We need to correct the ampersand entities that Zebra outputs $xmlrecord =~ s/\&amp;/\&/g; diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 1f002299ac..f9ae290a92 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -45,6 +45,7 @@ use Koha::Suggestions; use Koha::Subscriptions; use Koha::SearchEngine; use Koha::SearchEngine::Search; +use Koha::Util::Search; =head1 NAME @@ -506,31 +507,16 @@ this object (MARC21 773$w points to this) =cut sub components { - my ($self) = @_; + my ($self, $max_results) = @_; return if (C4::Context->preference('marcflavour') ne 'MARC21'); - my $marc = C4::Biblio::GetMarcBiblio({ biblionumber => $self->id }); - my $pf001 = $marc->field('001') || undef; - my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX}); - - if (defined($pf001)) { - my $pf003 = $marc->field('003') || undef; - my $searchstr; - - if (!defined($pf003)) { - # search for 773$w='Host001' - $searchstr = "rcn='".$pf001->data()."'"; - } else { - # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001') - $searchstr = "(rcn='".$pf001->data()."' AND cni='".$pf003->data()."')"; - $searchstr .= " OR rcn='".$pf003->data()." ".$pf001->data()."'"; - } + my $searchstr = Koha::Util::Search::get_component_part_query($self->id); - my ( $errors, $results, $total_hits ) = $searcher->simple_search_compat( $searchstr, 0, undef ); + if (defined($searchstr)) { + my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX}); + my ( $errors, $results, $total_hits ) = $searcher->simple_search_compat( $searchstr, 0, $max_results ); $self->{_components} = $results if ( defined($results) && scalar(@$results) ); - } else { - warn "Record $self->id has no 001"; } return $self->{_components} || (); diff --git a/Koha/Util/Search.pm b/Koha/Util/Search.pm new file mode 100644 index 0000000000..4e1c9706a8 --- /dev/null +++ b/Koha/Util/Search.pm @@ -0,0 +1,57 @@ +package Koha::Util::Search; + +# Copyright 2020 University of Helsinki +# +# 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 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 . + +use Modern::Perl; + +use C4::Biblio; + +=head1 NAME + +Koha::Util::Search – functions to build complex search queries + +=head1 FUNCTIONS + +=head2 get_component_part_query + +Returns a query which can be used to search for all component parts of MARC21 biblios + +=cut + +sub get_component_part_query { + my ($biblionumber) = @_; + + my $marc = C4::Biblio::GetMarcBiblio({ biblionumber => $biblionumber }); + my $pf001 = $marc->field('001') || undef; + + if (defined($pf001)) { + my $pf003 = $marc->field('003') || undef; + my $searchstr; + + if (!defined($pf003)) { + # search for 773$w='Host001' + $searchstr = "rcn='".$pf001->data()."'"; + } else { + # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001') + $searchstr = "(rcn='".$pf001->data()."' AND cni='".$pf003->data()."')"; + $searchstr .= " OR rcn='".$pf003->data()." ".$pf001->data()."'"; + } + } +} + +1; diff --git a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl index 13e5887fec..42fe45052e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl +++ b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl @@ -581,6 +581,7 @@ +
Component part records
    @@ -640,6 +641,11 @@
+ + +

Only 300 results are shown: /cgi-bin/koha/catalogue/search.pl?q=show all component parts

+
+
diff --git a/t/Koha/Util/Search.t b/t/Koha/Util/Search.t new file mode 100755 index 0000000000..c56b9404e2 --- /dev/null +++ b/t/Koha/Util/Search.t @@ -0,0 +1,42 @@ +#!/usr/bin/perl +# +# Copyright 2020 University of Helsinki +# +# 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 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 . + +use Modern::Perl; + +use Test::More tests => 1; +use t::lib::TestBuilder; + +use C4::Biblio; +use Koha::Util::Search; +use MARC::Field; + +my $builder = t::lib::TestBuilder->new; + +subtest 'get_component_part_query' => sub { + plan tests => 1; + + my $biblio = $builder->build_sample_biblio(); + my $biblionumber = $biblio->biblionumber; + my $record = GetMarcBiblio({ biblionumber => $biblionumber }); + my $marc_001_field = MARC::Field->new('001', $biblionumber); + $record->append_fields($marc_001_field); + ModBiblioMarc($record, $biblionumber); + + is(Koha::Util::Search::get_component_part_query($biblionumber), "rcn='$biblionumber'"); +}; -- 2.11.0