Wie im letzten Artikel geschrieben, habe ich seit Kurzem über das ElasticPress-Plugin den Suchserver Elasticsearch im Einsatz. Hier beschreibe ich, wie ihr die von ElasticPress generierte Such-Query so anpassen könnt, dass bei Suchanfragen mit mehreren Begriffen nur Treffer gezeigt werden, bei denen alle Begriffe vorkommen.
Aufmerksam geworden bin ich auf das Problem, als ich hier auf meiner Website nach WordPress-Backup gesucht und erwartet habe, dass mein Beitrag über WordPress-Backups zu AWS oben steht. Stattdessen wurde an Position 1 ein Wochenrückblick gelistet. Daraufhin habe ich mir das Plugin Debug Bar ElasticPress installiert, das die Elasticsearch-Anfragen zeigt, die durch ElasticPress gestellt werden. Der entscheidende Teil der Query sieht so aus:
"should": [
{
"multi_match": {
"query": "WordPress-Backup",
"type": "phrase",
"fields": [
"post_title",
"post_excerpt",
"post_content"
],
"boost": 4,
"fuzziness": 0,
}
},
{
"multi_match": {
"query": "WordPress-Backup",
"fields": [
"post_title",
"post_excerpt",
"post_content"
],
"boost": 2,
"fuzziness": 0,
"operator": "and"
}
},
{
"multi_match": {
"fields": [
"post_title",
"post_excerpt",
"post_content"
],
"query": "WordPress-Backup",
"fuzziness": 1,
}
}
]
Code-Sprache: PHP (php)
Sehr tief bin ich in der Materie immer noch nicht drin, aber hier scheint ja festgelegt zu werden, wie Elasticsearch den Index durchsuchen soll. Beim ersten und letzten multi_match
-Array fehlt der Eintrag "operator": "and"
. Das sah mir nach einem guten Ansatzpunkt aus, weshalb ich mich im ElasticPress-Plugin auf die Suche nach diesem Code und einem Filter zur Anpassung des Arrays gemacht habe. Gesucht, gefunden: ep_formatted_args
bekommt ein Array mit den Argumenten übergeben und ermöglicht dessen Veränderung. Um die beiden "operator": "and"
-Stellen nachzutragen, kommt folgender Code in die functions.php
:
/**
* Add “and” operator to first and third multi_match array from query
*
* @param $formatted_args
* @param $args
*
* @return array
*/
function slug_elasticpress_formatted_args( $formatted_args, $args ) {
$formatted_args["query"]["bool"]["should"]["0"]["multi_match"]["operator"] = "and";
$formatted_args["query"]["bool"]["should"]["2"]["multi_match"]["operator"] = "and";
return $formatted_args;
}
add_filter( 'ep_formatted_args', 'slug_elasticpress_formatted_args', 10, 2 );
Code-Sprache: PHP (php)
Damit wird nun immer nach Ergebnissen gesucht, die alle eingegebenen Wörter enthalten.
Haha, schön zu sehen, dass auch andere genau das gleiche Problem mit der Standardeinstellungen haben 🙂
Ich hatte genau aus diesem Grund zwei Folgeartikel geschrieben. Im ersten erkläre ich ebenfalls, wie ich das Problem mit der Volltextsuche gelöst habe. Ich bin dabei aber einen anderen Weg gegangen. Gestern habe ich dann etwas ausführlicher über die erweiterten Suchparameter zur Unschärfesuche und Gewichtung geschrieben.
Ich bin auch noch dabei, mich tiefer gehend einzuarbeiten. Es ist wirklich nicht einfach, die optimale Suchanfrage zu kreieren. Ich denke daher, dass ElasticPress hier einen eher konservativen Weg verfolgt hat, der eher zu viel, als zu wenig findet.
Danke für den Kommentar und die Links zu deinen Artikeln (wenn ich die mal vorher schon gesehen hätte … ^^), die werde ich mir mal genauer anschauen – du scheinst da schon deutlich tiefer drin zu sein als ich 🙂
Danke für den Artikel, im Code Beispiel ist aber ein Fehler.
Bei der add_filter Funktion fehlen der 3. und 4. Parameter.
Da die Funktion slug_elasticpress_formatted_args zwei parameter entgegennimmt, muss du das im in der add_filter Funktion als vierten Parameter angeben.
Hi Julian,
oh ja, danke für den Hinweis! Hab ich korrigiert 🙂
Viele Grüße
Florian