WP查询参数-标题或元值

时间:2015-02-18 作者:Bryan

如何按meta\\u值或标题进行查询?

如果我设置meta\\u值,

$args[\'meta_query\'] = array(
   \'relation\' => \'OR\',
    array(
        \'key\' => \'model_name\',
        \'value\' => $thesearch,
        \'compare\' => \'like\'
    )
);
它们会自动添加为和。

此搜索将是:

 WHERE title = \'Search\' AND (model_name = \'Search\' OR ...)
我需要

WHERE title = \'Search\' OR (model_name = \'Search\' OR ...)

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

请注意relation 中的一部分meta_query 参数,仅用于定义子元查询之间的关系。

您可以尝试以下设置:

$args = [ 
    \'_meta_or_title\' => $thesearch,   // Our new custom argument!
    \'meta_query\'    => [
        [
            \'key\'     => \'model_name\',
            \'value\'   => $thesearch,
            \'compare\' => \'like\'
        ]
    ],
];
我们引入了一个自定义参数_meta_or_title 激活元或标题查询。

以下插件支持此操作:

<?php
/**
 *  Plugin Name:   Meta OR Title query in WP_Query
 *  Description:   Activated through the \'_meta_or_title\' argument of WP_Query 
 *  Plugin URI:    http://wordpress.stackexchange.com/a/178492/26350
 *  Plugin Author: Birgir Erlendsson (birgire)
 *  Version:       0.0.1
 */

add_action( \'pre_get_posts\', function( $q )
{
    if( $title = $q->get( \'_meta_or_title\' ) )
    {
        add_filter( \'get_meta_sql\', function( $sql ) use ( $title )
        {
            global $wpdb;

            // Only run once:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Modify WHERE part:
            $sql[\'where\'] = sprintf(
                " AND ( %s OR %s ) ",
                $wpdb->prepare( "{$wpdb->posts}.post_title = \'%s\'", $title ),
                mb_substr( $sql[\'where\'], 5, mb_strlen( $sql[\'where\'] ) )
            );
            return $sql;
        });
    }
});

SO网友:Jeff Oliva

我是WP的新手,我还没有对我提出的这种方法进行过太多测试。也许你可以帮我检查一下我是否正确。到目前为止,我找到的解决方案是实现相同的meta\\u查询逻辑,只是进行一些替换。

首先,用法:

$args = array(
    \'lang\' => \'pt\', //this function does not conflict (example: polylang)
    \'post_type\' => \'produtos\', 
    \'post_status\'   => \'publish\',
    \'posts_per_page\' => 10,
    \'paged\' =>  1,
    \'fields\' => \'ids\',
);
$args[\'meta_query] = [
    [\'relation\'] => \'OR\'; //any relation you desire
    [
        \'key\' => \'acf_field\', //any custom field (regular usage)
        \'value\' => $search, //any value (regular usage)
        \'compare\' => \'LIKE\', //any comparition (regular usage)
    ],
    [
        \'key\' => \'post_title\', //set the default post content of wordpress you desire (\'post_content\', \'post_title\' and \'post_excerpt\')
        \'value\' => $search, //any value
        \'compare\' => \'LIKE\', //tested with \'LIKE and \'=\', works great and I can\'t realize other needs.
    ],
    [
        \'key\' => \'post_exerpt\', // you can add how many times you need
        \'value\' => $search_2,
        \'compare\' => \'LIKE\', 
    ],
];
$the_query = new WP_Query( $args ); //jus query
wp_reset_postdata(); //clean your query
若要工作,请将此函数添加到主题函数中。php

function post_content_to_meta_queries($where, $wp_query){
    global $wpdb;

    //if there is no metaquery, bye!
    $meta_queries = $wp_query->get( \'meta_query\' );
    if( !$meta_queries || $meta_queries == \'\' ) return $where;

    //if only one relation
    $where = str_replace($wpdb->postmeta . ".meta_key = \'post_title\' AND " . $wpdb->postmeta . ".meta_value", $wpdb->posts . ".post_title", $where);
    $where = str_replace($wpdb->postmeta . ".meta_key = \'post_content\' AND " . $wpdb->postmeta . ".meta_value", $wpdb->posts . ".post_content", $where);
    $where = str_replace($wpdb->postmeta . ".meta_key = \'post_excerpt\' AND " . $wpdb->postmeta . ".meta_value", $wpdb->posts . ".post_excerpt", $where);

    ////for nested relations

    //count the numbers of meta queries for possible replacements
    $number_of_relations = count($meta_queries);

    //replace \'WHERE\' using the multidimensional postmeta naming logic used by wordpress core
    $i = 1;
    while($i<=$number_of_relations && $number_of_relations > 0){
        $where = str_replace("mt".$i.".meta_key = \'post_title\' AND mt".$i.".meta_value", $wpdb->posts . ".post_title", $where);
        $where = str_replace("mt".$i.".meta_key = \'post_content\' AND mt".$i.".meta_value", $wpdb->posts . ".post_content", $where);
        $where = str_replace("mt".$i.".meta_key = \'post_excerpt\' AND mt".$i.".meta_value", $wpdb->posts . ".post_excerpt", $where);
        $i++;
    }

    return $where;
}

add_filter(\'posts_where\',\'post_content_to_meta_queries\',10,2);
我很肯定这是可以改进的!希望有帮助!

SO网友:rAthus

我找不到一个解决方案来查找可以混合在帖子标题、描述和/或一个或多个元中的多个关键字,所以我自己添加了搜索功能。

您只需在函数中添加以下代码。php,并且每当您在WP\\u Query()中使用\'s\'参数并希望它也搜索一个或多个时,只需添加一个\'s\\u meta\\u keys\'参数,该参数是要搜索的meta(s)键的数组:

/************************************************************************\\
|**                                                                    **|
|**  Allow WP_Query() search function to look for multiple keywords    **|
|**  in metas in addition to post_title and post_content               **|
|**                                                                    **|
|**  By rAthus @ Arkanite                                              **|
|**  Created: 2020-08-18                                               **|
|**  Updated: 2020-08-19                                               **|
|**                                                                    **|
|**  Just use the usual \'s\' argument and add a \'s_meta_keys\' argument  **|
|**  containing an array of the meta(s) key you want to search in :)   **|
|**                                                                    **|
|**  Example :                                                         **|
|**                                                                    **|
|**  $args = array(                                                    **|
|**      \'numberposts\'  => -1,                                         **|
|**      \'post_type\' => \'post\',                                        **|
|**      \'s\' => $MY_SEARCH_STRING,                                     **|
|**      \'s_meta_keys\' => array(\'META_KEY_1\',\'META_KEY_2\');            **|
|**      \'orderby\' => \'date\',                                          **|
|**      \'order\'   => \'DESC\',                                          **|
|**  );                                                                **|
|**  $posts = new WP_Query($args);                                     **|
|**                                                                    **|
\\************************************************************************/
add_action(\'pre_get_posts\', \'my_search_query\'); // add the special search fonction on each get_posts query (this includes WP_Query())
function my_search_query($query) {
    if ($query->is_search() and $query->query_vars and $query->query_vars[\'s\'] and $query->query_vars[\'s_meta_keys\']) { // if we are searching using the \'s\' argument and added a \'s_meta_keys\' argument
        global $wpdb;
        $search = $query->query_vars[\'s\']; // get the search string
        $ids = array(); // initiate array of martching post ids per searched keyword
        foreach (explode(\' \',$search) as $term) { // explode keywords and look for matching results for each
            $term = trim($term); // remove unnecessary spaces
            if (!empty($term)) { // check the the keyword is not empty
                $query_posts = $wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_status=\'publish\' AND ((post_title LIKE \'%%%s%%\') OR (post_content LIKE \'%%%s%%\'))", $term, $term); // search in title and content like the normal function does
                $ids_posts = [];
                $results = $wpdb->get_results($query_posts);
                if ($wpdb->last_error)
                    die($wpdb->last_error);
                foreach ($results as $result)
                    $ids_posts[] = $result->ID; // gather matching post ids
                $query_meta = [];
                foreach($query->query_vars[\'s_meta_keys\'] as $meta_key) // now construct a search query the search in each desired meta key
                    $query_meta[] = $wpdb->prepare("meta_key=\'%s\' AND meta_value LIKE \'%%%s%%\'", $meta_key, $term);
                $query_metas = $wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE ((".implode(\') OR (\',$query_meta)."))");
                $ids_metas = [];
                $results = $wpdb->get_results($query_metas);
                if ($wpdb->last_error)
                    die($wpdb->last_error);
                foreach ($results as $result)
                    $ids_metas[] = $result->post_id; // gather matching post ids
                $merged = array_merge($ids_posts,$ids_metas); // merge the title, content and meta ids resulting from both queries
                $unique = array_unique($merged); // remove duplicates
                if (!$unique)
                    $unique = array(0); // if no result, add a "0" id otherwise all posts wil lbe returned
                $ids[] = $unique; // add array of matching ids into the main array
            }
        }
        if (count($ids)>1)
            $intersected = call_user_func_array(\'array_intersect\',$ids); // if several keywords keep only ids that are found in all keywords\' matching arrays
        else
            $intersected = $ids[0]; // otherwise keep the single matching ids array
        $unique = array_unique($intersected); // remove duplicates
        if (!$unique)
            $unique = array(0); // if no result, add a "0" id otherwise all posts wil lbe returned
        unset($query->query_vars[\'s\']); // unset normal search query
        $query->set(\'post__in\',$unique); // add a filter by post id instead
    }
}
示例使用:

$search= "kewords to search";

$args = array(
    \'numberposts\'   => -1,
    \'post_type\' => \'post\',
    \'s\' => $search,
    \'s_meta_keys\' => array(\'short_desc\',\'tags\');
    \'orderby\' => \'date\',
    \'order\'   => \'DESC\',
);

$posts = new WP_Query($args);
此示例将查找关键字;kewords to search“要搜索的关键字”;在帖子标题、描述和元键“short\\u desc”和“tags”中。

关键字可以在一个或多个文件中找到,按任何顺序,它将返回在任何指定字段中包含所有关键字的任何帖子。

如果希望所有搜索查询都包含这些元键,则可以强制搜索包含在功能中的元键列表,并删除额外的agrument:)

希望这将帮助任何人谁面临同样的问题,我做了!

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post