LP#1549505: add flag to tweak popularity-adjusted relevance
authorGalen Charlton <gmc@esilibrary.com>
Fri, 11 Mar 2016 18:27:03 +0000 (13:27 -0500)
committerGalen Charlton <gmc@esilibrary.com>
Fri, 11 Mar 2016 18:27:03 +0000 (13:27 -0500)
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 <gmc@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.statisitcal-ratings.sql

index 3e3b017..fd2da63 100644 (file)
@@ -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';
index 6786d4e..00108b3 100644 (file)
@@ -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);
 }
index e7a2bfb..edcb930 100644 (file)
@@ -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)
index 3c5fe5d..a03d64c 100644 (file)
@@ -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