Elasticsearch mit PHP: Eine Suche für die Homepage

Im zweiten Teil über Elasticsearch erkläre ich Dir wie Du mit PHP auf die API zugreifest und eine erste Suche machst. Dazu gibt es ein paar Tipps, so dass auch Suchen mit Schreibfehlern zum Erfolg führen.

Im ersten Teil habe ich Dir erklärt, wie Du Elasticsearch auf einem Ubuntu Server installierst.

Elasticsearch und PHP

Elasticsearch PHP installieren

Die Installation des Elasticsearch PHP SDKs geht bequem über Composer. Dort erhältst Du Zugriff auf eine umfassende Bibliothek mit PHP Funktionen für den Zugriff auf Elasticsearch.

Du öffnest die Konsole, wechsle in das entsprechende Verzeichnis (z.B. /var/www/) und installiere Elasticsearch PHP:

cd /var/www/
composer require elasticsearch/elasticsearch

Unter /var/www/vendor/ wird jetzt der Ordner elasticsearch erstellt und alle Dateien heruntergeladen.

Elasticsearch PHP konfigurieren

Damit Du vernünftig und von überall problemlos auf Elasticsearch zugreifen kannst, baust Du Dir eine eigene Klasse "Elastic" in die alle Funktionen kommen:

require_once VENDOR.'autoload.php'; // VENDOR ist bei mir eine Konstante mit dem Pfad zu /var/www/vendor/
class Elastic{
public $es = false;

function __construct(){
$this->es = \Elasticsearch\ClientBuilder::create()
->setHosts([ 'IPELASTICSERVER:9200' ])
->build();
}
?>

In diesen wenigen Zeilen wird die Verbindung zum Elasticserver hergestellt. Du musst die Konstante VENDOR anpassen und natürlich statt IPELASTICSERVER die IP-Adresse eingeben auf der Elastc läuft (s. Tutorial 1).

Daten in Elasticsearch speichern mit PHP

Bevor Du Daten abfragen kannst, musst Du erstmal etwas abspeichern. Überleg Dir vorab, was Du alles speichern willst (bzw. wonach später gesucht werden soll). Bei mir schaut die Aufteilung so aus:

  • index: example-com-de | Im Indexname kommt bei mir die URL vor (example-com) gefolgt von der Sprache (-de für Deutsch)
  • type: blog | Der Type kann z.B. sein Blog, Produkt, Kategorie
  • id: die ID des Eintrags in meiner MySQL Datenbank | Der Vorteil liegt darin, dass die ID sowieso nur einmalig vorkommt und ich dann sofort eine Querverknüpfung habe
  • body: In den Body kommt der tatsächliche Inhalt. Das könnte sein: Title, Body (=Content des Blogs), MetaTitle, Teaser, etc.

Bist Du Dir im Klaren darüber wie die Struktur sein soll, kannst Du die Funktion zum speichern anlegen:

public function insert($p,$type='blog'){
if($type == 'blog'){
$params = [
'index' => $p->shopUrl.'-'.$p->lang,
'type' => $type,
'id' => $p->blogID,
'body' => [
'lang' => $p->lang,
'metaTitle' => $p->metaTitle,
'metaDescription' => $p->metaDescription,
'name' => $p->name,
'teaser' => $p->teaser,
'content' => $p->content
]
];
}
/*....*/
try{
// Alles hat geklappt
$indexed = $this->es->index($params);
return $indexed;
} catch (Elasticsearch\Common\Exceptions\BadRequest400Exception $e) {
// Speichern fehlgeschlagen
return false;
}
}

Das praktische ist: Wenn Du einen Eintrag updaten möchtest, kannst Du einfach die insert-Funktion verwenden. Sobange die ID identisch ist, wird der alte Beitrag einfach überschrieben. In $p sind alle Werte gespeichert die z.B. über ein POST-Formular kommen. Falls ihr sowohl einen Blog als auch eine Kategorie habt, könnt ihr über $type die IF-ELSE-Abfragen einfach weiter ausbauen.

Daten in Elasticsearch suchen mit PHP

Jetzt kommen wir zum spannenderen Teil, der Suche mit PHP und Elasticsearch.Auch das sind wenige Zeilen Code. Bzw. primär sind die Einstellungen wichtig, die man vornimmt:

public function search($q,$type='product'){
$query = $this->es->search([
'index' => 'example-com-de',
'type' => $type,
'body' => [
'query' =>[
'bool' => [
'must' => [
'multi_match' => [
'query' => $q,
'type' => 'phrase_prefix',
'cutoff_frequency' => '0.0007',
'operator' => 'or',
'fields' => ["name","metaTitle","metaDescription","teaser","content"]
]
]
]
]
]
'size' => 10,
'sort' => ['_score' => ['order' => 'desc']]
]
]);
return $query;
}

Das schaut jetzt ganz schön verschachtelt und unübersichtlich aus. Ist aber gar nicht so kompliziert. Im "Body"-Teil steht die eigentliche Suche. Alles darunter sind zusätzliche Einstellungen und Optionen. Aber der Reihe nach:

  • body -> query -> bool -> must: Die eigentliche Abfage. "Bool" sagt aus, dass es sich um eine Abfrage handelt, die mehrere Abfragen kombiniert. "Must" ist der Teil, der zwingend vorkommen muss.
  • multi_match: Ist eine Suchmethode, die mehrere Felder unabhängig von einander absucht und das Feld mit der besten Trefferquote wählt.
  • query: In der Variable $q ist die Sucheingabe des Nutzers gespeichert. Danach wird gesucht.
  • type: Hier wird die Art der Suche angegeben. phrase_prefix ist eine einfache Methode der Autovervollständigung und sucht entsprechende Teile ab. Dieser Type hat ein paar Tücken, ist aber gut genug für diesen Zweck.
  • cutoff_frequency: Ignoriert sehr häufig vorkommende Worte sofern es Sinn macht (z.B.: der, die, das)
  • operator: Die Art der Verknüpfung der Felder.
  • fields: Die Felder in denen gesucht werden soll.
  • size: Die Anzahl der Ergebnisse
  • sort: Die Sortierung der Ergebnisse. In diesem Falle sortiert er absteigend beginnend mit dem besten Treffer.

Das war es auch schon. In $query ist dann die Rückgabe gespeichert. Die könnt ihr einmal per var_dump ausgeben und entsprechend die Felder wählen.

Einfache Abfrage mit Elasticsearch PHP

Die gespeicherten Werte zu einer ID abzufragen ist enorm simpel und Bedarf kaum einer Erklärung:

public function get($p,$type='blog'){
$params = [
'index' => 'example-com-de',
'type' => $type,
'id' => $p->id,
];
try{
$indexed = $this->es->get($params);
return $indexed;
} catch (Elasticsearch\Common\Exceptions\InvalidArgumentException $e) {
return false;
} catch(Elasticsearch\Common\Exceptions\Missing404Exception $e){
return false;
}
}

Wir suchen also einfach nur mit "->get" nach der ID und erhalten alle gespeicherten Werte dazu zurück. Spannender wird es bei einer tatsächlichen Suche.

Suche mit Rechtschreibfehlern in PHP

Als letzten Punkt gibt es noch ein Beispiel für eine Suche mit Rechtschreibfehlern (z.B. Elastcsearch statt Elasticsearch). Das ganze nennt sich "Fuzzy" in Elasticsearch. Er sucht also nach Worten die bis zu einem gewissen Grade dem Suchwort ähnlich sind.

Sucht ihr bei Glohbe nach Elastcsearch findet ihr in der Live-Suche nichts, erst druch das Drücken von "Enter" erscheint die Suche auf der Ergebnisseite. Das habe ich aus dem Grund eingebaut, dass die Fuzzy-Suche länger dauert und mehr Ergebnisse zurückliefern könnte, als gewünscht. Ein Beispiel:

[...]
'type' => 'fuzzy',
'body' => [
'query' => [
'bool' => [
'must' => [
'multi_match' => [
'query' => $q,
'type' => 'best_fields',
'cutoff_frequency' => '0.0007',
'operator' => 'or',
'fields' => ["name^5","metaTitle^3","metaDescription^2","teaser^2","content^1"],
"fuzziness" => "AUTO"
]
]
]
]
[...]

Wir haben also wieder ein must mit multi_match. Allerdings bei type "best_fields". best_fields ist ideal bei der Suche nach mehreren Wörtern in einem Field. Bei fields sind euch sicher die Hochzahlen (^5) aufgefallen. Das sind einfach die Gewichtungen. Kommt das Suchwort bereits im Artikelnamen vor, soll der Treffer stärker gewichtet sein, als wenn er im Content vorkommt. Fuziness ist der Abstand zwischen den einzelnen Buchstaben die fehlen dürfen, um ein neues Wort zu bilden. Bei Elasticsearch darf also das "i" fehlen, damit er Elastcsearch noch erkennt. 

Fazit

Die Verknüpfung von Elasticsearch und Webseite über PHP ist sehr simpel und keine Wissenschaft. Die Feinabstimmung ist aber deutlich aufwendiger und sehr individuell. Die ganzen Werte und Einstellungen müssen auf die eigenen Anforderungen abgestimmt werden. Aber es ist so dennoch recht gut möglich eine sehr solide Suche auf die Beine zu stellen, die schonmal besser ist als 99% der Standardsuchen!

Weitere Artikel:

2018-elasticsearch-teil-1.jpg

Elasticsearch 6 - Installtion auf Ubuntu

In diesem Beitrag erkläre ich, wie Du Elasticsearch 6 auf einem Ubuntu Server installierst, einrichtest, absicherst und eine erste Abfrage machst. In Teil 2 werden wir Elasticsearch mit unserer Homepage verknüpfen.

2017-aktienkurse-php-ai.jpg

PHP - Aktienkurse vorhersagen mit einer KI

Künstliche Intelligenz ist im Moment sehr aktuell und entwickelt sich rasend schnell weiter. PHP ist zwar nicht die ideale Sprache dafür, aber für die ersten Schritte damit und zum Reinschnuppern langt es.

0 Kommentare

Kommentar verfassen
Ersten Kommentar abgeben
Name:
E-Mail
Bewertung Qualätit:
Bewertung Lesbarkeit:
Bewertung Inhalt:
Überschrift:
Kommentar:
www.godlike.de

Diese Webseite verwendet Cookies, damit wir die Inhalte und Funktionen der Webseite optimal gestalten können. Durch die weitere Nutzung der Webseite stimmen Sie der Nutzung von Cookies zu.