From 97ccbca72fe63b519faea56bb492b4d3772fec3a Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Fri, 11 Mar 2016 13:27:03 -0500 Subject: [PATCH] LP#1549505: add flag to tweak popularity-adjusted relevance This adds a new global_flag, search.max_popularity_importance_multiplier, to control the factor by which popularity affects Popularity Adjusted relevance ranking. The value should be a decimal number, typically between 1.0 and 2.0: * 1.0 be would be equivalent to not adjusting relevance for popularity at all. * 1.1 would mean that the multiplier would range from 1 (for zero popularity) to 1.1 (for maximum popularity) * values less than 1.0 would have the effect of boosting lower popularity records in search results -- dramatically Signed-off-by: Galen Charlton --- .../OpenILS/Application/Storage/Driver/Pg/QueryParser.pm | 11 ++++++++++- .../lib/OpenILS/Application/Storage/Publisher/metabib.pm | 13 +++++++++++++ Open-ILS/src/sql/Pg/950.data.seed-values.sql | 12 ++++++++++++ .../src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql | 12 ++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) 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 3e3b017227..fd2da63347 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 @@ -117,6 +117,14 @@ sub default_preferred_language_multiplier { return $self->custom_data->{default_preferred_language_multiplier}; } +sub max_popularity_importance_multiplier { + my $self = shift; + my $max = shift; + + $self->custom_data->{max_popularity_importance_multiplier} = $max if defined($max); + return $self->custom_data->{max_popularity_importance_multiplier}; +} + sub simple_plan { my $self = shift; @@ -875,7 +883,8 @@ sub toSQL { } elsif ($sort_filter eq 'edit_date') { $rank = "FIRST((SELECT edit_date FROM biblio.record_entry rbr WHERE rbr.id = m.source))"; } elsif ($sort_filter eq 'poprel') { - $rank = '1.0/((' . $rel . ') * (1.0 + AVG(COALESCE(pop_with.total_score::NUMERIC,0.0)) / 5.0))::NUMERIC'; + my $max_mult = $self->QueryParser->max_popularity_importance_multiplier() // 2.0; + $rank = '1.0/((' . $rel . ') * (' . $max_mult .' - 1.0) * (1.0 + AVG(COALESCE(pop_with.total_score::NUMERIC,0.0)) / 5.0))::NUMERIC'; } elsif ($sort_filter =~ /^pop/) { $rank = '1.0/(AVG(COALESCE(pop_with.total_score::NUMERIC,0.0)) + 5.0)::NUMERIC'; my $pop_desc = $desc eq 'ASC' ? 'DESC' : 'ASC'; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm index 6786d4e35c..00108b3724 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm @@ -5,6 +5,7 @@ use OpenSRF::EX qw/:try/; use OpenILS::Application::Storage::FTS; use OpenILS::Utils::Fieldmapper; use OpenSRF::Utils::Logger qw/:level/; +use OpenILS::Application::AppUtils; use OpenSRF::Utils::Cache; use OpenSRF::Utils::JSON; use Data::Dumper; @@ -12,6 +13,8 @@ use Digest::MD5 qw/md5_hex/; use OpenILS::Application::Storage::QueryParser; +my $U = 'OpenILS::Application::AppUtils'; + my $log = 'OpenSRF::Utils::Logger'; $VERSION = 1; @@ -70,6 +73,16 @@ sub _initialize_parser { )->gather(1), ); + my $max_mult; + my $cgf = $cstore->request( + 'open-ils.cstore.direct.config.global_flag.retrieve', + 'search.max_popularity_importance_multiplier' + )->gather(1); + $max_mult = $cgf->value if $cgf && $U->is_true($cgf->enabled); + $max_mult //= 2.0; + $max_mult = 2.0 unless $max_mult =~ /^-?(?:\d+\.?|\.\d)\d*\z/; # just in case + $parser->max_popularity_importance_multiplier($max_mult); + $cstore->disconnect; die("Cannot initialize $parser!") unless ($parser->initialization_complete); } diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index e7a2bfbd8c..edcb930fec 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -10291,6 +10291,18 @@ INSERT INTO config.global_flag (name, label, value, enabled) VALUES ( '', TRUE ); + +INSERT INTO config.global_flag (name, label, value, enabled) VALUES ( + 'search.max_popularity_importance_multiplier', + oils_i18n_gettext( + 'search.max_popularity_importance_multiplier', + 'Maximum popularity importance multiplier for popularity-adjusted relevance searches (decimal value between 1.0 and 2.0)', + 'cgf', + 'label' + ), + '2.0', + TRUE +); */ INSERT INTO config.usr_setting_type (name,opac_visible,label,description,datatype) diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql index 3c5fe5d5ce..a03d64cd17 100644 --- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql @@ -135,6 +135,18 @@ INSERT INTO config.global_flag (name, label, value, enabled) VALUES ( TRUE ); +INSERT INTO config.global_flag (name, label, value, enabled) VALUES ( + 'search.max_popularity_importance_multiplier', + oils_i18n_gettext( + 'search.max_popularity_importance_multiplier', + 'Maximum popularity importance multiplier for popularity-adjusted relevance searches (decimal value between 1.0 and 2.0)', + 'cgf', + 'label' + ), + '2.0', + TRUE +); + CREATE TABLE rating.popularity_parameter ( id INT PRIMARY KEY, name TEXT NOT NULL UNIQUE, -- i18n -- 2.11.0