Heim >Backend-Entwicklung >PHP-Tutorial >Effiziente Benutzerzeitpläne in einer PHP -Anwendung mit NEO4J
Jede soziale Anwendung, auf die Sie heutzutage begegnen, verfügt über eine Zeitleiste, in der Status Ihrer Freunde oder Follower im Allgemeinen in einer absteigenden Reihenfolge angezeigt wird. Die Implementierung einer solchen Funktion war in den gemeinsamen SQL- oder NoSQL -Datenbanken noch nie einfach.
Komplexität von Abfragen, Leistungseinflüsse, die mit der Anzahl der Freunde/Follower zunehmen, und Schwierigkeiten, Ihr soziales Modell zu entwickeln
In diesem Tutorial werden wir die Demo -Anwendung erweitern, die von den beiden Einführungsartikeln über NEO4J bzw. PHP verwendet wird:
entdecken
Sie werden eine bestimmte Modellierungstechnik namens Linked List und einige erweiterte Abfragen mit Cypher entdecken.
Der Quellcode für diesen Artikel ist in seinem eigenen Github -Repository zu finden.
Modellierung einer Zeitleiste in einer Diagrammdatenbank
Hier ist eine einfache Darstellung:
Ein Knoten in einer Diagrammdatenbank enthält einen Verweis auf die Verbindungen, die er hat, und bietet eine schnelle Leistung für Graphen -Travers.
Eine gemeinsame Modellierungstechnik für Benutzerfeeds wird als verlinkte Liste bezeichnet. In unserer Anwendung hat der Benutzerknoten eine Beziehung mit dem Namen last_post zum letzten vom Benutzer erstellten Beitrag. Dieser Beitrag hat eine vorherige Beziehung zur vorherigen Beziehung, die auch einen vorherigen zum zweiten vorherigen Beitrag usw. hat usw.
Mit diesem Modell haben Sie sofortigen Zugriff auf den neuesten Beitrag eines Benutzers. Tatsächlich müssen Sie gar nicht einen Zeitstempel haben, um seine Zeitleiste abzurufen (wir werden es jedoch behalten, um die Beiträge über verschiedene Benutzer hinweg zu sortieren).
Noch wichtiger ist, was der Benutzer in der Zeit in einer Grafikdatenbank auf natürliche Weise modelliert wird. Die Möglichkeit, die Daten auf eine Weise zu speichern, die entspricht, wie diese Daten außerhalb der Datenbank leben
Erstes Setup
<span>git clone git@github.com:sitepoint-editors/social-network </span><span>mv social-network social-timeline </span> <span>cd social-timeline </span><span>rm -rf .git </span><span>composer install </span>bower <span>install</span>Wie in den vorherigen Artikeln werden wir die Datenbank mit einem generierten Dummy -Datensatz mit Hilfe von Graphgen laden.
Sie müssen eine laufende Datenbank (lokal oder fern) haben, zu diesem Link gehen, auf Generieren klicken und dann unter "Ihre Datenbank populieren".
Wenn Sie NEO4J 2.2 verwenden, müssen Sie den NEO4J -Benutzernamen und Ihr Passwort im Populatorbox Graphgen angeben:
Wenn Sie jetzt den NEO4J -Browser öffnen, können Sie sehen, wie die Benutzer und Beiträge modelliert werden:
Der Benutzer füttert Route
hinzu
<span>git clone git@github.com:sitepoint-editors/social-network </span><span>mv social-network social-timeline </span> <span>cd social-timeline </span><span>rm -rf .git </span><span>composer install </span>bower <span>install</span>
Wir werden die Route zu einer Aktion in der Datei src/Controller/webcontroller.php zuordnen.
In dieser Aktion werden wir die Feeds des gegebenen Benutzers aus der NEO4J -Datenbank abrufen und sie zusammen mit dem Benutzerknoten an die Vorlage weitergeben.
<span>$app->get('/users/{user_login}/posts', 'Ikwattro\SocialNetwork\Controller\WebController::showUserPosts') </span> <span>->bind('user_post');</span>
Einige Erklärungen:
Wir werden zuerst einen Link im Benutzerprofil hinzufügen, um auf ihre Feeds zuzugreifen, indem wir diese Zeile am Ende des Benutzerinformationsblocks nur hinzufügen:
<span>public function showUserPosts(Application $application, Request $request) </span> <span>{ </span> <span>$login = $request->get('user_login'); </span> <span>$neo = $application['neo']; </span> <span>$query = 'MATCH (user:User) WHERE user.login = {login} </span><span> MATCH (user)-[:LAST_POST]->(latest_post)-[PREVIOUS_POST*0..2]->(post) </span><span> RETURN user, collect(post) as posts'; </span> <span>$params = ['login' => $login]; </span> <span>$result = $neo->sendCypherQuery($query, $params)->getResult(); </span> <span>if (null === $result->get('user')) { </span> <span>$application->abort(404, 'The user $login was not found'); </span> <span>} </span> <span>$posts = $result->get('posts'); </span> <span>return $application['twig']->render('show_user_posts.html.twig', array( </span> <span>'user' => $result->getSingle('user'), </span> <span>'posts' => $posts, </span> <span>)); </span> <span>}</span>
Wir werden jetzt unsere Vorlage erstellen, die die User Timeline (Beiträge) angezeigt wird. Wir setzen eine Überschrift und eine Schleife, die unsere Feeds -Sammlung iteriert, um sie in einem dedizierten HTML Div:
anzuzeigen<span><span><span><p</span>></span><span><span><a</span> href<span>="{{ path('user_post', {user_login: user.property('login') }) }}"</span>></span>Show posts<span><span></a</span>></span><span><span></p</span>></span></span>
Wenn Sie jetzt einen Benutzer auswählen und auf den Link Benutzerbeiträge anzeigen klicken, können Sie feststellen, dass unsere Beiträge gut angezeigt und durch Abstiegszeit bestellt werden, ohne eine Datumseigenschaft anzugeben.
Um eine Benutzerzeitleiste anzuzeigen, müssen Sie alle Benutzer abrufen, die er folgt, und die Abfrage von jedem Benutzer auf die Last_Post -Beziehung erweitern.
Wenn Sie alle diese Beiträge erhalten, müssen Sie sie nach Zeit filtern, um sie zwischen Benutzern zu bestellen.
Die User Timeline Route
Fügen Sie die Route zum Web/index.php -Datei
hinzu
{% extends "layout.html.twig" %} {% block content %} <span><span><span><h1</span>></span>Posts for {{ user.property('login') }}<span><span></h1</span>></span> </span> {% for post in posts %} <span><span><span><div</span> class<span>="row"</span>></span> </span> <span><span><span><h4</span>></span>{{ post.properties.title }}<span><span></h4</span>></span> </span> <span><span><span><div</span>></span>{{ post.properties.body }}<span><span></div</span>></span> </span> <span><span><span></div</span>></span> </span> <span><span><span><hr</span>/></span> </span> {% endfor %} {% endblock %}Die Controller -Aktion:
<span>$app->get('/user_timeline/{user_login}', 'Ikwattro\SocialNetwork\Controller\WebController::showUserTimeline') </span> <span>->bind('user_timeline');</span>Erklärungen zur Abfrage:
<span>public function showUserTimeline(Application $application, Request $request) </span> <span>{ </span> <span>$login = $request->get('user_login'); </span> <span>$neo = $application['neo']; </span> <span>$query = 'MATCH (user:User) WHERE user.login = {user_login} </span><span> MATCH (user)-[:FOLLOWS]->(friend)-[:LAST_POST]->(latest_post)-[:PREVIOUS_POST*0..2]->(post) </span><span> WITH user, friend, post </span><span> ORDER BY post.timestamp DESC </span><span> SKIP 0 </span><span> LIMIT 20 </span><span> RETURN user, collect({friend: friend, post: post}) as timeline'; </span> <span>$params = ['user_login' => $login]; </span> <span>$result = $neo->sendCypherQuery($query, $params)->getResult(); </span> <span>if (null === $result->get('user')) { </span> <span>$application->abort(404, 'The user $login was not found'); </span> <span>} </span> <span>$user = $result->getSingle('user'); </span> <span>$timeline = $result->get('timeline'); </span> <span>return $application['twig']->render('show_timeline.html.twig', array( </span> <span>'user' => $result->get('user'), </span> <span>'timeline' => $timeline, </span> <span>)); </span> <span>}</span>und erstellen Sie die Timeline -Vorlage:
<span><span><span><p</span>></span><span><span><a</span> href<span>="{{ path('user_timeline', {user_login: user.property('login') }) }}"</span>></span>Show timeline<span><span></a</span>></span><span><span></p</span>></span></span>Wir haben jetzt eine ziemlich coole Zeitleiste, die die letzten 20 Feeds der Personen zeigt, denen Sie folgen, die für die Datenbank effizient sind.
Um Beiträge zu verknüpften Listen hinzuzufügen, ist die Cypher -Abfrage etwas mehr knifflig . Sie müssen den Postknoten erstellen, die Last_Post -Beziehung vom Benutzer zum alten neuesten_Post entfernen, die neue Beziehung zwischen dem allerersten Postknoten und dem Benutzer erstellen und schließlich die Vorgängerbeziehung zwischen den neuen und alten letzten Postknoten erstellen.
Einfach, nicht wahr? Lass uns gehen!
Wie gewohnt erstellen wir die Postroute für das Formular, das auf die WebController -Aktion hinweist:
<span>git clone git@github.com:sitepoint-editors/social-network </span><span>mv social-network social-timeline </span> <span>cd social-timeline </span><span>rm -rf .git </span><span>composer install </span>bower <span>install</span>
Als nächstes werden wir ein grundlegendes HTML -Formular zum Einfügen des Posttitels und des Textes in die Benutzervorlage hinzufügen:
<span>$app->get('/users/{user_login}/posts', 'Ikwattro\SocialNetwork\Controller\WebController::showUserPosts') </span> <span>->bind('user_post');</span>
Und schließlich erstellen wir unsere NewPost -Aktion:
<span>public function showUserPosts(Application $application, Request $request) </span> <span>{ </span> <span>$login = $request->get('user_login'); </span> <span>$neo = $application['neo']; </span> <span>$query = 'MATCH (user:User) WHERE user.login = {login} </span><span> MATCH (user)-[:LAST_POST]->(latest_post)-[PREVIOUS_POST*0..2]->(post) </span><span> RETURN user, collect(post) as posts'; </span> <span>$params = ['login' => $login]; </span> <span>$result = $neo->sendCypherQuery($query, $params)->getResult(); </span> <span>if (null === $result->get('user')) { </span> <span>$application->abort(404, 'The user $login was not found'); </span> <span>} </span> <span>$posts = $result->get('posts'); </span> <span>return $application['twig']->render('show_user_posts.html.twig', array( </span> <span>'user' => $result->getSingle('user'), </span> <span>'posts' => $posts, </span> <span>)); </span> <span>}</span>
Einige Erklärungen:
Der schwierige Teil hier ist, dass die OldLatestPosts -Sammlung immer 0 oder 1 Elemente enthält, was für unsere Abfrage ideal ist.
In diesem Artikel haben wir eine Modellierungstechnik namens Linked List entdeckt, gelernt, wie man diese in einer sozialen Anwendung implementiert und wie Sie Knoten und Beziehungen auf effiziente Weise abrufen. Wir haben auch einige neue Cypher -Klauseln wie Skip and Limit gelernt, die für die Pagination nützlich sind.
Während die Zeitlinien der realen Welt etwas komplexer sind als das, was wir hier gesehen haben, hoffe ich, dass Grafikdatenbanken wie Neo4j wirklich die beste Wahl für diese Art von Anwendung sind.
Wie hat sich PHP im Laufe der Jahre entwickelt? Es begann als einfache Skriptsprache für die Webentwicklung, wurde jedoch zu einer vollwertigen Programmiersprache mit Unterstützung für objektorientierte Programmierung, funktionaler Programmierung und vieles mehr. Jede neue Version von PHP bringt Verbesserungen in Bezug auf Leistung, Sicherheit und Funktionen mit sich.
Das obige ist der detaillierte Inhalt vonEffiziente Benutzerzeitpläne in einer PHP -Anwendung mit NEO4J. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!