Switch to using weighted normalized proximity scores, a=chris

Chris Pollett [2022-07-30 01:Jul:th]
Switch to using weighted normalized proximity scores, a=chris
Filename
src/configs/Config.php
src/controllers/SearchController.php
src/controllers/components/CrawlComponent.php
src/library/PhraseParser.php
src/library/index_bundle_iterators/IntersectIterator.php
src/library/index_bundle_iterators/NetworkIterator.php
src/locale/ar/configure.ini
src/locale/bn/configure.ini
src/locale/de/configure.ini
src/locale/el_GR/configure.ini
src/locale/en_US/configure.ini
src/locale/es/configure.ini
src/locale/fa/configure.ini
src/locale/fr_FR/configure.ini
src/locale/he/configure.ini
src/locale/hi/configure.ini
src/locale/id/configure.ini
src/locale/it/configure.ini
src/locale/ja/configure.ini
src/locale/kn/configure.ini
src/locale/ko/configure.ini
src/locale/nl/configure.ini
src/locale/pl/configure.ini
src/locale/pt/configure.ini
src/locale/ru/configure.ini
src/locale/te/configure.ini
src/locale/th/configure.ini
src/locale/tl/configure.ini
src/locale/tr/configure.ini
src/locale/vi_VN/configure.ini
src/locale/vi_VN/statistics.txt
src/locale/zh_CN/configure.ini
src/models/PhraseModel.php
src/models/ProfileModel.php
src/views/elements/PageoptionsElement.php
diff --git a/src/configs/Config.php b/src/configs/Config.php
index 7ee53291f..da1211135 100755
--- a/src/configs/Config.php
+++ b/src/configs/Config.php
@@ -517,6 +517,12 @@ if (file_exists(WORK_DIRECTORY . PROFILE_FILE_NAME)) {
      *  each
      */
     nsdefine('TITLE_BONUS', 5);
+    /**
+     *  Phrase Proximity scores are normalized between 0 and 1, this is
+     *  the weighting factor to multiply that basic score before adding it
+     *  to the overall score used for ranking
+     */
+    nsdefine('PROXIMITY_BONUS', 20);
     /**
      *  Bonus to add to relevance score if the url path contains the search
      *  term. If the path has 1 term bonus would be 3 if 3 terms then 1
@@ -531,6 +537,12 @@ if (file_exists(WORK_DIRECTORY . PROFILE_FILE_NAME)) {
      *  Bonus to add to doc rank score if the url is a a hostname
      */
     nsdefine('HOST_URL_BONUS', 0.5);
+    /**
+     *  User rank scores for a document are normalized between 0 and 1, this is
+     *  the weighting factor to multiply that basic score before adding it
+     *  to the overall score used for ranking
+     */
+    nsdefine('USER_RANK_BONUS', 5);
     /**
      * If that many exist, the minimum number of results to get
      * and group before trying to compute the top x (say 10) results
diff --git a/src/controllers/SearchController.php b/src/controllers/SearchController.php
index d36888bd8..15ef4e0de 100755
--- a/src/controllers/SearchController.php
+++ b/src/controllers/SearchController.php
@@ -325,7 +325,9 @@ class SearchController extends Controller implements CrawlConstants
             "host_url_bonus" => C\HOST_URL_BONUS,
             "host_keyword_bonus" => C\HOST_KEYWORD_BONUS,
             "path_keyword_bonus" => C\PATH_KEYWORD_BONUS,
+            "proximity_bonus" => C\PROXIMITY_BONUS,
             "title_bonus" => C\TITLE_BONUS,
+            "user_rank_bonus" => C\USER_RANK_BONUS,
             ] as $factor => $default) {
             if (isset($_REQUEST[$factor])) {
                 $ranking_factors[strtoupper($factor)] =
diff --git a/src/controllers/components/CrawlComponent.php b/src/controllers/components/CrawlComponent.php
index fc3f58f7c..7c771f84c 100644
--- a/src/controllers/components/CrawlComponent.php
+++ b/src/controllers/components/CrawlComponent.php
@@ -1694,8 +1694,10 @@ class CrawlComponent extends Component implements CrawlConstants
         }
         $bonuses = ['HOST_KEYWORD_BONUS' => 6,
             'TITLE_BONUS' => 5, 'PATH_KEYWORD_BONUS' => 3,
+            'PROXIMITY_BONUS' => 20,
             'CLD_URL_BONUS' => 2, 'HOST_URL_BONUS' => 0.5,
-            'MIN_RESULTS_TO_GROUP' => C\MIN_RESULTS_TO_GROUP];
+            'MIN_RESULTS_TO_GROUP' => C\MIN_RESULTS_TO_GROUP,
+            'USER_RANK_BONUS' => 5];
         $change = false;
         foreach ($bonuses as $bonus => $value) {
             if (isset($_REQUEST[$bonus])) {
diff --git a/src/library/PhraseParser.php b/src/library/PhraseParser.php
index dad78a3be..39fadde13 100755
--- a/src/library/PhraseParser.php
+++ b/src/library/PhraseParser.php
@@ -1515,7 +1515,7 @@ vaffanculo fok hoer kut lul やりまん 打っ掛け
             "nifty\.org|adultdvd|suicidegirls|ftvgirls|asstr|private\.com|".
             "squirt\.org|fakku|faapy|fux|txxx|\Wnude\W/i";
         if (!empty($url) && preg_match($unsafe_url_regex, $url)) {
-            return 1000;
+            return 1;
         }
         if (is_string($word_lists)) {
             $lang = guessLocaleFromString($word_lists);
diff --git a/src/library/index_bundle_iterators/IntersectIterator.php b/src/library/index_bundle_iterators/IntersectIterator.php
index e933e05ad..6791db79c 100644
--- a/src/library/index_bundle_iterators/IntersectIterator.php
+++ b/src/library/index_bundle_iterators/IntersectIterator.php
@@ -338,12 +338,20 @@ class IntersectIterator extends IndexBundleIterator
     {
         $num_iterators = $this->num_iterators;
         if ($num_iterators < 1) {
-            return 1;
+            return 0;
         }
         $covers = [];
+        $max_covers = 1;
+        foreach ($word_position_lists as $positions) {
+            if (!empty($positions)) {
+                $last_pos = $positions[count($positions) - 1];
+                $max_covers = max($max_covers, $last_pos);
+            }
+        }
         $position_list = $word_position_lists;
         $interval = [];
         $num_words = count($position_list);
+        $max_covers = max(1, $max_covers - $num_words);
         for ($i = 0; $i < $num_words; $i++) {
             $min = (!empty($position_list[$i])) ?
                 array_shift($position_list[$i]) : null;
@@ -400,6 +408,8 @@ class IntersectIterator extends IndexBundleIterator
         foreach ($covers as $cover) {
             $score += (1/($cover[1] - $cover[0] + 1));
         }
+        $score = ($num_words * $score)/$max_covers;
+            // this will ensure the score is less than 1
         return $score;
     }
     /**
diff --git a/src/library/index_bundle_iterators/NetworkIterator.php b/src/library/index_bundle_iterators/NetworkIterator.php
index aa7f6e4ec..0b94aaa67 100644
--- a/src/library/index_bundle_iterators/NetworkIterator.php
+++ b/src/library/index_bundle_iterators/NetworkIterator.php
@@ -130,7 +130,9 @@ class NetworkIterator extends IndexBundleIterator
             "host_url_bonus" => C\HOST_URL_BONUS,
             "host_keyword_bonus" => C\HOST_KEYWORD_BONUS,
             "path_keyword_bonus" => C\PATH_KEYWORD_BONUS,
+            "proximity_bonus" => C\PROXIMITY_BONUS,
             "title_bonus" => C\TITLE_BONUS,
+            "user_rank_bonus" => C\USER_RANK_BONUS,
             ] as $factor => $default) {
             $this->base_query .= "&$factor=" . ($ranking_factors[$factor] ??
                 $default);
diff --git a/src/locale/ar/configure.ini b/src/locale/ar/configure.ini
index 6e8ecb831..57d12c52a 100755
--- a/src/locale/ar/configure.ini
+++ b/src/locale/ar/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "البحث ترتيب العوامل"
 pageoptions_element_host_keyword_bonus = "مكافأة استضافة الكلمات الرئيسية :"
 pageoptions_element_title_bonus = "عنوان مكافأة الكلمات الرئيسية"
 pageoptions_element_path_keyword_bonus = "مكافأة مسار الكلمات الرئيسية"
+pageoptions_element_proximity_bonus = "مكافأة القرب :"
 pageoptions_element_cld_url_bonus = "مكافأة رابط نطاق الشركة :"
 pageoptions_element_host_url_bonus = "مكافأة عنوان المضيف :"
+pageoptions_element_user_rank_bonus = "مكافأة رتبة المستخدم:"
 pageoptions_element_results_grouping_options = "تجميع نتائج البحث"
 pageoptions_element_min_results_to_group = "نتائج الحد الأدنى للمجموعة:"
 pageoptions_element_test_page = "صفحة اختبار"
diff --git a/src/locale/bn/configure.ini b/src/locale/bn/configure.ini
index 59e4bdbe4..e026924d5 100755
--- a/src/locale/bn/configure.ini
+++ b/src/locale/bn/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "সার্চ র্যাংকিং
 pageoptions_element_host_keyword_bonus = "হোস্ট কীওয়ার্ড বোনাস:"
 pageoptions_element_title_bonus = "শিরোনাম কীওয়ার্ড বোনাস"
 pageoptions_element_path_keyword_bonus = "পাথ কীওয়ার্ড বোনাস"
+pageoptions_element_proximity_bonus = "প্রক্সিমিটি বোনাস:"
 pageoptions_element_cld_url_bonus = "কোম্পানির ডোমেন ইউআরএল বোনাস:"
 pageoptions_element_host_url_bonus = "হোস্ট ইউআরএল বোনাস:"
+pageoptions_element_user_rank_bonus = "ব্যবহারকারী র্যাঙ্ক বোনাস:"
 pageoptions_element_results_grouping_options = "অনুসন্ধান ফলাফল জোট"
 pageoptions_element_min_results_to_group = "সর্বনিম্ন ফলাফল গ্রুপ:"
 pageoptions_element_test_page = "পরীক্ষা পৃষ্ঠা"
diff --git a/src/locale/de/configure.ini b/src/locale/de/configure.ini
index 931a9e430..3e799fee6 100755
--- a/src/locale/de/configure.ini
+++ b/src/locale/de/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Suche Ranking-Faktoren"
 pageoptions_element_host_keyword_bonus = "Schlüsselwortbonus für Gastgeber :"
 pageoptions_element_title_bonus = "Titel Stichwort Bonus"
 pageoptions_element_path_keyword_bonus = "Pfad-Schlüsselwort-Bonus"
+pageoptions_element_proximity_bonus = "Proximity-Bonus:"
 pageoptions_element_cld_url_bonus = "Firmen-Domain-URL-Bonus:"
 pageoptions_element_host_url_bonus = "Host-URL-Prämie:"
+pageoptions_element_user_rank_bonus = "Benutzerrangbonus :"
 pageoptions_element_results_grouping_options = "Suchergebnisse Gruppierung"
 pageoptions_element_min_results_to_group = "Minimale Ergebnisse Gruppe:"
 pageoptions_element_test_page = "Test Seite"
diff --git a/src/locale/el_GR/configure.ini b/src/locale/el_GR/configure.ini
index 5d0c9c8da..a78fb155e 100644
--- a/src/locale/el_GR/configure.ini
+++ b/src/locale/el_GR/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Παράγοντες κατάταξης
 pageoptions_element_host_keyword_bonus = "Μπόνους Λέξεων-Κλειδιών Υποδοχής :"
 pageoptions_element_title_bonus = "Τίτλος Λέξη-Κλειδί Μπόνους"
 pageoptions_element_path_keyword_bonus = "Διαδρομή Λέξη-Κλειδί Μπόνους"
+pageoptions_element_proximity_bonus = "Μπόνους Εγγύτητας :"
 pageoptions_element_cld_url_bonus = "Μπόνους Διεύθυνσης URL Τομέα Εταιρείας :"
 pageoptions_element_host_url_bonus = "Μπόνους URL Υποδοχής :"
+pageoptions_element_user_rank_bonus = "Μπόνους Κατάταξης Χρήστη :"
 pageoptions_element_results_grouping_options = "Ομαδοποίηση αποτελεσμάτων αναζήτησης"
 pageoptions_element_min_results_to_group = "Ελάχιστα αποτελέσματα στην ομάδα:"
 pageoptions_element_test_page = "Δοκιμαστική σελίδα"
diff --git a/src/locale/en_US/configure.ini b/src/locale/en_US/configure.ini
index de7de0c2f..d6aa946e1 100644
--- a/src/locale/en_US/configure.ini
+++ b/src/locale/en_US/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Search Ranking Factors"
 pageoptions_element_host_keyword_bonus = "Host Keyword Bonus:"
 pageoptions_element_title_bonus = "Title Keyword Bonus"
 pageoptions_element_path_keyword_bonus = "Path Keyword Bonus"
+pageoptions_element_proximity_bonus = "Proximity Bonus:"
 pageoptions_element_cld_url_bonus = "Company Domain Url Bonus:"
 pageoptions_element_host_url_bonus = "Host Url Bonus:"
+pageoptions_element_user_rank_bonus = "User Rank Bonus:"
 pageoptions_element_results_grouping_options = "Search Results Grouping"
 pageoptions_element_min_results_to_group = "Minimum Results to Group:"
 pageoptions_element_test_page = "Test Page"
diff --git a/src/locale/es/configure.ini b/src/locale/es/configure.ini
index 3af5caeae..412c4270f 100755
--- a/src/locale/es/configure.ini
+++ b/src/locale/es/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "La Clasificaci&oacute;n De La B&uacute;sq
 pageoptions_element_host_keyword_bonus = "Bonificación por palabra clave de anfitrión:"
 pageoptions_element_title_bonus = "Bono por Palabra Clave de Título"
 pageoptions_element_path_keyword_bonus = "Bonificación por Palabra Clave de Ruta"
+pageoptions_element_proximity_bonus = "Bonificación de proximidad:"
 pageoptions_element_cld_url_bonus = "Bonificación de Url de Dominio de Empresa:"
 pageoptions_element_host_url_bonus = "Bonificación de URL de Host:"
+pageoptions_element_user_rank_bonus = "Bonificación de Rango de Usuario :"
 pageoptions_element_results_grouping_options = "Resultados De La B&uacute;squeda De La Agrupaci&oacute;n"
 pageoptions_element_min_results_to_group = "Resultados m&iacute;nimos para el Grupo:"
 pageoptions_element_test_page = "P&aacute;gina De Prueba"
diff --git a/src/locale/fa/configure.ini b/src/locale/fa/configure.ini
index 026f50d36..3b14fc731 100755
--- a/src/locale/fa/configure.ini
+++ b/src/locale/fa/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "جستجو رتبه بندی عوامل"
 pageoptions_element_host_keyword_bonus = "میزبان کلید واژه پاداش:"
 pageoptions_element_title_bonus = "عنوان کلید واژه پاداش"
 pageoptions_element_path_keyword_bonus = "جایزه کلید واژه مسیر"
+pageoptions_element_proximity_bonus = "پاداش نزدیکی:"
 pageoptions_element_cld_url_bonus = "پاداش دامنه شرکت :"
 pageoptions_element_host_url_bonus = "پاداش نشانی وب میزبان :"
+pageoptions_element_user_rank_bonus = "پاداش رتبه کاربر:"
 pageoptions_element_results_grouping_options = "دسته&zwnj;بندی نتایج جستجو"
 pageoptions_element_min_results_to_group = "حداقل تعداد هر دسته:"
 pageoptions_element_test_page = "تست صفحه"
diff --git a/src/locale/fr_FR/configure.ini b/src/locale/fr_FR/configure.ini
index cb0997134..7ba8cabf2 100755
--- a/src/locale/fr_FR/configure.ini
+++ b/src/locale/fr_FR/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "La recherche des facteurs de classement"
 pageoptions_element_host_keyword_bonus = "Bonus de mot-clé hôte:"
 pageoptions_element_title_bonus = "Titre Mot-Clé Bonus"
 pageoptions_element_path_keyword_bonus = "Bonus de Mot-Clé Path"
+pageoptions_element_proximity_bonus = "Bonus de proximité:"
 pageoptions_element_cld_url_bonus = "Bonus d&#039;URL de domaine d&#039;entreprise:"
 pageoptions_element_host_url_bonus = "Bonus d&#039;URL d&#039;hôte:"
+pageoptions_element_user_rank_bonus = "Bonus de classement utilisateur:"
 pageoptions_element_results_grouping_options = "R&eacute;sultats de la recherche groupement"
 pageoptions_element_min_results_to_group = "Minimum de r&eacute;sultats &agrave; un groupe:"
 pageoptions_element_test_page = "Page de test"
diff --git a/src/locale/he/configure.ini b/src/locale/he/configure.ini
index 636227e35..009a7f617 100755
--- a/src/locale/he/configure.ini
+++ b/src/locale/he/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "חיפוש גורמי דירוג"
 pageoptions_element_host_keyword_bonus = "בונוס מילות מפתח מארח:"
 pageoptions_element_title_bonus = "בונוס מילת מפתח כותרת"
 pageoptions_element_path_keyword_bonus = "בונוס מילות מפתח נתיב"
+pageoptions_element_proximity_bonus = "בונוס קרבה:"
 pageoptions_element_cld_url_bonus = "בונוס כתובת אתר של תחום החברה :"
 pageoptions_element_host_url_bonus = "בונוס כתובת אתר מארח :"
+pageoptions_element_user_rank_bonus = "בונוס דירוג משתמש:"
 pageoptions_element_results_grouping_options = "תוצאות חיפוש קיבוץ"
 pageoptions_element_min_results_to_group = "מינימום תוצאות הקבוצה:"
 pageoptions_element_test_page = "דף בדיקה"
diff --git a/src/locale/hi/configure.ini b/src/locale/hi/configure.ini
index 0b1687884..9fd3a1072 100755
--- a/src/locale/hi/configure.ini
+++ b/src/locale/hi/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "खोज रैंकिंग कार
 pageoptions_element_host_keyword_bonus = "होस्ट कीवर्ड बोनस:"
 pageoptions_element_title_bonus = "शीर्षक कीवर्ड बोनस"
 pageoptions_element_path_keyword_bonus = "पथ कीवर्ड बोनस"
+pageoptions_element_proximity_bonus = "निकटता बोनस:"
 pageoptions_element_cld_url_bonus = "कंपनी डोमेन यूआरएल बोनस:"
 pageoptions_element_host_url_bonus = "होस्ट यूआरएल बोनस:"
+pageoptions_element_user_rank_bonus = "उपयोगकर्ता रैंक बोनस:"
 pageoptions_element_results_grouping_options = "खोज परिणाम समूहीकरण"
 pageoptions_element_min_results_to_group = "न्यूनतम परिणाम समूह के लिए:"
 pageoptions_element_test_page = "परीक्षण पृष्ठ"
diff --git a/src/locale/id/configure.ini b/src/locale/id/configure.ini
index c3b8ae7a5..2d1fb24db 100755
--- a/src/locale/id/configure.ini
+++ b/src/locale/id/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Pencarian Peringkat Faktor-Faktor"
 pageoptions_element_host_keyword_bonus = "Bonus Kata Kunci Host:"
 pageoptions_element_title_bonus = "Bonus Kata Kunci Judul"
 pageoptions_element_path_keyword_bonus = "Bonus Kata Kunci Jalur"
+pageoptions_element_proximity_bonus = "Bonus Kedekatan:"
 pageoptions_element_cld_url_bonus = "Bonus Url Domain Perusahaan:"
 pageoptions_element_host_url_bonus = "Bonus URL Tuan Rumah:"
+pageoptions_element_user_rank_bonus = "Bonus Peringkat Pengguna :"
 pageoptions_element_results_grouping_options = "Hasil Pencarian Pengelompokan"
 pageoptions_element_min_results_to_group = "Minimal Hasil untuk Kelompok:"
 pageoptions_element_test_page = "Uji Halaman"
diff --git a/src/locale/it/configure.ini b/src/locale/it/configure.ini
index d3604d256..72f9244c7 100755
--- a/src/locale/it/configure.ini
+++ b/src/locale/it/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Fattori del posto"
 pageoptions_element_host_keyword_bonus = "Bonus parole chiave host:"
 pageoptions_element_title_bonus = "Titolo Parola chiave Bonus"
 pageoptions_element_path_keyword_bonus = "Bonus parole chiave percorso"
+pageoptions_element_proximity_bonus = "Bonus di prossimità:"
 pageoptions_element_cld_url_bonus = "Bonus Url dominio azienda:"
 pageoptions_element_host_url_bonus = "Bonus Url host:"
+pageoptions_element_user_rank_bonus = "Bonus classifica utente:"
 pageoptions_element_results_grouping_options = "Raggruppa risultati di ricerca"
 pageoptions_element_min_results_to_group = "Minimo risultati da raggruppare:"
 pageoptions_element_test_page = "Pagina Di Prova"
diff --git a/src/locale/ja/configure.ini b/src/locale/ja/configure.ini
index 599110c25..b65b0bf19 100755
--- a/src/locale/ja/configure.ini
+++ b/src/locale/ja/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "検索ランキング因子"
 pageoptions_element_host_keyword_bonus = "ホストキーワードボーナス:"
 pageoptions_element_title_bonus = "タイトルキーワードボーナス"
 pageoptions_element_path_keyword_bonus = "パスキーワードボーナス"
+pageoptions_element_proximity_bonus = "近接ボーナス:"
 pageoptions_element_cld_url_bonus = "企業ドメインUrlボーナス:"
 pageoptions_element_host_url_bonus = "ホストUrlボーナス:"
+pageoptions_element_user_rank_bonus = "ユーザーランクボーナス:"
 pageoptions_element_results_grouping_options = "検索結果の分類"
 pageoptions_element_min_results_to_group = "最低限の結果をグループ"
 pageoptions_element_test_page = "テストページ"
diff --git a/src/locale/kn/configure.ini b/src/locale/kn/configure.ini
index 55dc2e465..15ad19564 100755
--- a/src/locale/kn/configure.ini
+++ b/src/locale/kn/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "ಹುಡುಕು ಶ್ರೇಯಾಂ
 pageoptions_element_host_keyword_bonus = "ಹೋಸ್ಟ್ ಕೀವರ್ಡ್ ಬೋನಸ್:"
 pageoptions_element_title_bonus = "ಶೀರ್ಷಿಕೆ ಕೀವರ್ಡ್ ಬೋನಸ್"
 pageoptions_element_path_keyword_bonus = "ಪಾತ್ ಕೀವರ್ಡ್ ಬೋನಸ್"
+pageoptions_element_proximity_bonus = "ಸಾಮೀಪ್ಯ ಬೋನಸ್:"
 pageoptions_element_cld_url_bonus = "ಕಂಪನಿ ಡೊಮೇನ್ ಯುಆರ್ಎಲ್ ಬೋನಸ್:"
 pageoptions_element_host_url_bonus = "ಹೋಸ್ಟ್ ಯುಆರ್ಎಲ್ ಬೋನಸ್:"
+pageoptions_element_user_rank_bonus = "ಬಳಕೆದಾರ ಶ್ರೇಣಿಯ ಬೋನಸ್:"
 pageoptions_element_results_grouping_options = "ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳು ಗುಂಪು"
 pageoptions_element_min_results_to_group = "ಕನಿಷ್ಠ ಫಲಿತಾಂಶಗಳು ಗುಂಪು:"
 pageoptions_element_test_page = "ಟೆಸ್ಟ್ ಪುಟ"
diff --git a/src/locale/ko/configure.ini b/src/locale/ko/configure.ini
index e0138cd71..fa025a708 100755
--- a/src/locale/ko/configure.ini
+++ b/src/locale/ko/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "검색 순위 요소"
 pageoptions_element_host_keyword_bonus = "호스트 키워드 보너스:"
 pageoptions_element_title_bonus = "제목 키워드 보너스"
 pageoptions_element_path_keyword_bonus = "경로 키워드 보너스"
+pageoptions_element_proximity_bonus = "근접 보너스:"
 pageoptions_element_cld_url_bonus = "회사 도메인 주소 보너스:"
 pageoptions_element_host_url_bonus = "호스트 주소 보너스:"
+pageoptions_element_user_rank_bonus = "사용자 순위 보너스:"
 pageoptions_element_results_grouping_options = "검색 결과 그룹"
 pageoptions_element_min_results_to_group = "최소 결과하는 그룹:"
 pageoptions_element_test_page = "테스트 페이지"
diff --git a/src/locale/nl/configure.ini b/src/locale/nl/configure.ini
index a9505aa44..a9b04e247 100644
--- a/src/locale/nl/configure.ini
+++ b/src/locale/nl/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Zoek Ranking Factors"
 pageoptions_element_host_keyword_bonus = "Host Keyword Bonus :"
 pageoptions_element_title_bonus = "Titel Trefwoord Bonus"
 pageoptions_element_path_keyword_bonus = "Pad Trefwoord Bonus"
+pageoptions_element_proximity_bonus = "Proximity Bonus :"
 pageoptions_element_cld_url_bonus = "Bedrijfsdomein Url-Bonus :"
 pageoptions_element_host_url_bonus = "Host Url Bonus :"
+pageoptions_element_user_rank_bonus = "User Rank Bonus :"
 pageoptions_element_results_grouping_options = "Zoekresultaten Groepering"
 pageoptions_element_min_results_to_group = "Minimum Resultaten Groep:"
 pageoptions_element_test_page = "testpagina"
diff --git a/src/locale/pl/configure.ini b/src/locale/pl/configure.ini
index 143262947..85c2123cd 100755
--- a/src/locale/pl/configure.ini
+++ b/src/locale/pl/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Czynniki Rankingu Wyszukiwania "
 pageoptions_element_host_keyword_bonus = "Host Keyword Bonus:"
 pageoptions_element_title_bonus = "Tytuł Keyword Bonus"
 pageoptions_element_path_keyword_bonus = "Path Keyword Bonus"
+pageoptions_element_proximity_bonus = "Premia Zbliżeniowa :"
 pageoptions_element_cld_url_bonus = "Bonus URL Domeny Firmowej :"
 pageoptions_element_host_url_bonus = "Bonus URL Hosta:"
+pageoptions_element_user_rank_bonus = "Bonus Rangi Użytkownika:"
 pageoptions_element_results_grouping_options = "Wyniki Wyszukiwania Grupowanie"
 pageoptions_element_min_results_to_group = "Minimalne wyniki w grupie:"
 pageoptions_element_test_page = "Strona Testowa "
diff --git a/src/locale/pt/configure.ini b/src/locale/pt/configure.ini
index 7ca1eefe0..7a6f1dee1 100755
--- a/src/locale/pt/configure.ini
+++ b/src/locale/pt/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Pesquisa De Fatores De Ranking"
 pageoptions_element_host_keyword_bonus = "Bônus De Palavra-Chave Do Host:"
 pageoptions_element_title_bonus = "Título Bonus Palavra-Chave"
 pageoptions_element_path_keyword_bonus = "Bônus De Palavra-Chave Do Caminho"
+pageoptions_element_proximity_bonus = "Bônus De Proximidade :"
 pageoptions_element_cld_url_bonus = "Bônus De Url De Domínio Da Empresa:"
 pageoptions_element_host_url_bonus = "Bônus De URL Do Host :"
+pageoptions_element_user_rank_bonus = "Bônus De Classificação Do Usuário :"
 pageoptions_element_results_grouping_options = "Resultados Da Pesquisa De Agrupamento"
 pageoptions_element_min_results_to_group = "Resultados m&iacute;nimos para o Grupo:"
 pageoptions_element_test_page = "P&aacute;gina De Teste"
diff --git a/src/locale/ru/configure.ini b/src/locale/ru/configure.ini
index baf724223..0da9ab8bc 100755
--- a/src/locale/ru/configure.ini
+++ b/src/locale/ru/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Факторы Ранжирования
 pageoptions_element_host_keyword_bonus = "Бонус за ключевое слово хоста:"
 pageoptions_element_title_bonus = "Бонус за ключевое слово в названии"
 pageoptions_element_path_keyword_bonus = "Бонус за ключевое слово Path"
+pageoptions_element_proximity_bonus = "Бонус за близость:"
 pageoptions_element_cld_url_bonus = "Бонусный URL-адрес домена компании:"
 pageoptions_element_host_url_bonus = "Бонусный URL-адрес хоста:"
+pageoptions_element_user_rank_bonus = "Бонус за ранг пользователя:"
 pageoptions_element_results_grouping_options = "Результаты Поиска Группировка"
 pageoptions_element_min_results_to_group = "Минимальные результаты в группе:"
 pageoptions_element_test_page = "Тестовая Страница "
diff --git a/src/locale/te/configure.ini b/src/locale/te/configure.ini
index da79e7ea4..06c85054b 100644
--- a/src/locale/te/configure.ini
+++ b/src/locale/te/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "శోధన ర్యాంకింగ
 pageoptions_element_host_keyword_bonus = "హోస్ట్ కీవర్డ్ బోనస్:"
 pageoptions_element_title_bonus = "శీర్షిక కీవర్డ్ బోనస్"
 pageoptions_element_path_keyword_bonus = "మార్గం కీవర్డ్ బోనస్"
+pageoptions_element_proximity_bonus = "సామీప్య బోనస్:"
 pageoptions_element_cld_url_bonus = "కంపెనీ డొమైన్ యూఆర్ఎల్ బోనస్:"
 pageoptions_element_host_url_bonus = "హోస్ట్ యూఆర్ఎల్ బోనస్:"
+pageoptions_element_user_rank_bonus = "వాడుకరి రాంక్ బోనస్:"
 pageoptions_element_results_grouping_options = "శోధన ఫలితాలు చోట"
 pageoptions_element_min_results_to_group = "కనీస ఫలితాలు గుంపు:"
 pageoptions_element_test_page = "టెస్ట్ పేజీ"
diff --git a/src/locale/th/configure.ini b/src/locale/th/configure.ini
index ebc3acdc7..f0f407df1 100755
--- a/src/locale/th/configure.ini
+++ b/src/locale/th/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "การค้นหาปัจจั
 pageoptions_element_host_keyword_bonus = "โบนัสคำหลักโฮสต์:"
 pageoptions_element_title_bonus = "ชื่อโบนัสคำสำคัญ"
 pageoptions_element_path_keyword_bonus = "โบนัสคำหลักเส้นทาง"
+pageoptions_element_proximity_bonus = "โบนัสความใกล้ชิด:"
 pageoptions_element_cld_url_bonus = "โบนัสโดเมนบริษัท:"
 pageoptions_element_host_url_bonus = "โบนัสโฮสต์:"
+pageoptions_element_user_rank_bonus = "โบนัสอันดับผู้ใช้:"
 pageoptions_element_results_grouping_options = "ผลการค้นหาการจัดกลุ่ม"
 pageoptions_element_min_results_to_group = "อย่างน้อยผลให้กลุ่ม:"
 pageoptions_element_test_page = "ทดสอบหน้า"
diff --git a/src/locale/tl/configure.ini b/src/locale/tl/configure.ini
index dfc3bacb1..1849e4565 100644
--- a/src/locale/tl/configure.ini
+++ b/src/locale/tl/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Maghanap Ng Pagra-Ranggo Ng Mga Kadahilan
 pageoptions_element_host_keyword_bonus = "Mag-Host Ng Keyword Bonus:"
 pageoptions_element_title_bonus = "Bonus Ng Keyword Ng Pamagat"
 pageoptions_element_path_keyword_bonus = "Path Keyword Bonus"
+pageoptions_element_proximity_bonus = "Malapit Na Bonus:"
 pageoptions_element_cld_url_bonus = "Bonus Ng Url Ng Domain Ng Kumpanya:"
 pageoptions_element_host_url_bonus = "Host Url Bonus:"
+pageoptions_element_user_rank_bonus = "Bonus Sa Ranggo Ng Gumagamit:"
 pageoptions_element_results_grouping_options = "Mga Resulta Ng Paghahanap Ng Pagpapangkat"
 pageoptions_element_min_results_to_group = "Minimum na mga Resulta sa Grupo:"
 pageoptions_element_test_page = "Pahina Ng Pagsubok"
diff --git a/src/locale/tr/configure.ini b/src/locale/tr/configure.ini
index 5800d39bc..19839537b 100755
--- a/src/locale/tr/configure.ini
+++ b/src/locale/tr/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Arama Sıralaması Fakt&ouml;rler"
 pageoptions_element_host_keyword_bonus = "Ana Anahtar Kelime Bonusu :"
 pageoptions_element_title_bonus = "Başlık Anahtar Kelime Bonusu"
 pageoptions_element_path_keyword_bonus = "Path Anahtar Kelime Bonusu"
+pageoptions_element_proximity_bonus = "Yakınlık Bonusu :"
 pageoptions_element_cld_url_bonus = "Şirket Alan Adı Url Bonusu :"
 pageoptions_element_host_url_bonus = "Ana Bilgisayar Url Bonusu :"
+pageoptions_element_user_rank_bonus = "Kullanıcı Sıralaması Bonusu :"
 pageoptions_element_results_grouping_options = "Arama Sonu&ccedil;ları Gruplandırma"
 pageoptions_element_min_results_to_group = "Minimum Sonu&ccedil;lar Grup i&ccedil;in:"
 pageoptions_element_test_page = "Test Sayfası"
diff --git a/src/locale/vi_VN/configure.ini b/src/locale/vi_VN/configure.ini
index 1bf797710..4ce08aa5b 100755
--- a/src/locale/vi_VN/configure.ini
+++ b/src/locale/vi_VN/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "Tìm Bảng Xếp Hạng Các Yếu Tố"
 pageoptions_element_host_keyword_bonus = "Máy Chủ Từ Khóa Thưởng:"
 pageoptions_element_title_bonus = "Tiêu Đề Tiền Thưởng Từ Khóa"
 pageoptions_element_path_keyword_bonus = "Con Đường Từ Khóa Tiền Thưởng"
+pageoptions_element_proximity_bonus = "Gần Thưởng:"
 pageoptions_element_cld_url_bonus = "Công Ty Miền Url Thưởng:"
 pageoptions_element_host_url_bonus = "Chủ Url Thưởng:"
+pageoptions_element_user_rank_bonus = "Sử Dụng Cấp Bậc Tiền Thưởng:"
 pageoptions_element_results_grouping_options = "Kết Quả Tìm Kiếm Nhóm"
 pageoptions_element_min_results_to_group = "Kết Quả tối thiểu để Nhóm:"
 pageoptions_element_test_page = "Kiểm Tra Trang"
diff --git a/src/locale/vi_VN/statistics.txt b/src/locale/vi_VN/statistics.txt
index 5a165df53..b6bef56f0 100755
--- a/src/locale/vi_VN/statistics.txt
+++ b/src/locale/vi_VN/statistics.txt
@@ -1 +1 @@
-d:100;
\ No newline at end of file
+d:99;
\ No newline at end of file
diff --git a/src/locale/zh_CN/configure.ini b/src/locale/zh_CN/configure.ini
index 4523d4b4b..10382a527 100755
--- a/src/locale/zh_CN/configure.ini
+++ b/src/locale/zh_CN/configure.ini
@@ -1389,8 +1389,10 @@ pageoptions_element_ranking_factors = "搜索排的因素"
 pageoptions_element_host_keyword_bonus = "主机关键字奖励:"
 pageoptions_element_title_bonus = "标题关键字奖金"
 pageoptions_element_path_keyword_bonus = "路径关键字奖励"
+pageoptions_element_proximity_bonus = "接近奖励:"
 pageoptions_element_cld_url_bonus = "公司域名Url奖金:"
 pageoptions_element_host_url_bonus = "主机Url奖金:"
+pageoptions_element_user_rank_bonus = "用户等级奖金:"
 pageoptions_element_results_grouping_options = "搜索结果的分组"
 pageoptions_element_min_results_to_group = "最低结果,小组:"
 pageoptions_element_test_page = "测试页"
diff --git a/src/models/PhraseModel.php b/src/models/PhraseModel.php
index 2e9c6a65f..7ae9d89ad 100755
--- a/src/models/PhraseModel.php
+++ b/src/models/PhraseModel.php
@@ -1273,8 +1273,16 @@ class PhraseModel extends ParallelModel
             // initialize scores
             $sort_start = microtime(true);
             $max_user_ranks = 0;
+            $ranking_factors["PROXIMITY_BONUS"] ??= C\PROXIMITY_BONUS;
+            $ranking_factors["USER_RANK_BONUS"] ??= C\USER_RANK_BONUS;
             for ($i = 0; $i < $result_count; $i++) {
-                $pages[$i]["OUT_SCORE"] = 0;
+                $pages[$i]["OUT_SCORE"] = $pages[$i][self::SCORE];
+                $pages[$i][self::PROXIMITY] ??= 0;
+                $pages[$i][self::PROXIMITY] *=
+                    $ranking_factors["PROXIMITY_BONUS"];
+                if ($use_proximity) {
+                    $pages[$i]["OUT_SCORE"] += $pages[$i][self::PROXIMITY];
+                }
                 if (isset($pages[$i][self::USER_RANKS])) {
                     $j = count($pages[$i][self::USER_RANKS]);
                     if ($max_user_ranks < $j) {
@@ -1286,63 +1294,21 @@ class PhraseModel extends ParallelModel
                 for ($i = 0; $i < $result_count; $i++) {
                     for ($j = 0; $j < $max_user_ranks; $j++) {
                         if (isset($pages[$i][self::USER_RANKS][$j])) {
-                            $pages[$i]["USCORE$j"] = floatval(number_format(
+                            $pages[$i]["USCORE$j"] =
+                                $ranking_factors["USER_RANK_BONUS"] *
+                                floatval(number_format(
                                 $pages[$i][self::USER_RANKS][$j]['SCORE'] ?? 0,
                                 4, '.', ''));
+                            $pages[$i]["OUT_SCORE"] += $pages[$i]["USCORE$j"];
                         } else {
+                            // might want to print all scores
                             $pages[$i]["USCORE$j"] = 0;
                         }
                     }
                 }
             }
-            $subscore_fields = [self::SCORE];
-            if ($use_proximity) {
-                $subscore_fields[] = self::PROXIMITY;
-            }
-            if ($max_user_ranks > 0) {
-                for ($j = 0; $j < $max_user_ranks; $j++) {
-                    $subscore_fields[] = "USCORE$j";
-                }
-            }
-            $num_fields = count($subscore_fields);
-            if ($num_fields > 1) {
-                // Compute Reciprocal Rank Fusion Score
-                $alpha = 400/$num_fields;
-                if (isset($pages[0])) {
-                    foreach ($subscore_fields as $field) {
-                        L\orderCallback($pages[0], $pages[0], $field);
-                        usort($pages, C\NS_LIB . "orderCallback");
-                        $score = 0;
-                        for ($i = 0; $i < $result_count; $i++) {
-                            if ($i > 0) {
-                                if ($pages[$i - 1][$field] !=
-                                    $pages[$i][$field]) {
-                                    $score++;
-                                }
-                            }
-                            $pages[$i]["OUT_SCORE"] += $alpha/(59 + $score);
-                        }
-                    }
-                    L\orderCallback($pages[0], $pages[0], "OUT_SCORE");
-                }
-                usort($pages, C\NS_LIB . "orderCallback");
-                if ($use_proximity) {
-                    for ($i = 0; $i < $result_count; $i++) {
-                        $pages[$i][self::SCORE] = $pages[$i]["OUT_SCORE"];
-                    }
-                } else {
-                    for ($i = 0; $i < $result_count; $i++) {
-                        $pages[$i][self::PROXIMITY] = 0;
-                        $pages[$i][self::SCORE] = $pages[$i]["OUT_SCORE"];
-                    }
-                }
-            } else if(isset($pages[0])) {
-                L\orderCallback($pages[0], $pages[0], self::SCORE);
-                usort($pages, C\NS_LIB . "orderCallback");
-                for ($i = 0; $i < $result_count; $i++) {
-                    $pages[$i][self::PROXIMITY] = 0;
-                }
-            }
+            L\orderCallback($pages[0], $pages[0], "OUT_SCORE");
+            usort($pages, C\NS_LIB . "orderCallback");
             $sort_time = L\changeInMicrotime($sort_start);
         }
         if ($num_retrieved < $to_retrieve) {
diff --git a/src/models/ProfileModel.php b/src/models/ProfileModel.php
index 47732e571..f7e742237 100755
--- a/src/models/ProfileModel.php
+++ b/src/models/ProfileModel.php
@@ -61,16 +61,16 @@ class ProfileModel extends Model
         'MAIL_SENDER', 'MAIL_SERVER', 'MAIL_SERVERPORT', 'MAIL_USERNAME',
         'MIN_RESULTS_TO_GROUP',  'MONETIZATION_TYPE', 'MORE_RESULT',
         'MEDIA_MODE', 'NAME_SERVER', 'PATH_KEYWORD_BONUS',
-        'PRIVATE_DB_NAME', 'PRIVATE_DB_HOST',
-        'PRIVATE_DBMS', 'PRIVATE_DB_PASSWORD', 'PRIVATE_DB_USER',
-        'PROXY_SERVERS', 'RECOVERY_MODE', 'REGISTRATION_TYPE', 'RESULT_SCORE',
+        'PRIVATE_DB_NAME', 'PRIVATE_DB_HOST', 'PRIVATE_DBMS',
+        'PRIVATE_DB_PASSWORD', 'PRIVATE_DB_USER', 'PROXY_SERVERS',
+        'PROXIMITY_BONUS', 'RECOVERY_MODE', 'REGISTRATION_TYPE', 'RESULT_SCORE',
         'ROBOT_INSTANCE','RSS_ACCESS', 'SEARCH_ANALYTICS_MODE',
         'SEARCHBAR_PATH', 'SEND_MAIL_MEDIA_UPDATER',
         'SESSION_NAME', 'SIDE_ADSCRIPT', 'SIDEBAR_COLOR', 'SIGNIN_LINK',
         'SIMILAR_LINK', 'SUBSEARCH_LINK', 'TITLE_BONUS', 'TIMEZONE',
         'TOPBAR_COLOR', 'TOP_ADSCRIPT','TOR_PROXY', 'USE_FILECACHE',
-        'USE_MAIL_PHP', 'USE_PROXY', 'USER_AGENT_SHORT', 'WEB_URI',
-        'WEB_ACCESS', 'WORD_CLOUD', 'WORD_SUGGEST'
+        'USE_MAIL_PHP', 'USE_PROXY', 'USER_AGENT_SHORT', 'USER_RANK_BONUS',
+        'WEB_URI', 'WEB_ACCESS', 'WORD_CLOUD', 'WORD_SUGGEST'
         ];
     /**
      * Profile fields which are stored in wiki or in a flat file
diff --git a/src/views/elements/PageoptionsElement.php b/src/views/elements/PageoptionsElement.php
index f4ab25b4b..453b69502 100644
--- a/src/views/elements/PageoptionsElement.php
+++ b/src/views/elements/PageoptionsElement.php
@@ -533,6 +533,11 @@ class PageOptionsElement extends Element
             <input type="text" id="path-keyword-bonus" class="very-narrow-field"
                 maxlength="<?= C\NUM_FIELD_LEN ?>" name="PATH_KEYWORD_BONUS"
                 value="<?= $data['PATH_KEYWORD_BONUS']  ?>" /></td></tr>
+        <tr><th><label for="proximity-bonus"><?=
+            tl('pageoptions_element_proximity_bonus')?></label></th><td>
+            <input type="text" id="proximity-bonus" class="very-narrow-field"
+                maxlength="<?= C\NUM_FIELD_LEN ?>" name="PROXIMITY_BONUS"
+                value="<?= $data['PROXIMITY_BONUS'] ?>" /></td></tr>
         <tr><th><label for="cld-url-bonus"><?=
             tl('pageoptions_element_cld_url_bonus')?></label></th><td>
             <input type="text" id="cld-url-bonus" class="very-narrow-field"
@@ -543,6 +548,11 @@ class PageOptionsElement extends Element
             <input type="text" id="host-url-bonus" class="very-narrow-field"
                 maxlength="<?= C\NUM_FIELD_LEN ?>" name="HOST_URL_BONUS"
                 value="<?= $data['HOST_URL_BONUS'] ?>" /></td></tr>
+        <tr><th><label for="user-rank-bonus"><?=
+            tl('pageoptions_element_user_rank_bonus')?></label></th><td>
+            <input type="text" id="user-rank-bonus" class="very-narrow-field"
+                maxlength="<?= C\NUM_FIELD_LEN ?>" name="USER_RANK_BONUS"
+                value="<?= $data['USER_RANK_BONUS'] ?>" /></td></tr>
         </table>
         <h2><?= tl('pageoptions_element_results_grouping_options') ?>
         <?= $this->view->helper("helpbutton")->render(
ViewGit