Come includere i dati di wp_postmeta nella ricerca?

8 dic 2011, 15:51:39
Visualizzazioni: 47.7K
Voti: 16

Ho un sito che utilizza Advanced Custom Fields per creare e memorizzare varie informazioni rilevanti. Queste devono essere incluse nella ricerca generale principale, che di default cerca solo nel titolo e nel contenuto principale.

Ho trovato molte informazioni su come ottenere risultati di ricerca basati su specifici elementi di postmeta, ma ho un problema con questo. Ci sono potenzialmente un numero illimitato di campi in postmeta da cercare.

La soluzione potrebbe essere quella di cercare qualsiasi cosa in postmeta o qualsiasi cosa con un meta_key che corrisponda a questa espressione regolare: content_section_[0-9]{1,4}_content_.{2,8}

Esempi di meta_keys da trovare sono:

content_section_0_content_title
content_section_0_content_title
content_section_4_content_subtitle
content_section_8_content_text

Qualsiasi modo per modificare i campi di ricerca per includere il postmeta sarebbe molto apprezzato.

2
Commenti

e la domanda è?

Naoise Golden Naoise Golden
8 dic 2011 23:31:53

La ricerca in WordPress non include i dati dai post meta - cerca solo nei campi del titolo e del contenuto. Aggiornerò la domanda principale per chiarire.

Jodi Warren Jodi Warren
9 dic 2011 02:53:07
Tutte le risposte alla domanda 6
2
11

Aggiungi questo al tuo plugin o al file functions.php del tuo tema. L'esempio qui sotto includerà 'your_key' nella ricerca. Puoi includere tutte le tue chiavi ripetendo l'array.


function me_search_query( $query ) {
  if ( $query->is_search ) {
    $meta_query_args = array(
      array(
        'key' => 'your_key',
        'value' => $query->query_vars['s'] = '',
        'compare' => 'LIKE',
      ),
    );
    $query->set('meta_query', $meta_query_args);
  };
}
add_filter( 'pre_get_posts', 'me_search_query');
10 set 2015 01:32:09
Commenti

Questo corrisponderà solo ai post che corrispondono al termine di ricerca nel titolo/contenuto e nel campo meta, il che non è come funziona tipicamente una ricerca full text.

David David
9 lug 2017 19:16:13

Questo sarà estremamente lento poiché i valori meta non sono indicizzati.

vancoder vancoder
18 ago 2020 21:31:38
3

Questa funzione dovrebbe funzionare, anche dopo l'aggiornamento di sicurezza di WP 4.8.3.

Utilizzo:

// Aggiungi questo nel file functions.php

add_meta_field_to_search_query('right_data');
add_meta_field_to_search_query('extra_search_terms');

Implementazione:

/* AGGIUNGI CAMPO META ALLA RICERCA */

function add_meta_field_to_search_query($field){
  if(isset($GLOBALS['added_meta_field_to_search_query'])){
    $GLOBALS['added_meta_field_to_search_query'][] = '\'' . $field . '\'';

    return;
  }

  $GLOBALS['added_meta_field_to_search_query'] = array();
  $GLOBALS['added_meta_field_to_search_query'][] = '\'' . $field . '\'';

  add_filter('posts_join', function($join){
      global $wpdb;

      if (is_search()){    
          $join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";
      }

      return $join;
  });

  add_filter('posts_groupby', function($groupby){
      global $wpdb;

      if (is_search()) {    
          $groupby = "$wpdb->posts.ID";
      }

      return $groupby;
  });

  add_filter('posts_search', function($search_sql){
      global $wpdb;

      $search_terms = get_query_var('search_terms');

      if(!empty($search_terms)){
        foreach ($search_terms as $search_term){
            $old_or = "OR ({$wpdb->posts}.post_content LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}')";
            $new_or = $old_or . " OR ({$wpdb->postmeta}.meta_value LIKE '{$wpdb->placeholder_escape()}{$search_term}{$wpdb->placeholder_escape()}' AND {$wpdb->postmeta}.meta_key IN (" . implode(', ', $GLOBALS['added_meta_field_to_search_query']) . "))";
            $search_sql = str_replace($old_or, $new_or, $search_sql);
        }
      }

      $search_sql = str_replace( " ORDER BY ", " GROUP BY $wpdb->posts.ID ORDER BY ", $search_sql );

      return $search_sql;
  });
}

Diverse persone hanno implementato questo in modi diversi:

http://websmartdesign.nz/searching-structured-post-data-with-wordpress/ https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/

28 ago 2017 13:42:45
Commenti

Il link per adambalee.com ha funzionato per me. Esegue semplicemente una ricerca generale in tutti i meta dei post.

Joe Joe
29 gen 2019 17:09:24

Allo stesso modo, la soluzione linkata su https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/ ha funzionato per me su WordPress 5.1.1...

jsmod jsmod
29 mar 2019 17:55:20

hai trovato un modo per cercare solo alcuni campi personalizzati? Ne ho molti e quasi ogni ricerca corrisponde a qualche contenuto anche se è solo per l'amministratore.

v3nt v3nt
16 giu 2020 18:59:42
1

Questa è una versione migliorata della risposta di Ahmed:

function me_search_query( $query ) {
  if ( $query->is_search ) {
    $meta_query_args = array(
      array(
        'key' => 'your_key',
        'value' => $query->query_vars['s'],
        'compare' => 'LIKE',
      ),
    );
    $query->set('meta_query', $meta_query_args);
    add_filter( 'get_meta_sql', 'me_replace_and_with_or' );
  };
}

function me_replace_and_with_or( $sql ) {
    if ( 1 === strpos( $sql['where'], 'AND' ) ) {
        $sql['where'] = substr( $sql['where'], 4 );
        $sql['where'] = ' OR ' . $sql['where'];
    }

    //assicurati che questo filtro venga eseguito solo una volta per la meta query
    remove_filter( 'get_meta_sql', 'me_replace_and_with_or' );
    return $sql;
}

add_filter( 'pre_get_posts', 'me_search_query');

Il problema è che WordPress genera la meta query con l'operatore "AND", e mostrerebbe solo i post che hanno la stringa di ricerca in entrambi i luoghi - titolo E meta, oppure contenuto E meta. Quindi, abbiamo bisogno di creare un filtro aggiuntivo per cambiare "AND" in "OR" (e poi rimuovere quel filtro per non rompere nient'altro).

29 dic 2018 18:28:28
Commenti

Cambiare l'AND in OR interrompe la logica SQL per filtrare il tipo di POST, quindi la ricerca verrà applicata a tutti i tipi di post, inclusi gli allegati. Sto ancora cercando di trovare una soluzione valida che funzioni con la combinazione di ricerca e filtri su un CPT

Alan Fuller Alan Fuller
2 nov 2021 17:12:47
0

Se vuoi utilizzare un plugin, Relevanssi - Una ricerca migliore potrebbe valere la pena provare.

La versione standard (gratuita) supporta la ricerca nei metadati dei post.

9 dic 2011 04:36:01
0

Questa è la soluzione più semplice e attualmente funzionante. Nessuna delle precedenti ha funzionato per me. È testata e funzionante con Wordpress 5.3.1.

Inserisci il seguente codice nel tuo file functions.php per agganciarti al filtro posts_clauses.

/**
 * Includi i campi meta nella ricerca
 * 
 * @author Mindaugas // meevly.com
 * @link https://meevly.com/services/custom-wordpress-themes-and-plugins/
 * 
 * @param array $pieces pezzi della query.
 * @param WP_Query $args oggetto della query.
 * @return array
 */
function mv_meta_in_search_query( $pieces, $args ) {
    global $wpdb;

    if ( ! empty( $args->query['s'] ) ) { // esegui solo su query di ricerca.
        $keywords        = explode(' ', get_query_var('s'));
        $escaped_percent = $wpdb->placeholder_escape(); // WordPress scappa il carattere "%" dalla versione 4.8.3, quindi non possiamo usare direttamente il carattere percentuale.
        $query           = "";

        foreach ($keywords as $word) {
            $query .= " (unique_postmeta_selector.meta_value LIKE '{$escaped_percent}{$word}{$escaped_percent}') OR ";
        }

        if ( ! empty( $query ) ) { // aggiungi le clausole WHERE e JOIN necessarie.
            $pieces['where'] = str_replace( "((({$wpdb->posts}.post_title LIKE '{$escaped_percent}", "( {$query} (({$wpdb->posts}.post_title LIKE '{$escaped_percent}", $pieces['where'] );
            $pieces['join'] = $pieces['join'] . " INNER JOIN {$wpdb->postmeta} AS unique_postmeta_selector ON ({$wpdb->posts}.ID = unique_postmeta_selector.post_id) ";
        }
    }

    return $pieces;
}
add_filter( 'posts_clauses', 'mv_meta_in_search_query', 20, 2 );

E la tua query dovrebbe essere simile alla seguente. Nota che suppress_filters => false è obbligatorio! Non funzionerà senza di esso.

$search_posts_array = array(
    'suppress_filters' => false,
    's'                => $keyword,
);

$search_results = get_posts( $search_posts_array );
9 gen 2020 13:18:39
0
-1

Non sono sicuro, ma per ottenere tutte le chiavi/valori dei campi personalizzati per la ricerca predefinita sarebbe necessaria una chiamata al database utilizzando wpdb.

L'alternativa ai plugin menzionati da goto10 è una soluzione molto più semplice. Search Everything, WP Custom Fields Search

9 dic 2011 05:13:03