--- /dev/null
+-- 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';
--- /dev/null
+-- 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"'
+ );
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}}) {
$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'));
$lang_join
$c_attr_join
$b_attr_join
+ $mlf_join
WHERE 1=1
$flat_where
GROUP BY 1
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} ) {
$uses_bre = $$subnode{uses_bre};
$uses_mrd = $$subnode{uses_mrd};
$uses_mrv = $$subnode{uses_mrv};
+ $uses_mlf = $$subnode{uses_mlf};
}
} else {
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 }) {
$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;
vis_filter => \%vis_filter,
uses_bre => $uses_bre,
uses_mrv => $uses_mrv,
- uses_mrd => $uses_mrd
+ uses_mrd => $uses_mrd,
+ uses_mlf => $uses_mlf
};
}