Maison >développement back-end >tutoriel php >PINQ - REQUIREZ VOTRE ensemble de données - Recherche à facettes

PINQ - REQUIREZ VOTRE ensemble de données - Recherche à facettes

Lisa Kudrow
Lisa Kudroworiginal
2025-02-20 12:29:14572parcourir

PINQ - REQUIREZ VOTRE ensemble de données - Recherche à facettes

Les plats clés

  • PINQ, un port PHP Linq, peut être utilisé pour imiter une fonction de recherche à facettes avec MySQL, offrant une approche puissante et simple.
  • Une recherche à facettes fonctionne en prenant des mots clés fournis par l'utilisateur pour rechercher des produits, en retournant des produits correspondants et en offrant des liens pour affiner la recherche en fonction de différentes marques, gammes de prix et fonctionnalités.
  • PINQ peut être utilisé pour étendre une application de démonstration en ajoutant des fonctionnalités de recherche à facettes essentielles, telles que le regroupement par une plage de valeur dans une étape spécifiée par $ gamme.
  • La recherche à facettes implémentée avec PINQ récupère les données du serveur MySQL à chaque fois, qui peut être évitée en utilisant un moteur de mise en cache.
  • Bien qu'il s'agisse d'une démo de base, l'approche de Pinq à la recherche à facettes offre beaucoup de place à l'amélioration et peut être construite sur des cas d'utilisation plus avancés.

Dans la partie 1, nous avons brièvement couvert l'installation et la syntaxe de base de PINQ, un port PHP LINQ. Dans cet article, nous verrons comment utiliser PINQ pour imiter une fonction de recherche à facettes avec mysql.

Nous n'allons pas couvrir le plein aspect de la recherche à facettes dans cette série. Les parties intéressées peuvent se référer aux articles pertinents publiés sur SitePoint et d'autres publications Internet.

Une recherche à facettes typique fonctionne comme celle-ci dans un site Web:

  • Un utilisateur fournit un mot-clé ou quelques mots clés à rechercher. Par exemple, «routeur» pour rechercher des produits contenant «routeur» dans la description, mot-clé, catégorie, balises, etc.
  • Le site renvoie les produits correspondant aux critères.
  • Le site fournira des liens pour affiner la recherche. Par exemple, il peut inciter à différentes marques pour un routeur, et il peut y avoir différentes gammes de prix et différentes fonctionnalités.
  • L'utilisateur peut être davantage filtrant les résultats en cliquant sur les différents liens fournis et finalement obtenir un ensemble de résultats plus personnalisé.

La recherche à facettes est si populaire et puissante et vous pouvez en faire l'expérience dans presque tous les site de commerce électronique.

Malheureusement, la recherche à facettes n'est pas encore une fonctionnalité intégrée fournie par MySQL. Que pouvons-nous faire si nous utilisons MySQL mais que nous voulons également fournir à nos utilisateurs une telle fonctionnalité?

Avec PINQ, nous verrons qu'il existe une approche tout aussi puissante et simple pour y parvenir comme lorsque nous utilisons d'autres moteurs DB - du moins d'une certaine manière.

Extension de la démo de la partie 1

Remarque: tout le code de cette partie et la démonstration de la partie 1 peuvent être trouvés dans le dépôt.

Dans cet article, nous prolongerons la démo que nous avons montrée dans la partie 1 et ajouterons certaines fonctionnalités de recherche à facettes essentielles.

Commençons par index.php en ajoutant les quelques lignes suivantes:

<span>$app->get('demo2', function () use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test2 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test2->test2($app, $demo->test1($app));
</span><span>}
</span><span>);
</span>
<span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test3 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test3->test3($app, $demo->test1($app), $key, $value);
</span><span>}
</span><span>);</span>

Nous venons de créer deux autres itinéraires dans notre application de démonstration (en utilisant Silex).

La première route consiste à nous amener à la page affichant tous les enregistrements qui correspondent à notre premier comportement de recherche, c'est-à-dire la recherche en fournissant un mot-clé. Pour garder la démo simple, nous sélectionnons tous les livres dans l'exemple de table book_book. Il affichera également l'ensemble de résultats et les liens à facettes pour une navigation supplémentaire.

Le deuxième itinéraire nous amène à une autre page montrant les enregistrements correspondant aux autres critères de recherche de facettes dans l'ensemble de résultats produit à l'étape ci-dessus. Il affichera également les liens de recherche à facettes.

Dans une implémentation du monde réel, une fois un lien à facettes cliqué, tout filtrage à facettes dans la page de résultats sera ajusté pour refléter les informations statistiques de l'ensemble de données de résultat. Ce faisant, l'utilisateur peut appliquer des dépistages «complémentaires», en ajoutant «marque» d'abord puis «gamme de prix», etc.

Mais dans cette démo simple, nous sauterons cette approche, toutes les recherches à facettes et les liens ne refléteront que les informations sur l'ensemble de données d'origine. Il s'agit de la première restriction et du premier domaine d'amélioration de notre démo.

Comme nous le voyons dans le code ci-dessus, les fonctions réelles résident dans un autre fichier appelé pinqdemo.php. Voyons le code pertinent qui fournit la fonction de recherche à facettes.

une classe facette

Tout d'abord, nous créons une classe pour représenter une facette. Généralement, une facette doit avoir quelques propriétés:

  • les données sur lesquelles il fonctionne ($ data)
  • La clé informatique se regroupe sur ($ key)
  • Le type de clé (type $). Cela peut être l'un des ci-dessous:
    • Spécifiez une chaîne complète pour faire une correspondance exacte
    • Spécifiez partiel (normalement en début) d'une chaîne pour faire une correspondance de modèle
    • Spécifiez une plage de valeur au groupe par une plage de valeur
  • Si le type de clé est une plage, il est nécessaire de spécifier une étape de valeur pour déterminer la limite supérieure / inférieure de la plage; ou si le type de clé est une chaîne partielle, nous devons fournir un numéro pour spécifier le nombre de premières lettres devraient être utilisées pour regrouper ($ gamme)

Le regroupement est la partie la plus critique d'une facette. Toutes les informations d'agrégation qu'une facette pourrait éventuellement retourner dépend des critères de «regroupement». Normalement, la «chaîne complète», la «chaîne partielle» et la «plage de valeur» sont les plus couramment utilisées.

<span>$app->get('demo2', function () use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test2 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test2->test2($app, $demo->test1($app));
</span><span>}
</span><span>);
</span>
<span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test3 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test3->test3($app, $demo->test1($app), $key, $value);
</span><span>}
</span><span>);</span>

Dans cette classe, la fonction clé consiste à renvoyer l'ensemble de résultats à facettes en fonction des données et des propriétés de clé de facette. Nous avons remarqué que pour différents types de clés, il existe différentes façons de regrouper les données. Dans ce qui précède, nous avons montré à quoi ressemblera le code si nous regroupons les données par une plage de valeur dans une étape spécifiée par $ plage.

Faire des facettes et affichage des données d'origine

<span>namespace classFacet
</span><span>{
</span>    <span>use Pinq<span>\ITraversable</span>,
</span>        Pinq\Traversable<span>;
</span>
    <span>class Facet
</span>    <span>{
</span>
        <span>public $data; // Original data
</span>        <span>public $key; // the field to be grouped on
</span>        <span>public $type; // F: full string; S: start of a string; R: range;
</span>        <span>public $range; // Only valid if $type is not F
</span>
		<span>...
</span>
        <span>public function getFacet()
</span>        <span>{
</span>            <span>$filter = '';
</span>
            <span>if ($this->type == 'F') // Full string 
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "S") //Start of string
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "R") // A value range
</span>            <span>{
</span>                <span>$filter = $this->data
</span>                        <span>->groupBy(function($row)
</span>                        <span>{
</span>                            <span>return floor($row[$this->key] / $this->range) * $this->range;
</span>                        <span>})
</span>                        <span>->select(function (ITraversable $data)
</span>                <span>{
</span>                    <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()];
</span>                <span>});
</span>            <span>}
</span>
            <span>return $filter;
</span>        <span>}
</span>    <span>}
</span><span>}</span>

Dans la fonction getfacet (), nous effectuons les étapes suivantes:

  • Convertir les données d'origine en un objet PINQTraversable pour un traitement ultérieur.
  • Nous créons 3 facettes. La facette «auteur» se regroupera sur l’auteur de terrain et il s’agit d’un regroupement de cordes complet; Facette «Title» sur le titre de terrain et un groupe de chaînes partiels (le nombre de lettres de départ); Facette «Prix» sur le prix du terrain et un regroupement de gamme (par une étape de 10).
  • Enfin, nous obtenons les facettes et les renvoyons à la fonction Test2 afin que le modèle puisse rendre les données et les facettes.

Affichage des facettes et des données filtrées

La plupart du temps, les facettes seront affichées sous forme de lien et nous amèneront à un ensemble de données filtrées.

Nous avons déjà créé une route ('Demo2 / Facet / {Key} / {Value}') pour afficher les résultats de recherche à facettes et les liens de facette.

L'itinéraire prend deux paramètres, reflétant la clé sur laquelle nous facet et la valeur de cette clé. La fonction TEST3 qui finit par être invoquée à partir de cette route est extraite ci-dessous:

<span>$app->get('demo2', function () use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test2 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test2->test2($app, $demo->test1($app));
</span><span>}
</span><span>);
</span>
<span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test3 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test3->test3($app, $demo->test1($app), $key, $value);
</span><span>}
</span><span>);</span>

Fondamentalement, en fonction de la clé, nous appliquons le filtrage (la fonction anonyme dans la clause) correspondant à la valeur transmise et obtenez les données supplémentaires. Nous pouvons également spécifier l'ordre des données à facettes.

Enfin, nous affichons les données (avec les facettes) dans un modèle. Cette route rend le même modèle que celui qui est utilisé par la route 'Demo2').

Ensuite, jetons un coup d'œil au modèle et voyons comment les liens de facette sont affichés. J'utilise Bootstrap pour que les composants CSS utilisés ici soient assez familiers:

<span>namespace classFacet
</span><span>{
</span>    <span>use Pinq<span>\ITraversable</span>,
</span>        Pinq\Traversable<span>;
</span>
    <span>class Facet
</span>    <span>{
</span>
        <span>public $data; // Original data
</span>        <span>public $key; // the field to be grouped on
</span>        <span>public $type; // F: full string; S: start of a string; R: range;
</span>        <span>public $range; // Only valid if $type is not F
</span>
		<span>...
</span>
        <span>public function getFacet()
</span>        <span>{
</span>            <span>$filter = '';
</span>
            <span>if ($this->type == 'F') // Full string 
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "S") //Start of string
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "R") // A value range
</span>            <span>{
</span>                <span>$filter = $this->data
</span>                        <span>->groupBy(function($row)
</span>                        <span>{
</span>                            <span>return floor($row[$this->key] / $this->range) * $this->range;
</span>                        <span>})
</span>                        <span>->select(function (ITraversable $data)
</span>                <span>{
</span>                    <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()];
</span>                <span>});
</span>            <span>}
</span>
            <span>return $filter;
</span>        <span>}
</span>    <span>}
</span><span>}</span>

Nous devons nous rappeler que la facette générée par notre application est un réseau imbriqué. Dans la première couche, il s'agit d'un tableau de toutes les facettes, et dans notre cas, nous avons un total de 3 (pour auteur, titre, auteur, respectivement).

Pour chaque facette, il s'agit d'un tableau apparié «Valeur clé» afin que nous puissions itérer de manière traditionnelle.

Veuillez noter comment nous construisons les URI des liens. Nous avons utilisé à la fois la clé de la boucle extérieure (k) et la clé de boucles internes (vv.key) pour être les paramètres de la route ('Demo2 / Facet / {key} / {value}'). Le nombre de la clé (Vv.Count) est utilisé pour retoucher l'affichage dans le modèle (en tant que badge bootstrap).

Le modèle sera rendu comme indiqué ci-dessous:

PINQ - REQUIREZ VOTRE ensemble de données - Recherche à facettes
PINQ - REQUIREZ VOTRE ensemble de données - Recherche à facettes

(le premier montre la page d'entrée initiale et le second affiche un résultat à facettes avec un prix entre 0 $ et 10 $ et commandé par l'auteur)

Très bien, jusqu'à présent, nous avons réussi à imiter une fonction de recherche à facettes dans notre application Web!

Avant de conclure cette série, nous allons jeter un coup d'œil à cette démo et voir ce qui peut être fait pour l'améliorer et quelles sont les limites.

Améliorations à faire

Dans l'ensemble, il s'agit d'une démo assez rudimentaire. Nous venons de parcourir la syntaxe et les concepts de base et les avons forgés dans un exemple de canette. Comme nous l'avons vu plus tôt, quelques zones peuvent être améliorées pour la rendre plus flexible.

Nous devons envisager de fournir une capacité de recherche de critères «complémentaire». Notre implémentation actuelle limite la recherche de facettes à appliquer uniquement sur l'original, au lieu des données criblées. C'est l'amélioration la plus importante à laquelle je peux penser.

limitations

La recherche à facettes implémentée ici a une limitation profonde (et probablement vrai pour les autres implémentations de recherche à facettes):

Nous récupérons les données du serveur MySQL à chaque fois.

Cette application utilise Silex comme cadre. Pour tout cadre d'entrée unique comme Silex, Symfony, Laravel, son index.php (ou app.php) est appelé chaque fois qu'un itinéraire doit être analysé et la fonction d'un contrôleur doit être invoquée.

En regardant le code dans notre index.php, nous verrons que cela signifie également la ligne de code ci-dessous:

<span>$app->get('demo2', function () use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test2 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test2->test2($app, $demo->test1($app));
</span><span>}
</span><span>);
</span>
<span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app)
</span><span>{
</span>    <span>global $demo;
</span>    <span>$test3 = new pinqDemo<span>\Demo</span>($app);
</span>    <span>return $test3->test3($app, $demo->test1($app), $key, $value);
</span><span>}
</span><span>);</span>

s'appelle chaque fois qu'une page de l'application s'affiche, ce qui signifie alors que les lignes suivantes sont exécutées à chaque fois:

<span>namespace classFacet
</span><span>{
</span>    <span>use Pinq<span>\ITraversable</span>,
</span>        Pinq\Traversable<span>;
</span>
    <span>class Facet
</span>    <span>{
</span>
        <span>public $data; // Original data
</span>        <span>public $key; // the field to be grouped on
</span>        <span>public $type; // F: full string; S: start of a string; R: range;
</span>        <span>public $range; // Only valid if $type is not F
</span>
		<span>...
</span>
        <span>public function getFacet()
</span>        <span>{
</span>            <span>$filter = '';
</span>
            <span>if ($this->type == 'F') // Full string 
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "S") //Start of string
</span>            <span>{
</span>				<span>...
</span>            <span>}
</span>            <span>elseif ($this->type == "R") // A value range
</span>            <span>{
</span>                <span>$filter = $this->data
</span>                        <span>->groupBy(function($row)
</span>                        <span>{
</span>                            <span>return floor($row[$this->key] / $this->range) * $this->range;
</span>                        <span>})
</span>                        <span>->select(function (ITraversable $data)
</span>                <span>{
</span>                    <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()];
</span>                <span>});
</span>            <span>}
</span>
            <span>return $filter;
</span>        <span>}
</span>    <span>}
</span><span>}</span>

sera-t-il mieux si nous évitons d'utiliser un cadre? Eh bien, en plus du fait que ce n'est pas vraiment une très bonne idée de développer une application sans cadre, nous sommes toujours confrontés au même problème: les données (et le statut) ne sont pas persistants d'un appel HTTP à un autre. C'est la caractéristique fondamentale de HTTP. Cela doit être évité avec l'utilisation d'un moteur de mise en cache.

Nous enregistrons certaines instructions SQL exécutées du côté du serveur lorsque nous construisons les facettes. Au lieu de passer 1 requête de sélection et 3 requêtes de groupe différentes par la même instruction, nous émettant simplement une requête sélectionnée avec l'instruction WHERE et utilisons PINQ pour fournir les informations d'agrégation.

Conclusion

Dans cette partie, nous avons réussi à imiter une capacité de recherche de facettes pour notre site de collecte de livres. Comme je l'ai dit, il s'agit simplement d'une démo à canette et a beaucoup d'amélioration et certaines limitations par défaut. Faites-nous savoir si vous construisez sur cet exemple et pouvez nous montrer des cas d'utilisation plus avancés!

L'auteur de PINQ travaille maintenant sur la prochaine version de version principale (version 3). J'espère que cela peut devenir plus puissant.

N'hésitez pas à laisser vos commentaires et vos pensées ci-dessous!

Questions fréquemment posées (FAQ) sur PINQ et la recherche à facettes

Qu'est-ce que PINQ et comment est-il lié à la recherche à facettes?

PINQ est une bibliothèque PHP qui fournit un langage de requête unique, intuitif et puissant pour manipuler des tableaux et d'autres ensembles de données. Il est conçu pour simplifier le processus de requête et de manipulation des données. En ce qui concerne la recherche à facettes, PINQ peut être utilisé pour créer des requêtes complexes qui peuvent filtrer et trier les données en fonction de plusieurs critères, qui est le concept principal de la recherche à facettes.

Comment l'approche de Pinq à la recherche à facettes diffère-t-elle des autres méthodes?

L'approche de Pinq de la recherche à facettes est unique car elle utilise un langage de requête basé sur PHP, qui est un langage de programmation largement utilisé. Cela facilite les développeurs qui connaissent déjà PHP pour implémenter la recherche facettée. De plus, le langage de requête de Pinq est conçu pour être intuitif et facile à utiliser, ce qui peut simplifier le processus de création de requêtes complexes.

peut être utilisée avec d'autres bases de données ou est-elle limitée à MySQL?

PINQ n'est pas limité à MySQL. Il peut être utilisé avec n'importe quel ensemble de données, y compris les tableaux et autres bases de données. Cette flexibilité fait de PINQ un outil polyvalent pour les développeurs qui ont besoin de travailler avec différents types de données.

Comment PINQ gère-t-il les grands ensembles de données?

PINQ est conçu pour gérer efficacement de grands ensembles de données. Il le fait en utilisant une stratégie d'évaluation paresseuse, ce qui signifie qu'il ne traite que les données lorsqu'elle est réellement nécessaire. Cela peut améliorer considérablement les performances lorsque vous travaillez avec de grands ensembles de données.

Quels sont les avantages de l'utilisation de PINQ pour la recherche à facettes?

L'utilisation de PINQ pour la recherche à facettes présente plusieurs avantages. Premièrement, il simplifie le processus de création de requêtes complexes, ce qui peut faire gagner du temps et des efforts pour les développeurs. Deuxièmement, il fournit un langage de requête puissant et flexible qui peut gérer un large éventail de types de données et de structures. Enfin, il est basé sur PHP, qui est un langage de programmation largement utilisé, ce qui facilite l'apprentissage et l'utilisation des développeurs. 🎜> PINQ est conçu pour être intuitif et facile à utiliser, ce qui le rend adapté aux débutants et aux développeurs expérimentés. Cependant, une certaine connaissance des langages PHP et de requête est bénéfique lors de l'utilisation de PINQ.

Comment PINQ garantit-il la précision des résultats de recherche?

PINQ assure la précision des résultats de recherche en utilisant un puissant et flexible Interroger le langage qui peut filtrer et trier avec précision les données en fonction de plusieurs critères. Cela lui permet de fournir des résultats de recherche précis et pertinents.

PINQ peut être utilisé pour la recherche en temps réel?

Oui, PINQ peut être utilisé pour une recherche en temps réel. Sa gestion efficace des grands ensembles de données et sa capacité à créer des requêtes complexes le rendent adapté aux applications de recherche en temps réel.

Comment PINQ se compare-t-il aux autres bibliothèques PHP pour la recherche facettée?

PINQ Stands D'autres bibliothèques PHP pour la recherche à facettes en raison de son langage de requête unique, intuitif et puissant. Il offre également une flexibilité en termes de types de données qu'il peut gérer, et sa manipulation efficace de grands ensembles de données en fait un choix fort pour les développeurs.

Est-ce que PINQ est open source et peut-il être personnalisé?

Oui, PINQ est une bibliothèque open source, ce qui signifie que les développeurs peuvent le personnaliser en fonction de leurs besoins spécifiques. Cette flexibilité est un autre avantage de l'utilisation de PINQ pour la recherche à facettes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn