web-dev-qa-db-fra.com

La recherche dans les types de publication personnalisés et les champs personnalisés prend 5 minutes.

J'ai un problème étrange et je suis coincé. J'ai un type de message personnalisé avec environ 15 champs personnalisés.

J'ai déplacé les données de l'ancienne base de données (pas WP) en utilisant wp_insert_post, update_post_meta et wp_set_object_terms.

Tout s'est bien passé. Toutes les vcards fonctionnent bien. J'ai reçu 3500 vcards et maintenant, lorsque j'essaie de rechercher des vcards - il suffit de geler pendant 10 minutes, puis le timeout est écoulé. La même chose se trouve dans le panneau d'administration si j'essaie de chercher dans un type de message personnalisé, la recherche prend 10 minutes et meurt ... J'ai donc une question: est-ce que wordpress est capable de gérer autant de messages personnalisés? ou j'ai fait une erreur de codage? Si vous avez besoin de n'importe quel type de code à afficher, merci de me dire que je le collerai ici car je ne sais même pas par où commencer la recherche.

Cordialement Charles


Voici un code:

Tout d’abord, je supprime d’autres pages de la recherche - je n’ai besoin que de mon type de message personnalisé

function search_types($query) {
if ( $query->is_search ) 
{
    $query->set('post_type', 'vcard');

}
return $query;

Cette partie du code que j'ai trouvée sur le réseau et que je viens de l'ajuster à mes besoins: je récupère tous les champs personnalisés (maintenant, dans le code, je n'ai qu'un seul champ à tester, normalement environ 15)

function custom_fields_search() {
global $wpdb;

$sql = "SELECT meta_key FROM ". $wpdb->prefix . "postmeta mk WHERE mk.meta_key LIKE 'companyKeyWords'";
$results = $wpdb->get_results( $sql );

if ( $results ) :
    foreach ($results as $result) {
        $custom_fields[] = $result->meta_key;
    }
endif;

return $custom_fields;

Maintenant ces 3 fonctionnent avec filtre

function custom_search_groupby($groupby) {
global $wpdb, $wp_query;

$groupby = "$wpdb->posts.ID";

return $groupby;
function custom_search_join($join) {
global $wpdb, $wp_query;

if ( is_search() && isset($_GET['s']) ) {

    $join  = " INNER JOIN $wpdb->term_relationships AS r ON ($wpdb->posts.ID = r.object_id) ";
    $join .= " INNER JOIN $wpdb->term_taxonomy AS x ON (r.term_taxonomy_id = x.term_taxonomy_id) ";
    $join .= " AND x.taxonomy = '".GO_TAX_CAT."'";


    // if an ad category is selected, limit results to that cat only
    $catid = $wp_query->query_vars['cat'];

    if ( !empty($catid) ) :

        // put the catid into an array
        (array) $include_cats[] = $catid;

        // get all sub cats of catid and put them into the array
        $descendants = get_term_children( (int) $catid, GO_TAX_CAT );

        foreach ( $descendants as $key => $value )
            $include_cats[] = $value;

        // take catids out of the array and separate with commas
        $include_cats = "'" . implode( "', '", $include_cats ) . "'";

        // add the category filter to show anything within this cat or it's children
        $join .= " AND x.term_id IN ($include_cats) ";

    endif; // end category filter


    $join .= " INNER JOIN $wpdb->postmeta AS m ON ($wpdb->posts.ID = m.post_id) ";
    $join .= " INNER JOIN $wpdb->terms AS t ON x.term_id = t.term_id ";

}

return $join;
}

function custom_search_where($where) {
global $wpdb, $wp_query;
$old_where = $where; // intercept the old where statement
if ( is_search() && isset($_GET['s']) ) {

    // get the custom fields to add to search
    $custom_fields = custom_fields_search();
    $customs = $custom_fields;

    $query = '';

    $var_q = stripslashes($_GET['s']);
    //empty the s parameter if set to default search text
    if ( __('What are you looking for?','go') == $var_q ) {
        $var_q = '';
    }

    if ( isset($_GET['sentence']) || $var_q == '' ) {
        $search_terms = array($var_q);
    }
    else {
        preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $var_q, $matches);
        $search_terms = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
    }

    if (!isset($_GET['exact']) ) $_GET['exact'] = '';

    $n = ( $_GET['exact'] ) ? '' : '%';

    $searchand = '';

    foreach ( (array)$search_terms as $term ) {
        $term = addslashes_gpc($term);

        $query .= "{$searchand}(";
        $query .= "($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
        $query .= " OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
        $query .= " OR ((t.name LIKE '{$n}{$term}{$n}')) OR ((t.slug LIKE '{$n}{$term}{$n}'))";

        foreach ( $customs as $custom ) {
            $query .= " OR (";
            $query .= "(m.meta_key = '$custom')";
            $query .= " AND (m.meta_value  LIKE '{$n}{$term}{$n}')";
            $query .= ")";
        }

        $query .= ")";
        $searchand = ' AND ';
    }

    $term = $wpdb->escape($var_q);

    if ( !isset($_GET['sentence']) && count($search_terms) > 1 && $search_terms[0] != $var_q ) {
        $query .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
        $query .= " OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
    }

    if ( !empty($query) ) {

        $where = " AND ({$query}) AND ($wpdb->posts.post_status = 'publish') ";

        // setup the array for post types
        $post_type_array = array();

        // always include the ads post type
        $post_type_array[] = GO_POST_TYPE;


        // build the post type filter sql from the array values
        $post_type_filter = "'" . implode("','",$post_type_array). "'";

        // return the post type sql to complete the where clause
        $where .= " AND ($wpdb->posts.post_type IN ($post_type_filter)) ";

    }
}

return( $where );

A la fin, j'applique les filtres:

add_filter('posts_join', 'custom_search_join');
add_filter('posts_where', 'custom_search_where');
add_filter('posts_groupby', 'custom_search_groupby');
3

Vous avez un preg_match_all(), divers JOINs, anonymous/lambda functions. En bref: tout ce qui fait que le débogage est difficile et que les performances sont irréprochables est tout à fait irréprochable.

En bref: vous devriez plutôt utiliser un meta_query. Jeter un coup d'œil à

Code meta_query " Gestion de plusieurs champs personnalisés:

2
kaiser