Mettre un ordre des objets dans le résultat d'une recherche globale

Tags: #<Tag:0x00007f9e5b5305b0>

Bonjour,

J’ai bien noté que la recherche indexée globale = rechercher dans les attributs indexés des objets indexés qui sont accessibles au user connecté dans le scope courant.
Ma question est : serait il possible de mettre un ordre dans le résultat d’une recherche ? Exemple : Je voudrais qu’il affiche d’abord les lignes trouvées de l’objet A d’abord, ensuite celles de l’objet B…
Merci d’avance.
Abed

Votre question concerne la pondération / scoring des objets trouvés.
Il n’y a pas de coefficient de pondération par objet ou par record. Le poids est donné par la clé fonctionnelle uniquement.

Simplicité donne une meilleure note aux items dont la clé fonctionnelle matche avec la recherche, puis aux autres données indexées.

Sinon il y a un hook des objets trouvés avant affichage :

GrantHooks.postSearchIndex(grant, items)

qui retourne une liste d’items que vous pouvez trier, sans que ça prenne 10 secondes.

On pourrait modéliser un poids dans la définition objet pour en favoriser certains.
Mais cela ne serait pas valable pour tout le monde, chaque utilisateur/profil/scope aura vite besoin d’avoir ses propres pondérations.

  • Un chef veut d’abord voir les statistiques du mois
  • Un opérationnel chercher des dossiers
  • Un admin les demandes de support
    etc

Ce serait donc complexe à modéliser et à paramétrer.
Notre approche est simple/agnostique en ne basant la pondération que sur la clé fonctionnelle de chaque objet.

Une autre demande est en cours pour permettre de faire une recherche indexée uniquement sur certains de ses objets habilités depuis la page de recherche globale :

Ce sera intégré à la V5.

1 Like

@francois,

J’ai mis en place le hook et j’obtiens pour un exemple le résultat suivant :

2020-04-09 19:31:08,479 INFO [com.simplicite.util.ScriptInterpreter] SIMPLICITE|http://e3m.simplicite.io:10158||INFO|system|com.simplicite.util.ScriptInterpreter|GrantHooks||Evénement: items = [com.simplicite.util.tools.SearchItem@47344555, com.simplicite.util.tools.SearchItem@7c112f4c]

En IHM :

Comment savoir quel items parmi 47344555 ou 7c112f4c correspondant à “Bien/Investisseur” par exemple, pour le mettre en premier résultat ? comment faire le lien entre le code de l’item et les objets fonctionnels concernés ?

Merci d’avance.

Bonsoir Abed,

nous avons un besoin similaire dans le cadre duquel nous parcourons la liste des rows (liste de searchItems).

Nous consultons le contenu ainsi:

console.log("Key: " + rows.get(j).key + " object " + rows.get(j).object + " score " + rows.get(j).score + " ukey: " + rows.get(j).ukey + " values: " + rows.get(j).values);

Bruno

Bonsoir @bmo,
Merci beaucoup pour l’info.
Abed.

C’est une liste d’objets Java, les attributs sont public :

en Rhino :
var item = rows.get(i);

en Java
SearchItem item = rows.get(i);

Cf
https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/tools/SearchItem.html

Bonjour,

Encore une dernière question (un peu bête, je l’avoue, mais je n’y arrive pas 😉) :

Je voudrais restructurer la liste SearchItem pour afficher les éléments d’un objet précis en premières positions. J’arrive à les identifier grâce au rows.get(j).object, mais comment forcer le score de ces éléments à une valeur fixe (1000 par exemple pour être sûr qu’ils sortiront en premier)? je n’arrive pas à utiliser le setValue, qu’elle est la syntaxe ?

Encore merci.

Le score est celui qui a été attribué et déjà trié.
Ce hook est là pour changer le résultat avant affichage, il n’y aura pas de nouveau tri même si vous changez les scores, il faut également permuter les objets de cette liste via les méthodes de List usuelles, ou préparer une nouvelle liste triée comme vous le souhaitez, par exemple :

List<SearchItem> list = new ArrayList<>();
for (SearchItem item : rows) {
   if ("myObject".equals(item.object)) {
       item.score = 99999;
       list.add(0, item); // en premier
   }
   else 
       list.add(item); // les autres en dernier
}
return list;

Merci @francois,
J’étais parti sur une mauvaise idée. Il ne faut donc pas que je cherche à changer le score mais plutôt à permuter les éléments dans la liste.

Encore merci.

Bonjour,

Serait-il possible d’afficher le résultat d’une recherche globale en liste avec ascenseur ?

Merci d’avance.
Abed.

Bonjour Abed,

Les résultats de recherche globale niveau plateforme renvoient tous types d’objets qui n’ont pas forcément les mêmes colonnes, il n’est donc pas possible d’afficher une liste sous forme de tableau avec ascenseur si c’est le sujet de la demande.

Vous pouvez par contre à cet effet utiliser la recherche globale au niveau de l’objet:

L’affichage se fait effectivement à base de vignettes car les objets ne sont pas de même nature lors d’une recherche globale.

La seule solution est donc de passer par du CSS si vous souhaitez changer l’affichage des div sans leur “masonry” façon Pinterest ou juste masquer des blocks (attributs, image, actions…) pour réduire leurs tailles, exemple :

.obj-grid {
    display: block !important;
    height: auto !important;
    overflow-x: hidden;
    overflow-y: auto;
}
.obj-grid .obj-grid-item {
    position: relative !important;
    display: block !important;
    float: none;
    width: 100% !important;
    top: 0 !important;
    left: 0 !important;
    margin: 0;
    padding: 5px 0;
}
.obj-summary .obj-fields { display: none; }
.obj-summary .obj-actions { display: none; }
.obj-summary .image { display: none; }

Vous aurez alors une liste scrollable des titres simples et dont 80% de l’écran ne contient rien :

ou utiliser des flexbox pour afficher les blocks d’une vignette en ligne plutôt qu’en vertical…

Bonjour,

Je voudrais savoir dans quel ordre sont traités les objets métiers lorsqu’on lance l’action « rebuildObjectIndex » ?

En effet, quand je fais une recherche, j’obtiens par exemple 50 résultats (ce qui correspond au paramètre « Taille maximale des listes » de mon user), or si les indexes de l’objet favoris qui m’intéresse se trouve à la fin de la création des indexes lors de l’exécution de rebuildObjectIndex, je n’aurais pas ses propositions, j’aurais les 50 premières propositions possibles.

Nous faisons actuellement un tri dans le postSearchIndex sur la liste searchItems pour l’afficher dans l’ordre souhaité, ce qui fonctionne bien, or avec la problématique ci-dessus, certaines propositions importantes ne sont pas présentes du tout dans la liste searchItems.

Donc ma question est : serait-il possible de proposer un ordre d’objets à traiter dans l’action rebuildObjectIndex histoire de mettre les objets favoris en premiers ? Je pars du principe que les objets favoris, le sont pour tous les users. J’ai bien noté aussi que même si on fait cela, les nouvelles créations/modifications des nouvelles lignes des objets favoris seront insérées à la fin et risquent de ne pas apparaître dans la liste searchItems, a moins de lancer l’action rebuildObjectIndex de temps en temps.

Ou mieux encore si possible, pouvoir intervenir lors de la création de la liste searchItems pour récupérer d’abord les propositions de nos objets favoris, avant de récupérer celles des autres (si on n’a pas encore atteint la limite « Taille maximale des listes ») ? « preSearchIndex » ?

Merci d’avance pour votre retour.

Abed.

1 Like

Bonjour, excusez-moi de m’incruster dans ce fil…

Nous avons les mêmes interrogations sur l’ordre “préféré” de retour des recherches plein texte.
Notre réflexion s’orientait sur le principe que les objets les plus intéressants sont souvent les objets métier de référence puis les objets qui les référencent (de la racine vers la feuille).

Cet “ordonnancement” du traitement des objets peut d’ailleurs correspondre à l’ordre documenté pour l’export dans la définition des objets métier (les référence d’abord, puis les relations ou autres objets reprenant ces références).

Nous avons par ailleurs aussi développé une solution spécifique permettant de filtrer les résultats de recherche pour réduire la portée d’une recherche plein texte sur une sélection spécifique d’objets propre à une page de groupe (indépendamment des droits d’accès de l’utilisateur courant).

Bonjour,

L’indexation est bête : elle stocke la clé fonctionnelle + un texte long des champs indéxables, il n’y pas d’habilitation. Le rebuildObjectIndex n’a strictement aucune notion d’ordre, il scanne tous les objets indexables et crée les paires “clé fonctionnelle + index full text” dans la table m_index.

C’est la recherche qui a une notion d’ordre comme suit :

  • elle dépend de la base données : contains sur oracle, match sur mysql, to_tsquery sur postgre, ou simple like%% (catastrophique en terme de perfs) sur hsqldb
  • Simplicité pondère avec un facteur 10 la clé fonctionnelle par rapport à l’index full text : si je cherche “Bob” ça ramène d’abord la personne “Bob” puis ses dossiers rattachés
  • puis Simplicité élague les objets non habilités : granted + select ok sur chaque row_id (pour appliquer les éventuelles search-spec)
  • et boucle jusqu’à la taille max des listes tant qu’il y a des résultats
  • Appel de postIndexSearch avec le résultat final

Prendre en compte la pondération/ordre d’export des objets est une approche possible mais ne répond pas au cas général : le cas de Bob et son dossier, on peut imaginer vouloir trouver un dossier plutôt que son propriétaire ou l’inverse.

Le seul cas général reste la clé fonctionnelle, donc si on veut trouver un dossier on rentre son numéro et pas Bob…

La difficulté est dans la “jointure ordonnée” avec les droits, car la pondération est en fonction de l’usage:

  • mes responsabilités : un DRH voudra trouver Bob en premier, un commercial plutôt son contrat
  • scope/application : ça rejoint les responsabilités actives si je suis à la fois DRH et commercial

Donc voilà différentes pistes d’amélioration possibles :

  • si on veut rendre paramétrable la pondération en fonction de l’usage, il faudra nécessairement la mettre dans la Fonction de lecture de l’objet = un groupe contient des fonctions de lecture, on peut en avoir plusieurs groupées suivant chaque groupe/usages.
  • et globalement avoir une pondération au niveau de l’objet (distinct de l’ordre d’export plus lié à l’intégrité référentielle) si la fonction n’en a pas (ou en sur-pondération ?)
  • au delà, il faudra créer un hook preSearchIndex pour indiquer les pondération de chaque objet avant le “select” en base

Ensuite il faut écrire l’équation de pondération de tout ça en SQL…