Suche, die im benutzerdefinierten Feld, im Post-Titel und im Post-Inhalt angezeigt wird
1 Antworten
- Stimmen
-
- 2013-05-17
Verwenden Sie zunächst keine
query_posts
.Zweitens können Sieeinen
s
-Parameter übergeben,um dengrößten Teil des Weges dorthin zugelangen.$program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search, 'meta_query' => array( array( 'key' => 'keywords', 'value' => $program_search, 'compare' => 'LIKE' ), ) ); $t = new WP_Query($args); var_dump($t->request);
Mit diesem
s
-Parameter werden dienormalen Suchmechanismen aktiviert,und der Titel und der Inhalt werden durchsucht. Wenn Sie sich diesegenerierte Abfrage ansehen,sehen Sie ...SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type = 'program' AND (wp_posts.post_status = 'publish') AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5
Dasist dasmeiste,was Sie wollen. Das
LIMIT
ist,sofernnicht anders angegeben,das unter wp-admin-> Settings-> Generalfestgelegte Limit. Esgibt jedochein Problem.AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%'))
Ichbin mir ziemlich sicher,dass dies
OR ((wp_postmeta.meta_key ...
) sein soll,und Siemöchten wirklich,dassesmit dempost_title
und dempost_content
auch soetwas:AND ( ( (wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%') OR (wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%') ) )
WP_Query
macht dasnicht,alsomüssen wiresmit einigen Filternmachen. Proof of Concept:function add_join_wpse_99849($joins) { global $wpdb; return $joins . " INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)"; } function alter_search_wpse_99849($search,$qry) { global $wpdb; $add = $wpdb->prepare("({$wpdb->postmeta}.meta_key = 'keywords' AND CAST({$wpdb->postmeta}.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s')); $pat = '|\(\((.+)\)\)|'; $search = preg_replace($pat,'(($1 OR '.$add.'))',$search); return $search; } $program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search ); add_filter('posts_join','add_join_wpse_99849'); add_filter('posts_search','alter_search_wpse_99849',1,2); $t = new WP_Query($args); remove_filter('posts_join','add_join_wpse_99849'); remove_filter('posts_search','alter_search_wpse_99849',1,2); // dump some data var_dump($t->request); var_dump($t->posts);
Beachten Sie,dassich die
meta_query
komplett weggelassen und die Funktionalität weitgehend dupliziert habe. Dies soll verhindern,dass dasproblematischeAND
generiert wird.Sie wenden diese Filter an undentfernen sie sofort,damit sie keine anderen Abfragen stören. Esgibt andere Möglichkeiten,den Filter oder andere Abfragen aus dem Weg zu räumen. Eine solche Methode wird hierbeschrieben . Sie können den
remove_filter
auch zumadd_filter
-Rückruf hinzufügen,damit sie sich automatisch selbstentfernen.First, don't use
query_posts
.Second, you can pass an
s
parameter to get most of the way there.$program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search, 'meta_query' => array( array( 'key' => 'keywords', 'value' => $program_search, 'compare' => 'LIKE' ), ) ); $t = new WP_Query($args); var_dump($t->request);
That
s
parameter kicks the ordinary search mechanisms into place and the title and the content gets searched. If you look at that generated query you will see...SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type = 'program' AND (wp_posts.post_status = 'publish') AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5
That is most of what you want. The
LIMIT
unless otherwise specified is the limit set at wp-admin->Settings->General. There is a problem though.AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%'))
I am pretty sure you want that to be
OR ((wp_postmeta.meta_key ...
and you really want it up with thepost_title
and thepost_content
too. Something like this:AND ( ( (wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%') OR (wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%') ) )
WP_Query
won't do that so we have to make it with some filters. Proof of concept:function add_join_wpse_99849($joins) { global $wpdb; return $joins . " INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)"; } function alter_search_wpse_99849($search,$qry) { global $wpdb; $add = $wpdb->prepare("({$wpdb->postmeta}.meta_key = 'keywords' AND CAST({$wpdb->postmeta}.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s')); $pat = '|\(\((.+)\)\)|'; $search = preg_replace($pat,'(($1 OR '.$add.'))',$search); return $search; } $program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search ); add_filter('posts_join','add_join_wpse_99849'); add_filter('posts_search','alter_search_wpse_99849',1,2); $t = new WP_Query($args); remove_filter('posts_join','add_join_wpse_99849'); remove_filter('posts_search','alter_search_wpse_99849',1,2); // dump some data var_dump($t->request); var_dump($t->posts);
Notice that I left out the
meta_query
altogether and largely duplicated the functionality. That is to keep that troublesomeAND
from being generated.You are applying and immediately removing those filters so they do not interfere with any other queries. There are other ways to keep the filter out of the way or other queries. One such method is outlined here. You can also add the
remove_filter
to theadd_filter
callback to have them automatically remover themselves.-
Können Sieerklären,warum Sie query_posts NICHT verwenden?Can you explain why NOT to use query_posts?
- 0
- 2018-10-12
- Lee
Ich suchenacheiner Möglichkeit,eine Suche durchzuführen. Während der Suche wirdein benutzerdefiniertes Feldmit den Namen "Schlüsselwörter",dem Titel des Beitrags und dem Inhalt des Beitrags überprüft. Wenneines dieser Felder Ergebnisseenthält,wie sie der Benutzer sucht,wird derbenutzerdefinierte Beitragstyp (Programme) auf der Ergebnisseite angezeigt.
Ichbrauche keine Hilfebeim Endergebnis der Anzeige (esmacht derzeit das,wasichmöchte),aberichmusses somachen,dassesbei der Suche alle drei Felder (Post-Titel,Post-Inhalt undbenutzerdefiniertes Feld) überprüft Schlüsselwörter),und wenneines vonihnenein Ergebnis wie dasgesuchte hat,werden die Ergebnisse angezeigt. Diesist der Code,denichbisher habe. Derzeit wirdnurim benutzerdefinierten Feldfür Schlüsselwörtergesucht: