Commit 4ee564a5 authored by Sebastien ANDRE's avatar Sebastien ANDRE
Browse files

dev #110215 : more relevant search

* titles, authors, dewey, ... indexation : exact all exact labels are
kept and indexed before phonetic. Articles are no longer dismissed
* authors indexation : in order to find "miles davis" AND "davis
miles", authors are indexed like this: "name firstname name"
* simple search: exact expression has more relevance and passes the
"dancing queen" test
* search by expression: users can now search an exact expression using
double quotes. In this case, if no result found, search is not extended
* Remove unused cosmogramme screen : Dewey & PCDM4
* fix bug when search widget keep last search : always unset pertinence to not extend search
parent fd5176ae
Pipeline #17391 passed with stage
in 79 minutes and 1 second
'110215' =>
['Label' => $this->_('Evolution du moteur de recherche'),
'Desc' => $this->_('Indexation plus large des titres, auteurs, sujets... pour améliorer la pertinence de la recherche. Introduction de la recherche par expression, en mettant plusieurs mots entre "". Nécessite un export total du SIGB'),
'Image' => '',
'Video' => '',
'Category' => $this->_('Moteur de recherche'),
'Right' => function($feature_description, $user) {return true;},
'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=Indexation_et_Recherche#Pond.C3.A9ration_et_classement_des_r.C3.A9sultats',
'Test' => '',
'Date' => '2022-02-24'],
\ No newline at end of file
- fonctionnalité #110215 : Moteur de recherche : Indexation plus large des titres, auteurs, sujets... pour améliorer la pertinence de la recherche. Introduction de la recherche par expression, en mettant plusieurs mots entre "". Nécessite un export total du SIGB
\ No newline at end of file
......@@ -41,8 +41,6 @@ if($_SESSION["passe"] == "catalogueur")
<?php
ligneMenu("Auteurs","codif_auteur.php");
ligneMenu("Matières","codif_matiere.php");
ligneMenu("Indices Dewey","codif_dewey.php");
ligneMenu("Indices PCDM4","codif_pcdm4.php");
?>
<div class="menu_section">Statistiques</div>
<?php
......@@ -106,8 +104,6 @@ else
ligneMenu("Emplacements", '../cosmozend/cosmo/emplacement');
ligneMenu("Auteurs","codif_auteur.php");
ligneMenu("Matières","codif_matiere.php");
ligneMenu("Indices Dewey","codif_dewey.php");
ligneMenu("Indices PCDM4","codif_pcdm4.php");
ligneMenu("Facettes dynamiques","../cosmozend/cosmo/facets/index");
?>
<div class="menu_section">Statistiques</div>
......@@ -143,4 +139,4 @@ function ligneMenu( $texte, $url,$confirmation=false)
print($texte);
print('</a></div>');
}
?>
\ No newline at end of file
?>
<?PHP
/**
* Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class dewey {
public function getIndicesSanslibelle($indice, $limite) {
global $sql;
$liste = [];
if ($indice)
$where = "and id_dewey like '$indice%'";
$handle = $sql->prepareListe("Select id_dewey from codif_dewey Where LENGTH(id_dewey)=$limite and libelle ='' ".$where." order by id_dewey");
while ($indice = $sql->fetchNext($handle,true))
$liste[] = $this->formatIndice($indice);
return $liste;
}
static function getIndices($pere) {
global $sql;
if ($pere == "root")
return $sql->fetchAll("select * from codif_dewey where LENGTH(id_dewey)=1 order by id_dewey");
$long = strlen($pere)+1;
$req = "select * from codif_dewey where id_dewey like '$pere%' and LENGTH(id_dewey)=$long order by id_dewey";
return $sql->fetchAll($req);
}
static function formatIndice($indice) {
if(strlen($indice)< 4)
return $indice;
$new = '';
while(strlen($indice) > 3) {
$new .= substr($indice,0,3) . ".";
$indice = substr($indice, 3, strlen($indice));
}
return $new . $indice;
}
static function filtreIndice($indice) {
$indice = trim($indice);
if(strlen($indice) > 18)
return false;
if(substr($indice,1,1) == ".")
return ''; // si c'est de la pcdm4 on dégage
$new = '';
for($i=0; $i < strlen($indice); $i++) {
$car = $indice[$i];
if ($car >= "0" and $car <= "9")
$new .= $car;
}
return $new;
}
static function getLibelle($indice) {
global $sql;
$libelle = $sql->fetchOne("select libelle from codif_dewey where id_dewey='$indice'");
if(!$libelle)
$libelle = dewey::formatIndice($indice) . " - intitulé non renseigné";
return $libelle;
}
public function ecrire($indice, $libelle) {
global $sql;
$indice = trim($indice);
$indice = str_replace(".", "", $indice);
$libelle = trim(str_replace("'", "''", $libelle));
if($indice == "")
return false;
$controle = $sql->fetchOne("select count(*) from codif_dewey where id_dewey='$indice'");
if (0 == $controle) {
$sql->execute("insert into codif_dewey (id_dewey,libelle) Values('$indice','$libelle')");
return 1;
}
// Maj du libelle
$sql->execute("Update codif_dewey set libelle='$libelle' Where id_dewey='$indice'");
// Maj des mots-recherche pour le nouveau libelle
$this->majFulltext($indice);
return 1;
}
public function majFulltext($indice) {
global $sql;
require_once("classe_indexation.php");
$ix = new indexation();
$indice = trim($indice);
$indice = str_replace(".","",$indice);
$code = "+D".$indice;
$liste = $sql->prepareListe("select id_notice,facettes from notices where match(facettes) against('".$code."' IN BOOLEAN MODE)");
if(!$liste)
return;
while($ligne = $sql->fetchNext($liste))
$this->_updateRecord($ligne, $ix);
}
protected function _updateRecord($ligne, $ix) {
global $sql;
$id_notice = $ligne["id_notice"];
$facets = explode(" ", $ligne["facettes"]);
foreach ($faces as $facet) {
if (!$facet)
continue;
$code = substr($facet, 0, 1);
$map = ['D' => 'dewey', 'P' => 'pcdm4'];
if (!array_key_exists($code, $map))
continue;
$value = substr($facet, 1);
if ($libelle = $sql->fetchOne("select libelle from codif_". $map[$code] . " where id_" . $map[$code] . "='" . $value ."'"))
$fulltext .= ' ' . $libelle;
}
$fulltext = $ix->getFulltext($fulltext);
$sql->execute("update notices set dewey='$fulltext' where id_notice=$id_notice");
}
}
?>
\ No newline at end of file
......@@ -20,16 +20,16 @@
*/
class indexation extends Class_Indexation {
protected static $phonetixCache = [];
protected static $phonetixCache = [];
public function phonetix($sIn) {
if (strlen($sIn)<4 || is_numeric($sIn))
return false;
public function phonetix(string $sIn) : string {
if (strlen($sIn)<4 || is_numeric($sIn))
return '';
return isset(static::$phonetixCache[$sIn])
? static::$phonetixCache[$sIn]
: static::$phonetixCache[$sIn] = $this->phonetixCompute($sIn);
}
return isset(static::$phonetixCache[$sIn])
? static::$phonetixCache[$sIn]
: static::$phonetixCache[$sIn] = $this->phonetixCompute($sIn);
}
}
?>
\ No newline at end of file
?>
......@@ -99,6 +99,7 @@ class notice_archive_calice
$notice["collation"] = $this->getCollation();
$notice["notes"] = $this->getNotes();
$notice["exportable"] = true;
$notice['other_terms'] = [];
// clefs d'index
$notice["alpha_titre"]=$this->indexation->codeAlphaTitre($notice["titre_princ"]." ".$notice["tome_alpha"]);
......@@ -211,11 +212,9 @@ class notice_archive_calice
// ----------------------------------------------------------------
// Collection
// ----------------------------------------------------------------
public function getCollection()
{
return trim($this->champs[7]);
}
public function getCollection() : array {
return [trim($this->champs[7])];
}
// ----------------------------------------------------------------
// Notes
// ----------------------------------------------------------------
......
......@@ -110,7 +110,7 @@ class notice_ascii
$notice["titres"]="";
$notice["auteurs"]=$this->enreg["auteurs"];
$notice["editeur"]=$this->enreg["editeur"];
$notice["collection"]=$this->enreg["collection"];
$notice["collection"] = [$this->enreg["collection"]];
$notice["matieres"]=$this->enreg["matieres"];
$notice["tome_alpha"] = $this->enreg["tome_alpha"];
$notice["annee"] = $this->enreg["annee"];
......@@ -119,6 +119,7 @@ class notice_ascii
$notice["data"] = $this->enreg["data"];
$notice["warnings"]=array();
$notice["id_commerciale"] = '';
$notice['other_terms'] = [];
if($this->enreg["isbn"])
{
......@@ -191,4 +192,4 @@ class notice_ascii
return $this->erreur;
}
}
?>
\ No newline at end of file
?>
......@@ -91,6 +91,7 @@ class notice_avenio {
$notice['titre_princ'] = $notice['titres'][0];
$notice['auteurs'] = $this->getAuteurs();
$notice['auteurs_renvois'] = [];
$notice['other_terms'] = [];
$notice['editeur'] = $this->getEditeur();
$notice['lieu_edition'] = $this->getLieuEdition();
$notice['collection'] = $this->getCollection();
......@@ -210,8 +211,8 @@ class notice_avenio {
}
public function getCollection(){
return trim($this->champs[10]);
public function getCollection() : array {
return [trim($this->champs[10])];
}
......
......@@ -588,12 +588,12 @@ class notice_integration {
'titres' => $this->indexation->getfullText(array_merge($this->notice['titres'],
[$this->notice['clef_chapeau'],
$this->notice['tome_alpha']])),
'auteurs' => $this->indexation->getfullText($this->_getFulltextAuthors()),
'other_terms'=> $this->indexation->getfulltext($this->notice['other_terms']),
'editeur' => $this->indexation->getfullText($this->notice['editeur']),
'collection' => $this->indexation->getfullText($this->notice['collection']),
'matieres' => $this->indexation->getfullText($this->_getFulltextSubjects()),
'dewey' => $this->indexation->getfullText($this->notice['full_dewey']),
'auteurs' => $this->indexation->getFullTextAuthor($this->_getFulltextAuthors()),
'other_terms'=> $this->indexation->getFulltext($this->notice['other_terms']),
'editeur' => $this->indexation->getFulltext($this->_getFulltextPublisher()),
'collection' => $this->indexation->getFulltext($this->notice['collection']),
'matieres' => $this->indexation->getFulltext($this->_getFulltextSubjects()),
'dewey' => $this->indexation->getFulltext($this->notice['full_dewey']),
'file_content' => $this->notice['file_content'],
'facettes' => $this->notice['facettes'],
'isbn' => $this->notice['isbn'],
......@@ -621,9 +621,9 @@ class notice_integration {
}
protected function _getFulltextAuthors() {
protected function _getFulltextAuthors() : array {
if (!$this->notice['auteurs'])
return $this->notice["200_f"];
return $this->notice["200_f"] ?? [];
return array_merge($this->notice["auteurs"],
$this->notice["auteurs_renvois"],
......@@ -631,7 +631,14 @@ class notice_integration {
}
protected function _getCodifAuteurRenvois() {
protected function _getFulltextPublisher() : array {
return is_array($this->notice['editeur'])
? $this->notice['editeur']
: [$this->notice['editeur']];
}
protected function _getCodifAuteurRenvois() : array {
$see_also = [];
foreach($this->notice['auteurs'] as $author) {
if (($codif = $this->_getCodifAuthorFor($author))
......@@ -643,9 +650,9 @@ class notice_integration {
}
protected function _getFulltextSubjects() {
protected function _getFulltextSubjects() : array {
if (!$this->notice['matieres'])
return ;
return [];
return array_merge($this->notice["matieres"],
$this->notice["matieres_renvois"],
......@@ -653,7 +660,7 @@ class notice_integration {
}
protected function _getCodifSubjectsRenvois() {
protected function _getCodifSubjectsRenvois() : array {
$see_also = [];
foreach($this->notice['matieres'] as $subject) {
......@@ -923,7 +930,7 @@ class notice_integration {
}
public function traiteFacettes($id_notice=null) {
public function traiteFacettes($id_notice=null) : self {
$facettes = [];
// Tags
......@@ -937,7 +944,7 @@ class notice_integration {
}
// Dewey
$this->notice["full_dewey"] = '';
$this->notice["full_dewey"] = [];
if($this->notice["dewey"])
{
foreach($this->notice["dewey"] as $indice)
......@@ -949,7 +956,7 @@ class notice_integration {
}
$this->notice["full_dewey"] .= $dewey->getLibelle()." ";
$this->notice["full_dewey"] [] = $dewey->getLibelle();
$facettes[]= $dewey->asFacet();
}
}
......@@ -973,7 +980,7 @@ class notice_integration {
if (empty($thesaurus))
continue;
if ($thesaurus->getLibelle())
$this->notice["full_dewey"] .= $thesaurus->getLibelle().' ';
$this->notice["full_dewey"] [] = $thesaurus->getLibelle();
$facettes[]= $thesaurus->asFacet();
}
}
......@@ -1008,7 +1015,7 @@ class notice_integration {
}
$facettes[] = $centre_interet->asFacet();
$this->notice["full_dewey"] .= $interet." ";
$this->notice["full_dewey"] [] = $interet;
}
}
......@@ -1031,7 +1038,7 @@ class notice_integration {
{
$facettes[]= Class_CodifGenre::CODE_FACETTE . $genre;
if ($codif_genre = Class_CodifGenre::find($genre))
$this->notice["full_dewey"] .= ' ' . $codif_genre->getLibelle();
$this->notice["full_dewey"] [] = $codif_genre->getLibelle();
}
}
......@@ -1043,13 +1050,14 @@ class notice_integration {
// Maj enreg facette
$this->notice["facettes"] = trim(implode(' ', array_unique($facettes)));
return $this;
}
protected function _processPCDM4($indice) {
$pcdm4 = Class_CodifPcdm4::getOrCreate($indice);
$this->notice["full_dewey"] .= $pcdm4->getLibelle()." ";
$this->notice["full_dewey"] [] = $pcdm4->getLibelle();
return $pcdm4->getFacetCode();
}
......
......@@ -21,8 +21,6 @@
require_once 'classe_profil_donnees.php';
require_once 'classe_iso2709.php';
require_once 'classe_dewey.php';
require_once 'classe_pcdm4.php';
require_once 'classe_indexation.php';
require_once("Class/Isbn.php");
require_once 'classe_codif_cache.php';
......@@ -1408,7 +1406,7 @@ class notice_unimarc extends iso2709_record {
$sous_champs = $this->decoupe_bloc_champ($items);
foreach ($sous_champs as $item)
if (($item['code'] == 'a')
&& ($indice = dewey::filtreIndice($item['valeur'])))
&& ($indice = Class_CodifDewey::filtreIndice($item['valeur'])))
$dewey[] = $indice;
}
return $dewey;
......@@ -1474,7 +1472,7 @@ class notice_unimarc extends iso2709_record {
}
public function getEditeur() {
public function getEditeur() : string {
return (new Class_Notice_Editeur($this))->getFirstEditeur();
}
......@@ -1556,7 +1554,7 @@ class notice_unimarc extends iso2709_record {
}
public function getCollection() {
public function getCollection() : array {
$data = $this->get_subfield(225, 'a');
if(!count($data))
$data = $this->get_subfield(410, 't');
......
<?PHP
/**
* Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
///////////////////////////////////////////////////////////////////
//
// GESTION DES INDICES DEWEY
//
////////////////////////////////////////////////////////////////////
include("_init_frame.php");
require_once("classe_dewey.php");
$dewey = new dewey();
extract($_POST);
?>
<script>
function give_libelle(sIndice,sValeur)
{
if(sValeur == "") return;
oChampRetour=document.getElementById("indice_a_ecrire");
oChampRetour.value=oChampRetour.value + sIndice + "#" + sValeur + ";";
}
function give_suppression()
{
oChampRetour=document.getElementById("indice_a_ecrire");
chaine="";
for (var i=0;i<document.getElementsByName("selection").length;i++)
{
if (document.getElementsByName("selection")[i].checked==true)
{
if(chaine > '') chaine=chaine+";";
chaine=chaine+document.getElementsByName("selection")[i].id;
}
}
oChampRetour.value=oChampRetour.value=chaine;
}
</script>
<?PHP
// ----------------------------------------------------------------
// ACCUEIL
// ----------------------------------------------------------------
if($_REQUEST["action"]=="")
{
print('<h1>Gestion des indices Dewey</h1>');
$nb=$sql->fetchOne("Select count(*) from codif_dewey");
$nb1=$sql->fetchOne("Select count(*) from codif_dewey where libelle=''" );
print('<span class="orange"><b>La base contient '.number_format($nb, 0, ',', ' ').' fiches Dewey</b></span>'.BR);
print('<span class="orange"><b>Libellés non renseignés : '.number_format($nb1, 0, ',', ' ').'</b></span>'.BR.BR);
print('<div class="liste" style="width:700px">');
$url="codif_dewey.php?action=NOLIB";
print('<form id="nolib" method="post" action="'.$url.'">');
print('<table width="60%" cellspacing="0">');
print('<tr><th align="left" width="50%">Indices sans libellés</th>');
print('<th align="right"><input type="submit" class="bouton" value="Lancer">&nbsp;&nbsp;&nbsp;</th>');
print('</tr>');
print('<tr>');
print('<td align="right">Nombre de décimales:&nbsp;</td>');
print('<td><input type ="text" name="nbdec" value="3" size="3" align="left"></td>');
print('</tr>');
print('</table></form>'.BR);
$url="codif_dewey.php?action=MAJ";
print('<form id="suppression" method="post" action="'.$url.'">');
print('<table width="60%" cellspacing="0">');
print('<tr><th align="left" width="50%">Modification de libellés</th>');
print('<th align="right"><input type="submit" class="bouton" value="Lancer">&nbsp;&nbsp;&nbsp;</th>');
print('</tr>');
print('<tr>');
print('<td align="right">Nombre de décimales:&nbsp;</td>');
print('<td><input type ="text" name="nbdec" value="3" size="3" align="left"></td>');
print('</tr>');
print('<tr>');
print('<td align="right">Indices commencent par:&nbsp;</td>');
print('<td><input type ="text" name="commencepar" value="" size="7" align="left"></td>');
print('</tr>');
print('</table></form>'.BR);
$url="codif_dewey.php?action=SUPPRESSION";
print('<form id="suppression" method="post" action="'.$url.'">');
print('<table width="60%" cellspacing="0">');
print('<tr><th align="left" width="50%">Suppression d\'indices</th>');
print('<th align="right"><input type="submit" class="bouton" value="Lancer">&nbsp;&nbsp;&nbsp;</th>');
print('</tr>');
print('<tr>');
print('<td align="right">Nombre de décimales:&nbsp;</td>');
print('<td><input type ="text" name="nbdec" value="3" size="3" align="left"></td>');
print('</tr>');
print('<tr>');
print('<td align="right">Indices commencent par:&nbsp;</td>');
print('<td><input type ="text" name="commencepar" value="" size="7" align="left"></td>');
print('</tr>');
print('</table></form>'.BR);
$url="codif_dewey.php?action=CONSOLIDATION";
print('<form id="consolidation" method="post" action="'.$url.'">');
print('<table width="60%" cellspacing="0">');
print('<tr><th align="left" width="70%">Consolidation par une liste d\'indices</th>');
print('<th align="right"><input type="submit" class="bouton" value="Lancer">&nbsp;&nbsp;&nbsp;</th>');
print('</tr>');
print('<tr>');
print('<td colspan="2" align="center"><input type ="checkbox" name="remplacer">Remplacer les libellés présents dans la base</td>');
print('</tr>');
print('</table></form>'.BR);
$url="codif_dewey.php?action=NIVEAUX";
print('<form id="niveaux" method="post" action="'.$url.'">');
print('<table width="60%" cellspacing="0">');
print('<tr><th align="left" width="70%">Création des niveaux intermédiaires</th>');
print('<th align="right"><input type="submit" class="bouton" value="Lancer">&nbsp;&nbsp;&nbsp;</th>');
print('</tr>');
print('<tr>');
print('<td colspan="2">Cette fonction créee les niveaux intermédiaires pour un bon fonctionnement de la recherche guidée</td>');
print('</tr>');
print('</table></form>'.BR);
}
// -----------