Meta-Abfrage (‘Meta-Abfrage’) mit einer Suchanfrage (‘s’) verwenden

Versuche, eine Suche zu erstellen, die nicht nur die Standardwerte (Titel, Inhalt usw.) durchsucht, sondern auch ein bestimmtes benutzerdefiniertes Feld.

Meine aktuelle Anfrage:

$args = array( 'post_type' => 'post', 's' => $query, 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) ); $search = new WP_Query( $args ) ... 

Dies gibt Beiträge zurück, die sowohl der Suchabfrage als auch der Meta-Abfrage entsprechen, aber ich möchte auch, dass sie auch Beiträge zurückgibt, wo sie einfach mit einem von beiden übereinstimmen.

Irgendwelche Ideen?

Solutions Collecting From Web of "Meta-Abfrage (‘Meta-Abfrage’) mit einer Suchanfrage (‘s’) verwenden"

Ich habe stundenlang nach einer Lösung für dieses Problem gesucht. Array-Zusammenführung ist nicht der richtige Weg, insbesondere wenn die Abfragen komplex sind und Sie in der Zukunft Meta-Abfragen hinzufügen können. Die Lösung, die einfach schön ist, besteht darin, ‘s’ so zu ändern, dass sowohl Titel als auch Meta-Felder gesucht werden können.

 add_action( 'pre_get_posts', function( $q ) { if( $title = $q->get( '_meta_or_title' ) ) { add_filter( 'get_meta_sql', function( $sql ) use ( $title ) { global $wpdb; // Only run once: static $nr = 0; if( 0 != $nr++ ) return $sql; // Modified WHERE $sql['where'] = sprintf( " AND ( %s OR %s ) ", $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title), mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) ) ); return $sql; }); } }); 

Verwendung:

 $meta_query = array(); $args = array(); $search_string = "test"; $meta_query[] = array( 'key' => 'staff_name', 'value' => $search_string, 'compare' => 'LIKE' ); $meta_query[] = array( 'key' => 'staff_email', 'value' => $search_string, 'compare' => 'LIKE' ); //if there is more than one meta query 'or' them if(count($meta_query) > 1) { $meta_query['relation'] = 'OR'; } // The Query $args['post_type'] = "staff"; $args['_meta_or_title'] = $search_string; //not using 's' anymore $args['meta_query'] = $meta_query; $the_query = new WP_Query($args) 

Durch die Verwendung einer modifizierten Version dieser Antwort kann viel Code reduziert werden.

 $q1 = new WP_Query( array( 'post_type' => 'post', 'posts_per_page' => -1, 's' => $query )); $q2 = new WP_Query( array( 'post_type' => 'post', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) )); $result = new WP_Query(); $result->posts = array_unique( array_merge( $q1->posts, $q2->posts ), SORT_REGULAR ); $result->post_count = count( $result->posts ); 

Gemäß dem Vorschlag von Nick Perkins musste ich zwei Abfragen wie folgt zusammenführen:

 $q1 = get_posts(array( 'fields' => 'ids', 'post_type' => 'post', 's' => $query )); $q2 = get_posts(array( 'fields' => 'ids', 'post_type' => 'post', 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) )); $unique = array_unique( array_merge( $q1->posts, $q2->posts ) ); $posts = get_posts(array( 'post_type' => 'posts', 'post__in' => $unique, 'post_status' => 'publish', 'posts_per_page' => -1 )); if( $posts ) : foreach( $posts as $post ) : setup_postdata($post); // now use standard loop functions like the_title() etc. enforeach; endif; 

Nun, es ist eine Art Hack, aber es funktioniert. Sie müssen den posts_clauses-Filter hinzufügen. Diese Filterfunktionsprüfung für das beliebige Abfragewort existiert im benutzerdefinierten Feld “speel” und die verbleibende Abfrage bleibt intakt.

 function custom_search_where($pieces) { // filter for your query if (is_search() && !is_admin()) { global $wpdb; $keywords = explode(' ', get_query_var('s')); $query = ""; foreach ($keywords as $word) { // skip possible adverbs and numbers if (is_numeric($word) || strlen($word) < = 2) continue; $query .= "((mypm1.meta_key = 'speel')"; $query .= " AND (mypm1.meta_value LIKE '%{$word}%')) OR "; } if (!empty($query)) { // add to where clause $pieces['where'] = str_replace("(((wp_posts.post_title LIKE '%", "( {$query} ((wp_posts.post_title LIKE '%", $pieces['where']); $pieces['join'] = $pieces['join'] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)"; } } return ($pieces); } add_filter('posts_clauses', 'custom_search_where', 20, 1); 

Ich hatte das gleiche Problem, für meine neue Seite habe ich gerade einen neuen Meta “Titel” hinzugefügt:

functionen.php

 add_action('save_post', 'title_to_meta'); function title_to_meta($post_id) { update_post_meta($post_id, 'title', get_the_title($post_id)); } 

Und dann … füge einfach so etwas hinzu:

 $sub = array('relation' => 'OR'); $sub[] = array( 'key' => 'tags', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $sub[] = array( 'key' => 'description', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $sub[] = array( 'key' => 'title', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $params['meta_query'] = $sub; 

Was denkst du über diese Problemumgehung?

Ich habe die @Stabir Kira Antwort ein bisschen optimiert

 function wp78649_extend_search( $query ) { $search_term = filter_input( INPUT_GET, 's', FILTER_SANITIZE_NUMBER_INT) ?: 0; if ( $query->is_search && !is_admin() && $query->is_main_query() && //your extra condition ) { $query->set('meta_query', [ [ 'key' => 'meta_key', 'value' => $search_term, 'compare' => '=' ] ]); add_filter( 'get_meta_sql', function( $sql ) { global $wpdb; static $nr = 0; if( 0 != $nr++ ) return $sql; $sql['where'] = mb_eregi_replace( '^ AND', ' OR', $sql['where']); return $sql; }); } return $query; } add_action( 'pre_get_posts', 'wp78649_extend_search'); 

Jetzt können Sie suchen nach (Titel, Inhalt, Ausscheidung) oder (Meta-Feld) oder (beide).