Eseguire una ricerca WP Query con corrispondenza esatta del termine
Sto usando WP Query e i risultati che ottengo quando uso il termine di ricerca non funzionano come vorrei. Per esempio, cercando 'art' vengono restituiti anche risultati per parole che contengono 'art' come 'part'. Come posso evitare questo comportamento e ottenere solo risultati per la parola esatta 'art'?
Per ottenere una corrispondenza esatta, puoi utilizzare questo approccio:
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'sentence' => true, // Cerca l'intera frase invece di parole separate
's' => ' ' . $search_term . ' ' // Aggiungi spazi per cercare la parola esatta
);
// Modifica la query per una corrispondenza esatta
add_filter('posts_where', function($where) use ($search_term) {
global $wpdb;
$where = str_replace(
"(" . $wpdb->posts . ".post_title LIKE",
"(" . $wpdb->posts . ".post_title REGEXP '[[:<:]]" . $search_term . "[[:>:]]' OR " . $wpdb->posts . ".post_title LIKE",
$where
);
return $where;
});
In alternativa, puoi utilizzare questo metodo più preciso:
add_filter('posts_search', function($search, $wp_query) {
if (!empty($search) && !empty($wp_query->query_vars['search_terms'])) {
global $wpdb;
$q = $wp_query->query_vars;
$n = !empty($q['exact']) ? '' : '%';
$search = array();
foreach ((array)$q['search_terms'] as $term) {
$search[] = $wpdb->prepare(
"($wpdb->posts.post_title REGEXP '[[:<:]]%s[[:>:]]')
OR ($wpdb->posts.post_content REGEXP '[[:<:]]%s[[:>:]]')",
$term, $term
);
}
if (!empty($search)) {
$search = ' AND (' . implode(' AND ', $search) . ')';
}
}
return $search;
}, 10, 2);
Questi metodi useranno espressioni regolari per trovare corrispondenze esatte delle parole, evitando risultati parziali come nell'esempio "part" quando si cerca "art".
Penso che qualcun altro abbia già risposto a questo: Guarda questa risposta, da @Sunyatasattva
Ma apparentemente WP_Query supporta alcuni parametri di ricerca aggiuntivi:
's' => $s, //(string) - Passa la variabile della stringa di query da una ricerca.
'exact' => true, //(bool) - flag per far corrispondere solo titoli/post completi - Il valore predefinito è false.
'sentence' => true, //(bool) - flag per effettuare una ricerca per frase - Il valore predefinito è false.
Maggiori informazioni su: https://gist.github.com/luetkemj/2023628
Spero sia utile,

Sfortunatamente il parametro sentence => true
non fa ciò che l'utente desidera. Piuttosto significa che WP restituirà solo i post dove la parte di una frase esiste, mentre normalmente restituirebbe corrispondenze per parte OR
di OR
una OR
frase. In entrambi i casi i risultati non sarebbero quelli richiesti se fosse fatta una ricerca per arte.

Questa è una domanda piuttosto complicata, perché specificando esattamente ci sono due modi in cui si può interpretare la tua domanda -
- Trovare solo i post in cui l'intero titolo o l'intero contenuto corrispondono esattamente. Ad esempio, se cerchi Il mio post è super non otterresti un post con il titolo Il mio post è super fantastico.
- Trovare i post in cui esiste l'esatta frase, non solo una parte di essa. Ad esempio, se cerchi la sua casa non otterresti un post con il titolo Amo questa casa, ma otterresti un post con il titolo Vado alla sua casa (esempi banali, ma spero che il concetto sia chiaro).
Fortunatamente puoi fare entrambe le cose, ma il metodo 1 è di gran lunga il più semplice. Aggiungi uno di questi esempi al tuo file functions.php -
Metodo 1
add_action('pre_get_posts', 'my_make_search_exact', 10);
function my_make_search_exact($query){
if(!is_admin() && $query->is_main_query() && $query->is_search) :
$query->set('exact', true);
endif;
}
La funzione my_make_search_exact()
verrà chiamata ogni volta che viene effettuata una query, utilizzando l'hook di azione pre_get_posts
.
Per assicurarci di non interferire con la query quando non è necessario, all'interno della funzione controlliamo che NON stiamo visualizzando l'area di amministrazione, che stiamo costruendo la query principale e che stiamo effettuando una ricerca.
Metodo 2
add_filter('posts_search', 'my_search_is_exact', 20, 2);
function my_search_is_exact($search, $wp_query){
global $wpdb;
if(empty($search))
return $search;
$q = $wp_query->query_vars;
$n = !empty($q['exact']) ? '' : '%';
$search = $searchand = '';
foreach((array)$q['search_terms'] as $term) :
$term = esc_sql(like_escape($term));
$search.= "{$searchand}($wpdb->posts.post_title REGEXP '[[:<:]]{$term}[[:>:]]') OR ($wpdb->posts.post_content REGEXP '[[:<:]]{$term}[[:>:]]')";
$searchand = ' AND ';
endforeach;
if(!empty($search)) :
$search = " AND ({$search}) ";
if(!is_user_logged_in())
$search .= " AND ($wpdb->posts.post_password = '') ";
endif;
return $search;
}
Crediti a tinyGod per questa risposta - http://tinygod.pt/make-wordpress-search-exact/
