Heim >Backend-Entwicklung >PHP-Tutorial >Pinq - Fragen Sie Ihre Datensätze an - Facetten -Suche

Pinq - Fragen Sie Ihre Datensätze an - Facetten -Suche

Lisa Kudrow
Lisa KudrowOriginal
2025-02-20 12:29:14563Durchsuche

Pinq - Fragen Sie Ihre Datensätze an - Facetten -Suche

Key Takeaways

  • Pinq, ein Php -Linq -Port, kann verwendet werden, um eine facettierte Suchfunktion mit MySQL nachzuahmen und einen leistungsstarken und einfachen Ansatz zu bieten.
  • Eine facettierte Suche funktioniert, indem Sie von Benutzer bereitgestellte Schlüsselwörter zur Suche nach Produkten, Rückgabe von passenden Produkten und Anbieten von Links, um die Suche auf basierend auf verschiedenen Marken, Preisstufen und Funktionen zu optimieren.
  • PINQ kann verwendet werden, um eine Demo -Anwendung durch Hinzufügen von Suchfunktionen mit wesentlichen, facettierten, z.
  • Die mit Pinq implementierte facettierte Suche ruft jedes Mal Daten vom MySQL -Server ab, was durch Verwendung einer Caching -Engine vermieden werden kann.
  • Obwohl Pinqs Ansatz zur facettierten Suche eine grundlegende Demo ist, bietet er viel Raum für Verbesserungen und kann für fortgeschrittenere Anwendungsfälle aufgebaut werden.
  • In Teil 1 haben wir kurz die Installation und die grundlegende Syntax von Pinq, einen PHP -Linq -Port, abgedeckt. In diesem Artikel werden wir sehen, wie Pinq verwendet wird, um eine facettierte Suchfunktion mit MySQL zu imitieren.

Wir werden nicht den vollen Aspekt der Facett -Suche in dieser Serie abdecken. Interessierte Parteien können auf relevante Artikel verweisen, die auf SitePoint und anderen Internetveröffentlichungen veröffentlicht wurden.

Eine typische facettierte Suche funktioniert wie diese in einer Website:

Ein Benutzer stellt ein Schlüsselwort oder einige Schlüsselwörter zur Suche nach. Zum Beispiel „Router“, um nach Produkten zu suchen, die „Router“ in der Beschreibung, in der Schlüsselwort, in der Kategorie, in den Tags usw. enthalten.
  • Die Site gibt die Produkte zurück, die den Kriterien entsprechen.
  • Die Site bietet einige Links, um die Suche zu beenden. Zum Beispiel kann es auffordern, dass es verschiedene Marken für einen Router gibt, und es kann unterschiedliche Preisbereiche und unterschiedliche Funktionen geben.
  • Der Benutzer kann die Ergebnisse weiter im Bildschirm sehen, indem Sie auf die verschiedenen bereitgestellten Links klicken und schließlich eine benutzerdefinierte Ergebnismenge erhalten.
  • Die facettierte suche
  • ist so beliebt und leistungsstark und Sie können sie in fast jeder E-Commerce-Website erleben.

Leider ist die Facette-Suche noch keine integrierte Funktion von MySQL. Was können wir tun, wenn wir MySQL verwenden, aber unseren Benutzern auch eine solche Funktion bieten möchten?

Mit Pinq werden wir sehen, dass es einen ebenso leistungsstarken und einfachen Ansatz gibt, um dies zu erreichen, als wenn wir andere DB -Motoren verwenden - zumindest in gewisser Weise.

Teil 1 Demo

erweitern

Hinweis: Alle Code in diesem Teil und in der Teil 1 -Demo finden Sie im Repo.

In diesem Artikel werden wir die Demo erweitern, die wir in Teil 1 gezeigt haben, und einige wichtige, facettierte Suchfunktionen hinzufügen.

Beginnen wir mit index.php, indem wir die folgenden Zeilen hinzufügen:

Wir haben gerade zwei weitere Routen in unserer Demo -Anwendung (mit Silex) erstellt.
<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>

Die erste Route besteht darin, uns auf die Seite zu bringen, die alle Datensätze zeigt, die unserem ersten Suchverhalten entsprechen, d. H. Durch die Suche eines Schlüsselworts. Um die Demo einfach zu halten, wählen wir alle Bücher aus der Tabelle book_book aus. Außerdem werden die Ergebnisse und facettierte Links für die weitere Navigation angezeigt.

Die zweite Route bringt uns zu einer anderen Seite, die die Datensätze zeigt, die weitere Facetten -Suchkriterien in dem im obigen Schritt erstellten Ergebnis -Set entsprechen. Es werden auch die facettierten Suchlinks angezeigt.

In einer realen Implementierung wird nach dem Klicken eines facettierten Links jede facettierte Filterung auf der Ergebnisseite angepasst, um die statistischen Informationen des Ergebnisdatensatzes widerzuspiegeln. Auf diese Weise kann der Benutzer "Add-On" -Sichtweite anwenden und zuerst „Marke“ hinzufügen und dann „Preisspanne“ usw.

Aber in dieser einfachen Demo werden wir diesen Ansatz überspringen, alle facettierten Suche und die Links werden nur die Informationen zum Originaldatensatz widerspiegeln. Dies ist die erste Einschränkung und der erste Bereich für Verbesserungen in unserer Demo.

Wie wir aus dem obigen Code sehen, befinden sich die realen Funktionen in einer anderen Datei namens Pinqdemo.php. Sehen wir uns den relevanten Code an, der die facettierte Suchfunktion bietet.

Eine Facettenklasse

Erstens erstellen wir eine Klasse, um eine Facette darzustellen. Im Allgemeinen sollte eine Facette einige Eigenschaften haben:

  • Die Daten, die sie betreiben ($ data)
  • Der Schlüssel -IT -Gruppen auf ($ key)
  • Der Schlüsseltyp ($ type). Es kann eines der folgenden sein:
    • Geben Sie eine vollständige Zeichenfolge an, um eine genaue Übereinstimmung
    • zu erstellen
    • Geben Sie teilweise (normalerweise beginnen) einer Zeichenfolge an, um ein Muster überein zu machen
    • Geben Sie einen Wertebereich an, der nach einem Wertebereich
  • gruppiert wird
  • Wenn der Schlüsseltyp ein Bereich ist, muss ein Wertschritt angegeben werden, um die obere/untere Grenze des Bereichs zu bestimmen. Oder wenn der Schlüsseltyp eine Teilzeichenfolge ist, müssen wir eine Nummer angeben, um anzugeben, wie viele erste Buchstaben für die Gruppierung ($ Range)
  • verwendet werden sollen

Die Gruppierung ist der kritischste Teil einer Facette. Alle aggregierenden Informationen, die eine Facette möglicherweise zurückgeben könnte, hängt von den "Gruppierungskriterien" ab. Normalerweise sind „Vollstring“, „Teilzeichenfolge“ und „Wertebereich“ die am häufigsten verwendeten.

<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>

In dieser Klasse besteht die Schlüsselfunktion darin, das facettierte Ergebnissatz basierend auf den Daten und den Facettenschlüsseleigenschaften zurückzugeben. Wir haben festgestellt, dass es für verschiedene Tastenarten verschiedene Möglichkeiten gibt, die Daten zu gruppieren. Im obigen Punkt haben wir gezeigt, wie der Code aussehen wird, wenn wir die Daten nach einem Wertebereich in einem von $ Range angegebenen Schritt gruppieren.

Facetten erstellen und die Originaldaten

anzeigen
<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>

In der Funktion getfacet () machen wir die folgenden Schritte aus:

  • Umwandeln Sie die Originaldaten in ein PinQtraversable -Objekt für die weitere Verarbeitung.
  • Wir erstellen 3 Facetten. Die Facette "Autor" wird auf dem Feldautor gruppieren, und es handelt sich um eine vollständige String -Gruppierung. Facette "Titel" auf Feldtitel und eine Teilzeichengruppierung (die Anzahl der Start 6 Buchstaben); "Preis" Facette zum Feldpreis und einer Reichweite (um einen Schritt von 10).
  • Schließlich erhalten wir die Facetten und geben sie zurück in die Test2 -Funktion, damit die Vorlage die Daten und die Facetten rendern kann.

Anzeigen der Facetten und der gefilterten Daten

Meistens werden Facetten als Link angezeigt und bringen uns zu einem gefilterten Datensatz.

Wir haben bereits eine Route erstellt ('Demo2/facet/{key}/{value}'), um die facettierten Suchergebnisse und die Facettenlinks anzuzeigen.

Die Route nimmt zwei Parameter vor, die den Schlüssel widerspiegeln, auf dem wir facetten, und den Wert dieses Schlüssels. Die Test3 -Funktion, die schließlich von dieser Route aufgerufen wird

<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>
Abhängig vom Schlüssel wenden wir im Grunde die Filterung (die anonyme Funktion in der Klausel) an, die dem in übergebenen Wert entspricht, und erhalten die weiteren gescreenten Daten. Wir können auch die Reihenfolge der facettierten Daten angeben.

Schließlich zeigen wir die Daten (zusammen mit den Facetten) in einer Vorlage an. Diese Route macht die gleiche Vorlage wie die, die auf der Route 'Demo2' verwendet wird.

Schauen wir uns als nächstes die Vorlage an und sehen Sie, wie die Facettenlinks angezeigt werden. Ich verwende Bootstrap, damit die hier verwendeten CSS -Komponenten ziemlich vertraut sein sollten:

<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>
Wir müssen uns daran erinnern, dass die von unserer App generierte Facette ein verschachteltes Array ist. In der ersten Schicht ist es eine Reihe aller Facetten, und in unserem Fall haben wir insgesamt 3 (für Autor, Titel, Autor).

Für jede Facette handelt es sich um ein "Schlüsselwert" gepaartes Array, damit wir auf traditionelle Weise iterieren können.

Bitte beachten Sie, wie wir die URIs der Links erstellen. Wir haben sowohl den Schlüssel (K) als auch den Inner Loops -Schlüssel (Vv.Key) der Außenschleife als Parameter in der Route ('Demo2/facet/{Key}/{value}') verwendet. Die Anzahl der Schlüssel (VV.Count) wird verwendet, um das Display in der Vorlage (als Bootstrap -Abzeichen) zu verbessern.

Die Vorlage wird wie unten gezeigt gerendert:

Pinq - Fragen Sie Ihre Datensätze an - Facetten -Suche
Pinq - Fragen Sie Ihre Datensätze an - Facetten -Suche

(Die erste zeigt die anfängliche Eintragsseite und die zweite zeigt ein facettiertes Ergebnis mit einem Preis zwischen 0 und 10 US -Dollar und vom Autor bestellt)

In Ordnung, bisher haben wir es geschafft, eine facettierte Suchfunktion in unserer Web -App nachzuahmen!

Bevor wir diese Serie abschließen, werden wir uns diese Demo abschließen und sehen, was getan werden kann, um sie zu verbessern und was die Grenzen sind.

Verbesserungen, die vorgenommen werden können

Insgesamt ist dies eine ziemlich rudimentäre Demo. Wir haben gerade die grundlegende Syntax und Konzepte durchlaufen und sie in ein Can-Run-Beispiel geschmiedet. Wie wir bereits gesehen haben, können einige Bereiche verbessert werden, um es flexibler zu machen.

Wir müssen in Betracht ziehen, "Add-On" -Kriterien zur Suche nach Funktionen zu geben. Unsere aktuelle Implementierung begrenzt die Facettensuche, die nur auf das Original angewendet wird, anstatt der gescreenten Daten. Dies ist die wichtigste Verbesserung, die ich mir vorstellen kann.

Einschränkungen

Die hier implementierte facettierte Suche hat eine tief verwurzelte Einschränkung (und wahrscheinlich für andere facettierte Suchimplementierungen):

Wir reichen jedes Mal Daten vom MySQL -Server ab.

Diese App verwendet Silex als Framework. Für jedes Einzeleingangs-Framework wie Silex, Symfony, Laravel, sein Index.php (oder app.php) wird jedes Mal aufgerufen, wenn eine Route analysiert und die Funktion eines Controllers aufgerufen wird.

Wenn wir den Code in unserem Index.php betrachten, werden wir feststellen, dass dies auch die folgende Codezeile bedeutet:

<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>
wird jedes Mal aufgerufen, wenn eine Seite in der App angezeigt wird, was bedeutet, dass die folgenden Zeilen jedes Mal ausgeführt werden:

<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>
Wird es besser sein, wenn wir vermeiden, ein Framework zu verwenden? Nun, abgesehen von der Tatsache, dass es nicht wirklich eine sehr gute Idee ist, eine App ohne Framework zu entwickeln, stehen wir immer noch vor dem gleichen Problem: Daten (und Status) sind von einem HTTP -Anruf zum anderen nicht bestehen. Dies ist das grundlegende Merkmal von HTTP. Dies sollte durch die Verwendung eines Caching -Motors vermieden werden.

wir speichern einige SQL -Anweisungen, die auf der Serverseite ausgeführt werden, wenn wir die Facetten erstellen. Anstatt 1 Abfrage auszuwählen und 3 verschiedene Gruppen durch Abfragen mit derselben Where -Anweisung auszuwählen, geben wir nur eine Auswahl von Abfrage mit der WHERE -Anweisung aus und verwenden PINQ, um die Aggregationsinformationen bereitzustellen.

Schlussfolgerung

In diesem Teil haben wir es geschafft, eine Facetten -Suchfunktion für unsere Buchsammlung nachzuahmen. Wie ich bereits sagte, ist es nur eine Can-Run-Demo und hat viel Raum der Verbesserung und einige Standardeinschränkungen. Lassen Sie uns wissen, ob Sie auf diesem Beispiel aufbauen und uns einige fortgeschrittenere Anwendungsfälle zeigen können!

Der Autor von Pinq arbeitet jetzt an der nächsten Major -Versionsveröffentlichung (Version 3). Ich hoffe, es kann mächtiger werden.

Fühlen Sie sich frei, Ihre Kommentare und Gedanken unten zu hinterlassen!

häufig gestellte Fragen (FAQs) zu PINQ und Facetted Search

Was ist Pinq und wie bezieht es sich auf facettierte Suche? Es wurde entwickelt, um den Prozess der Abfragung und Manipulation von Daten zu vereinfachen. In Bezug auf die facettierte Suche kann PINQ verwendet werden, um komplexe Abfragen zu erstellen, die Daten basierend auf mehreren Kriterien filtern und sortieren können. Dies ist das Kernkonzept der facettierten Suche.

Wie unterscheidet sich Pinqs Ansatz zur facettierten Suche von anderen Methoden? Dies erleichtert Entwicklern, die bereits mit PHP vertraut sind, facettierte Suche zu implementieren. Darüber hinaus ist die Abfragesprache von Pinq intuitiv und einfach zu bedienen, was den Prozess des Erstellens komplexer Abfragen vereinfachen kann. > Pinq ist nicht auf MySQL beschränkt. Es kann mit jedem Datensatz verwendet werden, einschließlich Arrays und anderen Datenbanken. Diese Flexibilität macht PINQ für Entwickler zu einem vielseitigen Tool für Entwickler, die mit verschiedenen Datenarten arbeiten müssen. Dies geschieht durch die Verwendung einer faulen Bewertungsstrategie, was bedeutet, dass nur Daten verarbeitet werden, wenn sie tatsächlich benötigt werden. Dies kann die Leistung bei der Arbeit mit großen Datensätzen erheblich verbessern. Erstens vereinfacht es den Prozess der Erstellung komplexer Abfragen, die den Entwicklern Zeit und Mühe sparen können. Zweitens bietet es eine leistungsstarke und flexible Abfragesprache, die eine Vielzahl von Datentypen und Strukturen verarbeiten kann. Schließlich basiert es auf PHP, eine weit verbreitete Programmiersprache, die es Entwicklern erleichtert, zu lernen und zu verwenden. 🎜> Pinq ist so konzipiert, dass es intuitiv und einfach zu bedienen ist, was es sowohl für Anfänger als auch für erfahrene Entwickler geeignet ist. Einige Kenntnisse in PHP- und Abfragesprachen sind jedoch von Vorteil bei der Verwendung von Pinq.

Wie stellt PINQ die Genauigkeit der Suchergebnisse sicher? Abfragesprache, die Daten genau basierend auf mehreren Kriterien filtern und sortieren kann. Dies ermöglicht es, präzise und relevante Suchergebnisse bereitzustellen.

Kann PINQ für die Echtzeitsuche verwendet werden? Die effiziente Behandlung großer Datensätze und seine Fähigkeit, komplexe Abfragen zu erstellen, machen es für Echtzeit-Suchanwendungen geeignet. Aus anderen PHP -Bibliotheken nach facettierter Suche aufgrund ihrer einzigartigen, intuitiven und leistungsstarken Abfragesprache. Es bietet auch Flexibilität in Bezug auf die Arten von Daten, die sie verarbeiten können, und der effiziente Umgang mit großen Datensätzen macht es zu einer starken Wahl für Entwickler.

Ja, Pinq ist eine Open-Source-Bibliothek, was bedeutet, dass Entwickler sie an ihre spezifischen Bedürfnisse anpassen können. Diese Flexibilität ist ein weiterer Vorteil der Verwendung von PINQ für die Facettenuche.

Das obige ist der detaillierte Inhalt vonPinq - Fragen Sie Ihre Datensätze an - Facetten -Suche. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn