Cum să incluzi date din wp_postmeta în căutare?

8 dec. 2011, 15:51:39
Vizualizări: 47.7K
Voturi: 16

Am un site care folosește Advanced Custom Fields pentru a crea și stoca diverse informații relevante. Acestea trebuie incluse în căutarea generală principală, care în mod implicit caută doar în titlu și conținutul principal.

Am găsit multe informații despre obținerea rezultatelor căutării bazate pe anumite părți din postmeta, dar am o problemă cu asta. Există un număr potențial nelimitat de câmpuri în postmeta care trebuie căutate.

Soluția ar putea fie să caute orice în postmeta, fie să caute orice cu un meta_key care se potrivește cu această expresie regulată: content_section_[0-9]{1,4}_content_.{2,8}

Exemple de meta_keys care trebuie să se potrivească sunt:

content_section_0_content_title
content_section_0_content_title
content_section_4_content_subtitle
content_section_8_content_text

Orice modalitate prin care pot modifica câmpurile căutate pentru a include postmeta ar fi foarte apreciată.

2
Comentarii

și întrebarea este?

Naoise Golden Naoise Golden
8 dec. 2011 23:31:53

Căutarea în WordPress nu caută date din post meta - caută doar în câmpurile de titlu și conținut. Voi actualiza întrebarea principală pentru a clarifica.

Jodi Warren Jodi Warren
9 dec. 2011 02:53:07
Toate răspunsurile la întrebare 6
2
11

Adăugați acest cod în plugin-ul dvs. sau în fișierul functions.php al temei. Exemplul de mai jos va include 'your_key' în căutare. Puteți include toate cheile dorite prin repetarea array-ului.

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 sept. 2015 01:32:09
Comentarii

Acesta va potrivi doar articolele care corespund termenului de căutare în titlu/conținut și în câmpul meta, ceea ce nu este modul în care funcționează de obicei o căutare full-text.

David David
9 iul. 2017 19:16:13

Acest lucru va fi extrem de lent deoarece valorile meta nu sunt indexate.

vancoder vancoder
18 aug. 2020 21:31:38
3

Această funcție ar trebui să funcționeze, chiar și după actualizarea de securitate WP 4.8.3.

Utilizare:

// Adăugați acest cod în functions.php

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

Implementare:

/* ADĂUGĂ CÂMP META ÎN INTEROGAREA DE CĂUTARE */

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;
  });
}

Mai multe persoane au implementat această funcționalitate în moduri diferite:

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

28 aug. 2017 13:42:45
Comentarii

Link-ul pentru adambalee.com a funcționat pentru mine. Face doar o căutare generală în toate metadatele postărilor.

Joe Joe
29 ian. 2019 17:09:24

La fel, soluția prezentată la https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/ a funcționat pentru mine pe WordPress 5.1.1...

jsmod jsmod
29 mar. 2019 17:55:20

ai reușit să găsești o metodă de a căuta doar în câteva câmpuri personalizate? Am multe și aproape fiecare căutare găsește un rezultat, chiar dacă este doar pentru administrator.

v3nt v3nt
16 iun. 2020 18:59:42
1

Acesta este un răspuns îmbunătățit al lui 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'];
    }

    //asigură-te că acest filtru se va declanșa doar o singură dată pentru interogarea meta
    remove_filter( 'get_meta_sql', 'me_replace_and_with_or' );
    return $sql;
}

add_filter( 'pre_get_posts', 'me_search_query');

Problema este că WordPress generează interogări meta cu operatorul "AND", ceea ce ar afișa doar postările care conțin șirul de căutare în ambele locuri - titlu ȘI meta, sau conținut ȘI meta. Prin urmare, trebuie să creăm un filtru suplimentar pentru a schimba "AND" în "OR" (și apoi să eliminăm acel filtru pentru a nu afecta altceva).

29 dec. 2018 18:28:28
Comentarii

Schimbarea operatorului AND în OR distruge logica SQL pentru filtrarea tipului POST, astfel încât căutarea se va aplica pe toate tipurile de postări, inclusiv fișierele atașate. Încă încerc să găsesc o soluție viabilă care să funcționeze atât cu căutarea, cât și cu filtrele combinate pe un CPT (Custom Post Type).

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

Dacă ești dispus să folosești un plugin, Relevanssi - O Căutare Mai Bună ar putea fi o opțiune de încercat.

Versiunea standard (gratuită) suportă căutarea în meta-datelor articolelor.

9 dec. 2011 04:36:01
0

Acesta este cea mai simplă și funcțională soluție în prezent. Niciuna dintre cele menționate mai sus nu a funcționat pentru mine. Este testat și funcționează cu WordPress 5.3.1.

Introduceți următorul cod în fișierul functions.php pentru a-l conecta la filtrul posts_clauses.

/**
 * Include meta fields in search
 * 
 * @author Mindaugas // meevly.com
 * @link https://meevly.com/services/custom-wordpress-themes-and-plugins/
 * 
 * @param array $pieces componentele interogării.
 * @param WP_Query $args obiectul interogării.
 * @return array
 */
function mv_meta_in_search_query( $pieces, $args ) {
    global $wpdb;

    if ( ! empty( $args->query['s'] ) ) { // rulează doar la interogarea de căutare.
        $keywords        = explode(' ', get_query_var('s'));
        $escaped_percent = $wpdb->placeholder_escape(); // WordPress scapează "%" începând cu versiunea 4.8.3, așa că nu putem folosi caracterul procent direct.
        $query           = "";

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

        if ( ! empty( $query ) ) { // adaugă condițiile WHERE și JOIN necesare.
            $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 );

Și interogarea ar trebui să arate astfel. Vă rugăm să rețineți că suppress_filters => false este obligatoriu! Nu va funcționa fără el.

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

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

Nu sunt sigur, dar pentru a prelua toate cheile/valorile câmpurilor personalizate pentru căutarea implicită ar fi necesară o interogare la baza de date folosind wpdb.

Alternativa la plugin-urile menționate de goto10 reprezintă o soluție mult mai simplă. Search Everything, WP Custom Fields Search

9 dec. 2011 05:13:03