Erweiterte WordPress-Suche

Ich habe verschiedene Wege und Mittel versucht, um ein Benutzerformular zu erstellen, mit dem man eine WordPress-Seite mit den folgenden Feldern durchsuchen kann:

All of these words:  The exact phrase:  Any of these words:  None of these words:  

Aber ich bringe es einfach nicht zum Laufen – ist das sogar im WordPress-Szenario möglich?

Ich dachte, ich könnte irgendwie den “s” -Parameter manipulieren und Operatoren wie Plus, Minus und doppelte Anführungszeichen übergeben, aber das scheint nicht zu funktionieren.

Jedes Plugin oder jede Seite, die ich in der WordPress-Suche finde, bietet verschiedene Möglichkeiten, um Kategorien oder Tags anzugleichen, aber keine, um den “s” -Parameter selbst zu behandeln

Ist das tatsächlich möglich oder gehe ich einfach den falschen Weg?

Solutions Collecting From Web of "Erweiterte WordPress-Suche"

Es ist irgendwie möglich, da Sie SQL-Abfragen so formulieren können, dass sie Ihren Bedingungen entsprechen, aber es wird nicht sehr gut funktionieren, da die MySQL-Tabellenstruktur nicht für diese Art von Volltextsuche ausgelegt ist.

Die Lösung erfordert jedoch mehr, als nur die Suchabfrage (die Benutzereingabe) an die standardmäßige WordPress-Abfragevariable zu übergeben. Sie müssen die vollständige SQL-Abfrage manuell anpassen.

Sehen wir uns zuerst die konkreten MySQL-Klauseln für jede Ihrer Bedingungen an. In den Beispielen lorem ipsum dolor ich davon aus, dass die Suchanfrage des Benutzers lorem ipsum dolor .

All diese Wörter

 WHERE 1=1 AND `post_content` LIKE "%lorem%" AND `post_content` LIKE "%ipsum%" AND `post_content` LIKE "%dolor%" 

Das Beispiel zeigt nur die WHERE Klausel und vergleicht nur mit dem post_content Feld. Da wir wollen, dass das Ergebnis allen drei Wörtern entspricht, suchen wir jedes Wort allein und kombinieren jeden Vergleich mit einem AND . % ist ein Platzhalterzeichen, das besagt, dass möglicherweise andere Zeichen vorhanden sind oder nicht.

Der genaue Ausdruck

 WHERE 1=1 AND `post_content` LIKE "%lorem ipsum dolor%" 

In diesem Fall stimmen wir mit der genauen Wortgruppe überein.

Irgendeines dieser Wörter

 WHERE 1=1 AND `post_content` LIKE "%lorem%" OR `post_content` LIKE "%ipsum%" OR `post_content` LIKE "%dolor%" 

Dieser sieht dem ersten Beispiel ziemlich ähnlich, außer dass wir das AND durch ein OR wie wir eines oder mehrere dieser Wörter wollen.

Keines dieser Wörter

 WHERE 1=1 AND `post_content` NOT LIKE "%lorem%" AND `post_content` NOT LIKE "%ipsum%" AND `post_content` NOT LIKE "%dolor%" 

Schließlich kehren wir die Logik um und suchen nach Einträgen, die nicht mit jedem der Wörter in der Suchanfrage übereinstimmen .

Filtern Sie die WordPress-Abfrage

Der wichtige Filter zum Ändern der WHERE Klausel in der WordPress-DB-Abfrage heißt posts_where .

Um nur die Hauptabfrage zu beeinflussen, würde ich auf pre_get_posts , um den callback posts_where :

 < ?php add_action( 'pre_get_posts', function( WP_Query $main_query ) { // Don't filter custom queries if ( ! $main_query->is_main_query() ) return; // Validate the request if it comes from your search form if ( ! wpse235391_is_custom_search() ) { return; } add_filter( 'posts_where', function( $where, WP_Query $query ) use ( $main_query ) { // Don't filter other queries than our main query if ( $query !== $main_query ) { return $where; } // Validate and sanitize your search query here // Don't forget to use esc_sql() on each term! $search_query = trim( $_GET[ 'search_input' ] ); $search_words = explode( ' ', $search_query ); // remove empty words $search_words = array_filter( $search_words, function( $value ) { return $value !== ''; } ); array_map( 'esc_sql', $search_words ); // Build the WHERE clause according to your request return $where; } ); } ); 

Bitte beachten Sie, dass dieser Code nur ein Beispiel ist, das den allgemeinen process beschreiben sollte. Ich würde nicht vorschlagen, diesen Code in der Produktion zu verwenden, da er nicht testbar ist. Die Verwendung anonymer functionen ist nur eine Möglichkeit, den Code auf den wesentlichen Teil zu reduzieren. Es wird auch nicht von mir selbst getestet und könnte einige weitere Verbesserungen benötigen, um die Interoperabilität zu erhöhen. ZB gibt das bedingte Tag is_search() in diesem Fall FALSE zurück.

Ein Wort zur Skalierbarkeit

Diese Abfragen sind im Vergleich zu den Standard-WordPress-Abfragen teuer. Das bedeutet, dass sie langsam laufen, wenn Sie einen großen Datenpool haben und sie Ihren MySQL-Server belasten, wenn Sie hohe Zugriffszahlen bei Ihrer Suche erwarten (z. B. bei der Suche nach einer automatisch vorgeschlagenen Benutzeroberfläche). Das ist nichts, was komplett “wegoptimiert” werden kann, wir stoßen gerade an die Grenzen von MySQL. In diesen Fällen ist es besser, einen optimierten Suchindex wie Solr oder Elasticsearch zu verwenden .