web-dev-qa-db-fra.com

Existe-t-il une fonction/plugin de recherche admin plus efficace?

Les rédacteurs de notre grande installation Wordpress adorent utiliser la fonctionnalité de recherche de contenu. Aussi pratique que soit cette fonctionnalité, la complexité de ses requêtes ralentit considérablement notre base de données. Voici un exemple d'une requête SQL trouvée dans notre journal de requête lent il y a quelques minutes à peine:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID 
FROM wp_posts  
WHERE 1=1  
AND (
    ((wp_posts.post_title LIKE '%Made%') OR (wp_posts.post_content LIKE '%Made%')) 
    AND ((wp_posts.post_title LIKE '%in%') OR (wp_posts.post_content LIKE '%in%')) 
    AND ((wp_posts.post_title LIKE '%the%') OR (wp_posts.post_content LIKE '%the%')) 
    AND ((wp_posts.post_title LIKE '%shade:%') OR (wp_posts.post_content LIKE '%shade:%')) 
    AND ((wp_posts.post_title LIKE '%Easy%') OR (wp_posts.post_content LIKE '%Easy%')) 
    AND ((wp_posts.post_title LIKE '%tips%') OR (wp_posts.post_content LIKE '%tips%')) 
    AND ((wp_posts.post_title LIKE '%to%') OR (wp_posts.post_content LIKE '%to%')) 
    AND ((wp_posts.post_title LIKE '%care%') OR (wp_posts.post_content LIKE '%care%')) 
    AND ((wp_posts.post_title LIKE '%for%') OR (wp_posts.post_content LIKE '%for%')) 
    AND ((wp_posts.post_title LIKE '%your%') OR (wp_posts.post_content LIKE '%your%')) 
    AND ((wp_posts.post_title LIKE '%outdoor%') OR (wp_posts.post_content LIKE '%outdoor%')) 
    AND ((wp_posts.post_title LIKE '%furniture%') OR (wp_posts.post_content LIKE '%furniture%'))
)  
AND wp_posts.post_type = 's5_post' 
AND (
    wp_posts.post_status = 'publish' 
    OR wp_posts.post_status = 'future' 
    OR wp_posts.post_status = 'draft' 
    OR wp_posts.post_status = 'pending' 
    OR wp_posts.post_status = 'private'
)  
ORDER BY wp_posts.post_date DESC LIMIT 0, 20

Découvrez la taille de ce gars! Ce n'est pas étonnant que cela fonctionne lentement.

Je serais intéressé d'entendre des idées sur la façon de coder quelques modifications à cette fonctionnalité pour la rendre un peu plus efficace. (J'ai déjà quelques idées personnelles; j'espère que les vôtres sont meilleures que les miennes! :))

5
rinogo

Modification de la clause WHERE

Un filtre nommé posts_search permet de filtrer la clause SQL WHERE utilisée pour la requête lors de la recherche (lorsque WP_Query::is_search() renvoie true et que WP_Query->s est défini):

add_filter( 'posts_search', 'wpse134392PostsSearchSQL', 20, 2 );
function wpse134392PostsSearchSQL( $sql, $wp_query )
{
    // Alter SQL clause here

    return $where;
}

Personnalisé ORDERBY

Pour intercepter l'instruction ORDERBY (par exemple, pour trier par auteur afin que l'auteur de la recherche obtienne ses publications en premier/dernier), vous pouvez utiliser posts_search_orderby:

add_filter( 'posts_search_orderby', 'wpse134392PostsSearchOrderbySQL', 20, 2 );
function wpse134392PostsSearchOrderbySQL( $orderby, $wp_query )
{
    if ( is_admin() )
        return $GLOBALS['wpdb']->posts."post_date";

    return $orderby;
}

SQL à grain fin

Vous pouvez également modifier le posts_clauses ou le pre_get_posts pour obtenir des résultats encore plus précis en vérifiant dans votre rappel si is_admin() et $query->is_search() sont TRUE.

Ne pas rechercher tout

Pour exclure les termes courants qui ne vous aideront pas, vous pouvez utiliser WP_Query::get_search_stopwords() - ou mieux: Un rappel sur le filtre. Actuellement, les mots vides sont:

about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www

Un exemple de rappel de filtre:

add_action( 'wp_search_stopwords', 'wpse134392SearchStopwords' );
function wpse134392SearchStopwords( $stopwords )
{
    return $stopwords + array(
        'my',
        'your',
        'easy',
    );

}

Astuce: Il semble que quelque chose (un plugin probablement) intercepte déjà votre rappel car il contient des mots qui ne devraient pas être recherchés.

3
kaiser

Je recommanderais de changer votre requête avec $ args étant quelque chose comme ça

    $args = array(
        'post_status' => array('pending', 'draft', 'future' ), 
        'post_type' => array( 'post', 'page', 'movie', 'book' ),
        'orderby' => 'date', 
        'order' => 'DESC',
        's' => 'keyword'
    );
    $search_query = new WP_Query($args);

Il y a aussi une description plus détaillée ici . La seule chose que je n'arrive pas à trouver est de rechercher plusieurs mots clés. Peut-être que si vous faites quelque chose comme ça ça pourrait marcher

's' => 'keyword1+keyword2+keyword3'
0
Kyle