From 0836acd0ed5cd226c41fa666e393b89f0e30099b Mon Sep 17 00:00:00 2001 From: Dan Wells Date: Fri, 4 Oct 2013 10:02:39 -0400 Subject: [PATCH] LP#1389403 Add normalizer detection to call number browse When finding the pivot for call number browse, we currently rely on simple label matching (rather than normalized label matching), since we do not know at the time of the search which normalizer we should use. Rather than blindly using the label, let's select the pivot in two phases. First, we will do what we do know, getting as close as possible by label alone. If we find an exact match, we are done (same as the current code). If we don't find an exact match, we take the normalizer setting from the closest label match, normalize our input, then search again. This method *greatly* improves the overall accuracy of call number searching whenever the call number being browsed for does not exist, while causing no harm to accuracy when it does exist (since it will either match the label or normalize to the same call number anyway). Eventually, we may want to add interface elements for selecting the call number type, probably defaulting to the default call number type for the org unit being searched, but even with that in place, this "auto-detection" logic should still be valuable. Signed-off-by: Dan Wells Signed-off-by: Kathy Lussier Signed-off-by: Ben Shum --- .../lib/OpenILS/Application/SuperCat.pm | 31 ++++++++++++++++--- Open-ILS/src/sql/Pg/040.schema.asset.sql | 6 ++-- ...XXXX.function.cn_normalizers_immutable.sql | 9 ++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.function.cn_normalizers_immutable.sql diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm index bf795e4189..61e9c0783f 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm @@ -339,15 +339,38 @@ sub _label_sortkey_from_label { deleted => 'f', @$cp_filter }, - { limit => 1, + { flesh => 1, + flesh_fields => { acn => [qw/label_class/] }, + limit => 1, order_by => { acn => "oils_text_as_bytea(label), id" } } )->gather(1); if (@$closest_cn) { - return $closest_cn->[0]->label_sortkey; - } else { - return '~~~'; #fallback to high ascii value, we are at the end + if ($closest_cn->[0]->label eq $label) { + # we found an exact match stop here + return $closest_cn->[0]->label_sortkey; + } else { + # we got as close as we could by label alone, let's try to + # normalize and get closer + $closest_cn = $_storage->request( + "open-ils.cstore.direct.asset.call_number.search.atomic", + { label_sortkey + => { ">=" => [$closest_cn->[0]->label_class->normalizer, $label] }, + owning_lib => $ou_ids, + deleted => 'f', + @$cp_filter + }, + { limit => 1, + order_by => { acn => "label_sortkey, id" } + } + )->gather(1); + if (@$closest_cn) { + return $closest_cn->[0]->label_sortkey; + } + } } + + return '~~~'; #fallback to high ascii value, we are at the end of the range } sub cn_browse { diff --git a/Open-ILS/src/sql/Pg/040.schema.asset.sql b/Open-ILS/src/sql/Pg/040.schema.asset.sql index 2381fdb543..e7b1daa944 100644 --- a/Open-ILS/src/sql/Pg/040.schema.asset.sql +++ b/Open-ILS/src/sql/Pg/040.schema.asset.sql @@ -348,7 +348,7 @@ CREATE OR REPLACE FUNCTION asset.label_normalizer_generic(TEXT) RETURNS TEXT AS $callnum =~ s/ {2,}/ /g; return $callnum; -$func$ LANGUAGE PLPERLU; +$func$ LANGUAGE PLPERLU IMMUTABLE; CREATE OR REPLACE FUNCTION asset.label_normalizer_dewey(TEXT) RETURNS TEXT AS $func$ # Derived from the Koha C4::ClassSortRoutine::Dewey module @@ -387,7 +387,7 @@ CREATE OR REPLACE FUNCTION asset.label_normalizer_dewey(TEXT) RETURNS TEXT AS $f return $key; -$func$ LANGUAGE PLPERLU; +$func$ LANGUAGE PLPERLU IMMUTABLE; CREATE OR REPLACE FUNCTION asset.label_normalizer_lc(TEXT) RETURNS TEXT AS $func$ @@ -401,7 +401,7 @@ CREATE OR REPLACE FUNCTION asset.label_normalizer_lc(TEXT) RETURNS TEXT AS $func my $callnum = Library::CallNumber::LC->new(shift); return $callnum->normalize(); -$func$ LANGUAGE PLPERLU; +$func$ LANGUAGE PLPERLU IMMUTABLE; INSERT INTO asset.call_number_class (name, normalizer, field) VALUES ('Generic', 'asset.label_normalizer_generic', '050ab,055ab,060ab,070ab,080ab,082ab,086ab,088ab,090,092,096,098,099'), diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.cn_normalizers_immutable.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.cn_normalizers_immutable.sql new file mode 100644 index 0000000000..60618da3eb --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.cn_normalizers_immutable.sql @@ -0,0 +1,9 @@ +BEGIN; + +--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +ALTER FUNCTION asset.label_normalizer_generic(TEXT) IMMUTABLE; +ALTER FUNCTION asset.label_normalizer_dewey(TEXT) IMMUTABLE; +ALTER FUNCTION asset.label_normalizer_lc(TEXT) IMMUTABLE; + +COMMIT; -- 2.43.2