I got strange problem and I’m stuck. I have custom post type with around 15 custom fields.
I moved data from old db (not WP) by using wp_insert_post
,update_post_meta
and wp_set_object_terms
.
All went good. All vcards works fine. I got 3500 vcards and now when I try to search some vcards – search just freeze for 10 minutes then i get timeout. Same thing is in admin panel if I try to search in custom post type menu search takes 10 minutes and dies…
So I have a question is wordpress capable to handle that amount of custom post type posts ? or i made some mistake in coding ? If You need any kind of code to show please tell me i will paste it here since now i dont even know where to start search.
Best Regards
Charles
Here is a code:
First of all i drop other pages from search – i need only my custom post type
function search_types($query) {
if ( $query->is_search )
{
$query->set('post_type', 'vcard');
}
return $query;
This part of code i found on net and just adjusted it to my needs:
I grab all custom fields ( now in code i got only 1 field becouse of testing – normally is about 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;
Now those 3 function with filter
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 );
At the end, I applyfilters :
add_filter('posts_join', 'custom_search_join');
add_filter('posts_where', 'custom_search_where');
add_filter('posts_groupby', 'custom_search_groupby');
You got a
preg_match_all()
, variousJOIN
s,anonymous/lambda function
s. In short: Everything that makes debugging hard and is performance wise a no-go.In short: You should use a
meta_query
instead. Take a look at