我正在使用合著者插件:
https://wordpress.org/plugins/co-authors-plus/
我编写了一些SQL,以便在搜索帖子时从显示名称与搜索查询匹配的作者那里获取帖子。它实际上是在一个非常小的测试博客上工作,但它在一个生产博客上花费了很长时间(实际上很长,以至于我们的主机抛出502)。
这项工作只有一部分我不了解,那就是编写SQL查询来实现我想要的:
“author”是来自coauthors插件的自定义分类法(请参见上面的链接)每个分配到一个职位的合著者都是该分类法中的一个术语将搜索词与合著者的词描述进行匹配获取包含匹配条件的帖子关键是我需要将结果合并到正常的搜索结果中。这不是小部件、模板标记或短代码,需要作为搜索页面的主查询。我通过posts\\u请求过滤器实现了这一点(我没有足够的代表粘贴到该过滤器的链接)。
这是我的SQL。我能做些什么来提高性能吗?
http://pastebin.com/TZA7tqCv
<?php
/**
* Create an SQL statement for searching posts by coauthor name.
*
* @todo I\'m having trouble getting $wpdb -> prepare to work, although I don\'t think it\'s necessary since I am sanitizing the data very strictly.
* @todo I really have no idea if this is actually how you do a JOIN.
*
* @param string $s The search term.
* @param string $matching_users A comma-sep list of user ID\'s.
* @param int $limit The maximum number of results.
* @param int $offset The number of results to skip, as per pagination.
* @return string SQL for searching posts by coauthor name.
*/
private function sql( $s, $matching_users, $limit, $offset ) {
// Sanitize the search term and matching users, although replacing illegal chars with a wildcard.
$s = $this -> sanitize( $s, \'_\' );
$matching_users = $this -> sanitize( $matching_users, \'_\' );
// And then hit them with esc_sql because I\'m paranoid.
$s = esc_sql( $s );
$matching_users = esc_sql( $matching_users );
// Sanitize the LIMIT making sure it\'s an int, defaulting to 10.
$limit = absint( $limit );
if( empty ( $limit ) ) { $limit = 10; }
// Sanitize the the OFFSET, making sure it\'s an int, defaulting to 0.
$offset = absint( $offset );
if( empty ( $offset ) ) { $offset = 0; }
// We\'re gonna need this to build our table names.
global $wpdb;
// Shorten the name of the psots table for easier reading.
$p = $wpdb -> posts;
$tt = $wpdb -> term_taxonomy;
$tr = $wpdb -> term_relationships;
$t = $wpdb -> terms;
$sql = <<<SQL
/* We\'re selecting posts in order to fulfill the search query. */
SELECT
/* This will prevent multiple copies of the same post, though I don\'t totally understand why we\'d otherwise be getting them. */
DISTINCT
/* Populates a value so you can determine how many rows you would have gotten without the LIMIT clause. */
SQL_CALC_FOUND_ROWS
/* We want every column from the posts table. */
$p.*
/* I want results from the posts table, but I have to invoke these other tables for when I am sort of using them later in WHERE clause. */
FROM $p, $tr, $t, $tt
WHERE (
/* See if the search term matches the post title. */
(
$p.post_title LIKE \'%$s%\'
/* See if the search term matches the post content. */
) OR (
$p.post_content LIKE \'%$s%\'
/* See if the post author is in the array of author ID\'s that I have from my script. */
) OR (
$p.post_author IN ( $matching_users )
/* This is the part where I\'m hazy. */
) OR (
/* Search the TT table for terms from the \'author\' taxonomy ... */
(
$tt.taxonomy = \'author\'
/* ... and whose term description matches the search term ... */
) AND (
$tt.description LIKE \'%$s%\'
/* ... and whose ID matches the ID in the terms table where ... */
) AND (
$tt.term_id = $t.term_id
/* ... the term_id matches the TR table where ... */
) AND (
$tr.term_taxonomy_id = $t.term_id
/* ... the object_id in the TR table matches the post ID ... */
) AND (
$tr.object_id = $p.ID
)
/* End the part where I\'m hazy. */
)
/* Limit results to the normal post types. */
) AND $p.post_type IN (
\'post\', \'page\'
/* Limit results to the normal post status. */
) AND (
$p.post_status = \'publish\'
/* WP Core does this and I have no idea why. */
) AND (
1 = 1
)
/* Get results in reverse cron, like usual. */
ORDER BY $p.post_date DESC
/* Of course we only want our normal posts per page. */
LIMIT $limit
/* And we need to account for pagination. */
OFFSET $offset
SQL;
return $sql;
}