Implémentation d'un moteur de recherche facile à utiliser dans des entités de doctrine.
Pour une utilisation de base, tout ce que vous avez à faire est de définir une carte des entités recherchées et de leurs propriétés, le moteur de recherche organisera leur charge correctement et triera automatiquement les résultats de recherche en fonction des candidats trouvés.
Le but du package est de fournir une API simple pour la recherche avancée en texte intégral dans les entités de doctrine. Au début d'une demande, un schéma de recherche est construit et ce package garantit automatiquement que les meilleurs résultats sont trouvés et renvoyés en fonction de la pertinence.
Pour installer manuellement le compositeur d'appels de package et exécuter la commande suivante:
$ composer require baraja-core/doctrine-fulltext-search Puis enregistrer DoctrineFulltextSearchExtension dans la configuration néon:
extensions :
doctrineFulltextSearch : BarajaSearchDoctrineFulltextSearchExtension ou vous pouvez créer une instance de BarajaSearchSearch manuellement.
La recherche est effectuée en construisant une requête (entités de cartographie et colonnes):
$ results = $ this -> search -> search ( $ query , [
Article ::class => [ ' :title ' ],
User ::class => ' :username ' , // it can also be an ordinary string for a single column
UserLogin ::class => [ ' :ip ' , ' hostname ' , ' userAgent ' ],
]);
echo $ results ; // Uses the default HTML renderer Ou vous pouvez utiliser SelectorBuilder avec des validations de type strictes complètes et des méthodes d'article pour construire la requête:
$ results = $ this -> search -> selectorBuilder ( $ query )
-> addEntity ( Article ::class)
-> addColumnTitle ( ' title ' )
-> addEntity ( User ::class)
-> addColumnTitle ( ' username ' )
-> addEntity ( UserLogin ::class)
-> addColumnTitle ( ' ip ' )
-> addColumn ( ' hostname ' )
-> addColumnSearchOnly ( ' userAgent ' )
-> search ();
echo $ results ;Il n'est pas nécessaire d'échapper à la sortie, toute logique est résolu automatiquement par le moteur.
:username - La colonne sera utilisée comme légende
!slug - La colonne sera utilisée pour la recherche, mais ignorée dans la sortie PEREX.
_durationTime - La colonne sera chargée dans l'entité, mais ne sera pas prise en compte lors du calcul de la pertinence et ne sera pas incluse dans le PEREX.
content.versions.haystack - Une relation entre les entités crée automatiquement une jointure et charge la dernière propriété.
versions(content) - Custom Getter (rejoignez automatiquement la colonne versions , mais appelez getContent() pour obtenir les données).
Si nous utilisons un côlon au début du nom de la colonne (par exemple ':username' ), il sera automatiquement utilisé comme titre.
Le titre sera affiché même s'il ne contient pas les mots de recherche.
La légende peut être vide et peut ne pas exister (peut être null ).
Si le titre n'existe pas, le moteur peut automatiquement le calculer en fonction de la meilleure occurrence du texte trouvé.
La requête de recherche est automatiquement normalisée et les mots d'arrêt sont supprimés, pour lesquels il n'a pas de sens de rechercher.
L'algorithme peut être remplacé dans un projet spécifique en mettant en œuvre l'interface IQueryNormalizer et en l'écrassant dans le conteneur DIC.
La sortie de la méthode search() est une entité du type SearchResult , qui implémente l'interface Iterator pour la capacité de passer facilement à travers les résultats.
Astuce: Si vous avez juste besoin d'imprimer rapidement les résultats de la recherche et que les exigences d'apparence ne sont pas très élevées, l'entité
SearchResultimplémente directement la méthode__toString()pour un rendu facile des résultats directement sous forme de HTML.
Le résultat de la recherche résume tous les résultats de toutes les recherches dans toutes les entités. Tous les résultats sont obtenus par la méthode getItems() - la sortie sera un tableau d'entités du type SearchItem[] .
Cependant, nous devons souvent compiler une requête en vrac, puis énumérer séparément les catégories et les produits. Pour ce faire, utilisez la méthode d'assistance getItemsOfType(string $type) , qui renvoie un tableau tronqué de résultats de type SearchItem[] uniquement pour les entités selon le paramètre passé.
Nous avons utilisé la méthode getItems() ou getItemsOfType() pour obtenir les résultats de recherche que nous traversons. Mais comment travailler avec un résultat spécifique?
Il est important de noter qu'à ce stade, nous n'avons plus la méthode __toString() disponible et devons nous-même rendre le résultat (idéalement dans un modèle).
Pour la plupart des cas, les aides prêtes à l'emploi suffiront:
getTitle() Renvoie le titre de l'entité trouvée en tant que chaîne ou null.getTitleHighlighted() appelle getTitle() en interne, et si le résultat est une chaîne valide, il coche les occurrences de chaque mot avec <i class="highlight"> et </i> .getSnippet() renvoie un extrait de l'entité trouvée, qui résume la zone la plus trouvée de l'entité d'origine (par exemple, un extrait d'article où les mots de recherche se produisent). Plus d'extraits peuvent être retournés (les occurrences individuelles sont divisées par un côlon). Renvoie toujours une chaîne (peut être vide).getTitleHighlighted() appelle en interne getSnippet() et colore les occurrences de chaque mot avec <i class="highlight"> et </i> .getScore() renvoie le relatif (différent contextuel en fonction de la requête de recherche et des données disponibles dans chaque projet) évaluation de points du résultat (selon ce paramètre, les résultats sont automatiquement triés).getEntity() renvoie l'entité trouvée originale que la doctrine a produite en interne. La recherche est effectuée en utilisant une sélection partielle, donc toutes les propriétés ne peuvent pas toujours être disponibles.entityToArray() se retourne comme un tableau. Les cordes sont automatiquement normalisées. Les deux méthodes pour obtenir des résultats ( getItems() et getItemsOfType() ) acceptent les paramètres $limit (par défaut 10 ) et $offset (par défaut 0 ).
La pagination elle-même est mieux mise en œuvre à l'aide de la pagination de nette.
Le nombre total de résultats est obtenu par la méthode getCountResults() au-dessus de l'entité SearchResult .
Le moteur de recherche utilise PARTIAL pour charger des entités de base de données et enveloppe les entités résultantes en résultats de recherche, vous pouvez donc les charger à tout moment en appelant ->getEntity() au-dessus d'un résultat de recherche spécifique.
Si aucun résultat ne peut être trouvé, ou si leur nombre est "petit" (la définition est déterminée par l'algorithme lui-même en fonction de l'analyse d'un projet spécifique), une astuce pour la meilleure correction de la requête de recherche peut (et peut ne pas) être disponible.
Pour obtenir de l'aide, appelez la méthode getDidYouMean() sur SearchResult . La sortie est soit String (meilleure requête de recherche) ou NULL.
La meilleure correction de requête de recherche est obtenue par le moteur de recherche lui-même en fonction de l'analyse de recherche avancée dans chaque projet séparément à l'aide de méthodes d'apprentissage automatique . À chaque recherche, des statistiques sur la requête de recherche, le nombre de résultats et d'autres signaux sont automatiquement enregistrés et analysés rétrospectivement si nécessaire.
Obtenir de l'aide est naturel et ne peut pas être facilement influencé. Le moteur de recherche recherche une objectivité maximale et offre aux utilisateurs des mots qui recherchent d'autres et renvoient autant de résultats pertinents que possible en fonction du contexte actuel. En interne, des fonctions mathématiques complexes sont utilisées, ce que nous améliorons constamment en fonction de l'expérience de tous les projets.
Lors de la recherche, une liste de candidats pour les résultats de recherche est d'abord compilée. Ces résultats sont transmis individuellement à travers un algorithme d'évaluation qui effectue une évaluation "relative" automatique dans la plage 0 à 512 (sur la base de divers signaux tels que la requête de recherche, l'historique récent, le langage, l'emplacement physique, le contenu et le type d'entité) (le résultat est toujours int ).
Selon l'évaluation des points, les résultats sont automatiquement triés.
L'algorithme de notation peut être remplacé en implémentant l'interface IScoreCalculator et en l'écrassant dans le conteneur DIC.
baraja-core/doctrine-fulltext-search est autorisé sous la licence MIT. Voir le fichier de licence pour plus de détails.