From: Bill Erickson Date: Wed, 29 Oct 2014 21:06:14 +0000 (-0400) Subject: kmain-310. Additional language search Searches MARC 041 for additional language codes. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=cab3af075780e135566960ace87221383b5e0a9d;p=working%2FEvergreen.git kmain-310. Additional language search Searches MARC 041 for additional language codes. SQL scripts add new metabib.language_filter table and associated trigger/scripts new file: sql/kmain-310/kclsupgrad34.rollback.sql new file: sql/kmain-310/kclsupgrad34.sql modified: usr/lib/perl5/site_perl/5.8.8/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm (cherry picked from commit baf328d0c8a9ffb10eeb243db2fe4278ff1adcec) Cross-port: 7952a80 Conflicts: Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm Conflicts: Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm --- diff --git a/KCLS/sql/kmain-310/kclsupgrad34.rollback.sql b/KCLS/sql/kmain-310/kclsupgrad34.rollback.sql new file mode 100644 index 0000000000..18cfaa3a20 --- /dev/null +++ b/KCLS/sql/kmain-310/kclsupgrad34.rollback.sql @@ -0,0 +1,22 @@ +-- Trigger: language_filter_trigger on biblio.record_entry + +DROP TRIGGER IF EXISTS language_filter_trigger ON biblio.record_entry; + +-- Table: metabib.language_filter + +DROP TABLE IF EXISTS metabib.language_filter; + +-- Function: biblio.extract_languages(bigint) + +DROP FUNCTION IF EXISTS biblio.extract_languages(bigint); + +-- Function: biblio.update_language_filter() + +DROP FUNCTION IF EXISTS biblio.update_language_filter(); + +-- RECORD in config.org_unit_setting_type + +DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'opac.additional_language.subfields'; +DELETE FROM actor.org_unit_setting WHERE name = 'opac.additional_language.subfields'; +DELETE FROM config.org_unit_setting_type_log WHERE field_name = 'opac.additional_language.subfields'; +DELETE FROM config.org_unit_setting_type WHERE name = 'opac.additional_language.subfields'; diff --git a/KCLS/sql/kmain-310/kclsupgrad34.sql b/KCLS/sql/kmain-310/kclsupgrad34.sql new file mode 100644 index 0000000000..0feadc22e0 --- /dev/null +++ b/KCLS/sql/kmain-310/kclsupgrad34.sql @@ -0,0 +1,112 @@ +-- Table: metabib.language_filter + +-- DROP TABLE metabib.language_filter; + +CREATE TABLE metabib.language_filter +( + id bigserial NOT NULL, + source bigint NOT NULL, + value tsvector, + CONSTRAINT id PRIMARY KEY (id ), + CONSTRAINT source FOREIGN KEY (source) + REFERENCES biblio.record_entry (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +) +WITH ( + OIDS=FALSE +); +ALTER TABLE metabib.language_filter + OWNER TO evergreen; + +-- Function: biblio.extract_languages(bigint) + +-- DROP FUNCTION biblio.extract_languages(bigint); + +CREATE OR REPLACE FUNCTION biblio.extract_languages(bigint) + RETURNS tsvector AS +$BODY$ + +DECLARE + alt_lang text; + lang text; + subfields text; +BEGIN + lang := biblio.marc21_extract_fixed_field($1, 'Lang'); + +-- read MARC 041 subfields from actor.org_unit_setting.opac_additional_language_subfields +-- trim any '"' chars, split into array of subfields + + SELECT value INTO subfields FROM actor.org_unit_setting where name like 'opac.additional_language_subfields'; +-- +-- query MARC 041 specified subfields for additional search languages +-- + FOR alt_lang IN (SELECT value FROM biblio.flatten_marc($1) where tag='041' and POSITION(subfield IN subfields) > 0) + LOOP + lang := lang || ' ' || alt_lang; + END LOOP; + + return lang::tsvector; +END; +$BODY$ + LANGUAGE plpgsql VOLATILE + COST 100; +ALTER FUNCTION biblio.extract_languages(bigint) + OWNER TO evergreen; + +-- Function: update_language_filter() + +-- DROP FUNCTION update_language_filter(); + +CREATE OR REPLACE FUNCTION biblio.update_language_filter() + RETURNS trigger AS +$BODY$ +DECLARE + lang tsvector; + lang_filter bigint; +BEGIN + lang := biblio.extract_languages(NEW.id); + + SELECT metabib.language_filter.source INTO lang_filter FROM metabib.language_filter WHERE NEW.id = metabib.language_filter.source; + + IF FOUND THEN + UPDATE metabib.language_filter SET value = lang WHERE metabib.language_filter.source = NEW.id; + ELSE + INSERT INTO metabib.language_filter(source, value) VALUES (NEW.id, lang); + END IF; + + RETURN NEW; + +END; +$BODY$ + LANGUAGE plpgsql VOLATILE + COST 100; +ALTER FUNCTION biblio.update_language_filter() + OWNER TO evergreen; + +-- Trigger: language_filter_trigger on biblio.record_entry + +-- DROP TRIGGER language_filter_trigger ON biblio.record_entry; + +CREATE TRIGGER language_filter_trigger + AFTER INSERT OR UPDATE + ON biblio.record_entry + FOR EACH ROW + EXECUTE PROCEDURE biblio.update_language_filter(); + +-- +-- added record in config.org_unit_setting_type is used in proposal/additional_language_search +-- +INSERT INTO config.org_unit_setting_type + (name, label, grp, description, datatype) + VALUES ( + 'opac.additional_language.subfields', + 'Specify MARC 041 subfields for additional search languages', + 'opac', + 'Specify which MARC 041 subfields should be used when searching for additional languages.', + 'string' + ); + +INSERT INTO actor.org_unit_setting + (org_unit, name, value) VALUES + (1, 'opac.additional_language.subfields', '"abdefj"' + ); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm index 941085133d..d7fe36ec7e 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm @@ -835,6 +835,7 @@ sub toSQL { my $flat_plan = $self->flatten; + # generate the relevance ranking my $rel = '1'; # Default to something simple in case rank_list is empty. if (@{$$flat_plan{rank_list}}) { @@ -887,6 +888,11 @@ sub toSQL { $bre_join = 'INNER JOIN biblio.record_entry bre ON m.source = bre.id AND NOT bre.deleted'; } + my $mlf_join = ''; + if ($$flat_plan{uses_mlf}) { + $mlf_join = 'JOIN metabib.language_filter AS mlf ON m.source = mlf.source'; + } + my $desc = 'ASC'; $desc = 'DESC' if ($self->find_modifier('descending')); @@ -1156,6 +1162,7 @@ SELECT id, $lang_join $c_attr_join $b_attr_join + $mlf_join WHERE 1=1 $flat_where GROUP BY 1 @@ -1198,6 +1205,7 @@ sub flatten { my $uses_bre = 0; my $uses_mrd = 0; my $uses_mrv = 0; + my $uses_mlf = 0; my @rank_list; for my $node ( @{$self->query_nodes} ) { @@ -1412,6 +1420,7 @@ sub flatten { $uses_bre = $$subnode{uses_bre}; $uses_mrd = $$subnode{uses_mrd}; $uses_mrv = $$subnode{uses_mrv}; + $uses_mlf = $$subnode{uses_mlf}; } } else { @@ -1468,6 +1477,7 @@ sub flatten { my @dlist = (); my $common = 0; # for each dynamic filter, build more of the WHERE clause + for my $filter (@{$self->filters}) { my $NOT = $filter->negate ? 'NOT ' : ''; if (grep { $_ eq $filter->name } @{ $self->QueryParser->dynamic_filters }) { @@ -1476,6 +1486,17 @@ sub flatten { $fname = 'item_lang' if $fname eq 'language'; #XXX filter aliases warn "flatten(): processing dynamic filter ". $filter->name ."\n" + if ($fname eq 'item_lang') + { + $where .= "$NOT( " . 'mlf.value @@ ' . "\'" . join('|', @fargs) . '\'::tsquery)'; + $uses_mlf = 1; + } else { + $where .= sprintf( + "${NOT}COALESCE((mrd.attrs->'%s') IN (%s), false)", $fname, + join(',', map { $self->QueryParser->quote_value($_) } @fargs)); + } + + warn "flatten(): filter where => $where\n" if $self->QueryParser->debug; my $vlist_query; @@ -1735,7 +1756,8 @@ sub flatten { vis_filter => \%vis_filter, uses_bre => $uses_bre, uses_mrv => $uses_mrv, - uses_mrd => $uses_mrd + uses_mrd => $uses_mrd, + uses_mlf => $uses_mlf }; }