搜索自定义帖子类型和自定义字段需要5分钟

时间:2012-03-10 作者:Charles Kłyciński

我遇到了奇怪的问题,我被卡住了。我有大约15个自定义字段的自定义帖子类型。

我使用wp_insert_post ,update_post_metawp_set_object_terms.

一切顺利。所有vCard都工作正常。我有3500个vCard,现在当我尝试搜索一些vCard时-搜索只需冻结10分钟,然后我就会超时。同样的事情是在管理面板,如果我试图在自定义帖子类型菜单搜索需要10分钟,然后死亡。。。所以我有一个问题,wordpress是否能够处理那么多自定义帖子类型的帖子?还是我在编码上出错了?如果你需要任何类型的代码来显示,请告诉我,我会粘贴在这里,因为现在我甚至不知道从哪里开始搜索。

最佳RegardsCharles

以下是代码:

首先,我从搜索中删除其他页面-我只需要自定义帖子类型

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

}
return $query;
我在网上找到了这部分代码,并根据自己的需要对其进行了调整:我获取了所有自定义字段(现在在代码中,由于测试,我只获得了1个字段-通常是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;
现在,这3个功能与过滤器

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 );
最后,我应用过滤器:

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

1 个回复
最合适的回答,由SO网友:kaiser 整理而成

你有preg_match_all(), 各种各样的JOINsanonymous/lambda functions、 简而言之:所有使调试变得困难和性能明智的事情都是不可能的。

简而言之:您应该使用meta_query 相反看看

密码meta_query »Multiple Custom Field Handling:

结束