Bug 25030: Implement IncludeSeeFromInSearches with Elasticsearch

Test plan:
1. Create an authority with at least a 1XX$a and a 4XX$a, for instance:
    100 $a Foo
    400 $a Bar
2. Create a biblio and add a link to this authority using the
   cataloguing plugin
3. Disable syspref IncludeSeeFromInSearches
4. Reindex the biblio. You should be able to find it when searching
   'Foo' but not when searching 'Bar'
5. Enable syspref IncludeSeeFromInSearches
6. Reindex the biblio. You should be able to find it when searching
   'Foo' and also when searching 'Bar'
   without the patch, 'Bar' doesn't yeld results. With it, it does.
7. prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t

Signed-off-by: Séverine QUEUNE <severine.queune@bulac.fr>

Signed-off-by: Lucy Vaux-Harvey <lucy.vaux-harvey@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Julian Maurice 2020-11-10 15:22:21 +01:00 committed by Jonathan Druart
parent b5da108e35
commit 2c0d09e993
3 changed files with 140 additions and 7 deletions

View file

@ -58,22 +58,31 @@ sub filter {
if (ref $record eq 'ARRAY') {
my @recarray;
foreach my $thisrec (@$record) {
push @recarray, _processrecord($thisrec);
push @recarray, $self->_processrecord($thisrec);
}
$newrecord = \@recarray;
} elsif (ref $record eq 'MARC::Record') {
$newrecord = _processrecord($record);
$newrecord = $self->_processrecord($record);
}
return $newrecord;
}
sub _processrecord {
my $record = shift;
my ($self, $record) = @_;
$record->append_fields($self->fields($record));
return $record;
}
sub fields {
my ($self, $record) = @_;
my ($item_tag) = GetMarcFromKohaField( "items.itemnumber" );
$item_tag ||= '';
my @newfields;
foreach my $field ( $record->fields() ) {
next if $field->is_control_field();
next if $field->tag() eq $item_tag;
@ -85,7 +94,6 @@ sub _processrecord {
next unless $authority;
my $auth_marc = $authority->record;
my @seefrom = $auth_marc->field('4..');
my @newfields;
foreach my $authfield (@seefrom) {
my $tag = substr($field->tag(), 0, 1) . substr($authfield->tag(), 1, 2);
next if MARC::Field->is_controlfield_tag($tag);
@ -100,9 +108,9 @@ sub _processrecord {
$newfield->delete_subfield( code => '9' );
push @newfields, $newfield if (scalar($newfield->subfields()) > 0);
}
$record->append_fields(@newfields);
}
return $record;
return @newfields;
}
1;

View file

@ -24,6 +24,7 @@ use C4::Context;
use Koha::Database;
use Koha::Exceptions::Config;
use Koha::Exceptions::Elasticsearch;
use Koha::Filter::MARC::EmbedSeeFromHeadings;
use Koha::SearchFields;
use Koha::SearchMarcMaps;
use Koha::Caches;
@ -639,6 +640,54 @@ sub marc_records_to_documents {
}
}
}
if (C4::Context->preference('IncludeSeeFromInSearches') and $self->index eq 'biblios') {
foreach my $field (Koha::Filter::MARC::EmbedSeeFromHeadings->new->fields($record)) {
my $data_field_rules = $data_fields_rules->{$field->tag()};
if ($data_field_rules) {
my $subfields_mappings = $data_field_rules->{subfields};
my $wildcard_mappings = $subfields_mappings->{'*'};
foreach my $subfield ($field->subfields()) {
my ($code, $data) = @{$subfield};
my @mappings;
push @mappings, @{ $subfields_mappings->{$code} } if $subfields_mappings->{$code};
push @mappings, @$wildcard_mappings if $wildcard_mappings;
# Do not include "see from" into these kind of fields
@mappings = grep { $_->[0] !~ /__(sort|facet|suggestion)$/ } @mappings;
if (@mappings) {
$self->_process_mappings(\@mappings, $data, $record_document, {
data_source => 'subfield',
code => $code,
field => $field
}
);
}
}
my $subfields_join_mappings = $data_field_rules->{subfields_join};
if ($subfields_join_mappings) {
foreach my $subfields_group (keys %{$subfields_join_mappings}) {
my $data_field = $field->clone;
# remove empty subfields, otherwise they are printed as a space
$data_field->delete_subfield(match => qr/^$/);
my $data = $data_field->as_string( $subfields_group );
if ($data) {
my @mappings = @{ $subfields_join_mappings->{$subfields_group} };
# Do not include "see from" into these kind of fields
@mappings = grep { $_->[0] !~ /__(sort|facet|suggestion)$/ } @mappings;
$self->_process_mappings(\@mappings, $data, $record_document, {
data_source => 'subfields_group',
codes => $subfields_group,
field => $field
}
);
}
}
}
}
}
}
foreach my $field (keys %{$rules->{defaults}}) {
unless (defined $record_document->{$field}) {
$record_document->{$field} = $rules->{defaults}->{$field};

View file

@ -17,7 +17,7 @@
use Modern::Perl;
use Test::More tests => 6;
use Test::More tests => 7;
use Test::Exception;
use t::lib::Mocks;
@ -29,6 +29,8 @@ use MARC::Record;
use Try::Tiny;
use List::Util qw( any );
use C4::AuthoritiesMarc;
use Koha::SearchEngine::Elasticsearch;
use Koha::SearchEngine::Elasticsearch::Search;
@ -850,4 +852,78 @@ subtest 'Koha::SearchEngine::Elasticsearch::marc_records_to_documents () authori
};
subtest 'Koha::SearchEngine::Elasticsearch::marc_records_to_documents with IncludeSeeFromInSearches' => sub {
plan tests => 4;
t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
t::lib::Mocks::mock_preference('IncludeSeeFromInSearches', '1');
my $builder = t::lib::TestBuilder->new;
my $auth_type = $builder->build_object({
class => 'Koha::Authority::Types',
value => {
auth_tag_to_report => '150'
}
});
my $authority_record = MARC::Record->new();
$authority_record->append_fields(
MARC::Field->new(150, '', '', a => 'Foo'),
MARC::Field->new(450, '', '', a => 'Bar'),
);
my $authid = AddAuthority($authority_record, undef, $auth_type->authtypecode);
my @mappings = (
{
name => 'subject',
type => 'string',
facet => 1,
suggestible => 1,
sort => undef,
searchable => 1,
marc_type => 'marc21',
marc_field => '650a',
}
);
my $se = Test::MockModule->new('Koha::SearchEngine::Elasticsearch');
$se->mock('_foreach_mapping', sub {
my ($self, $sub) = @_;
foreach my $map (@mappings) {
$sub->(
$map->{name},
$map->{type},
$map->{facet},
$map->{suggestible},
$map->{sort},
$map->{searchable},
$map->{marc_type},
$map->{marc_field}
);
}
});
my $see = Koha::SearchEngine::Elasticsearch::Search->new({ index => $Koha::SearchEngine::Elasticsearch::BIBLIOS_INDEX });
my $marc_record_1 = MARC::Record->new();
$marc_record_1->leader(' cam 22 a 4500');
$marc_record_1->append_fields(
MARC::Field->new('001', '123'),
MARC::Field->new('245', '', '', a => 'Title'),
MARC::Field->new('650', '', '', a => 'Foo', 9 => $authid),
MARC::Field->new('999', '', '', c => '1234567'),
);
# sort_fields will call this and use the actual db values unless we call it first
$see->get_elasticsearch_mappings();
my $docs = $see->marc_records_to_documents([$marc_record_1]);
is_deeply($docs->[0]->{subject}, ['Foo', 'Bar'], 'subject should include "See from"');
is_deeply($docs->[0]->{subject__facet}, ['Foo'], 'subject__facet should not include "See from"');
is_deeply($docs->[0]->{subject__suggestion}, [{ input => 'Foo' }], 'subject__suggestion should not include "See from"');
is_deeply($docs->[0]->{subject__sort}, ['Foo'], 'subject__sort should not include "See from"');
};
$schema->storage->txn_rollback;