Использование meta query ('meta_query') вместе с поисковым запросом ('s')

8 янв. 2013 г., 04:32:40
Просмотры: 106K
Голосов: 40

Пытаюсь создать поиск, который ищет не только по стандартным полям (заголовок, содержимое и т.д.), но также и по определенному произвольному полю.

Мой текущий запрос:

$args = array(
  'post_type' => 'post',
  's' => $query,
  'meta_query' => array(
     array(
       'key' => 'speel',
       'value' => $query,
       'compare' => 'LIKE'
     )
   )
);

$search = new WP_Query( $args )
...

Этот запрос возвращает записи, которые соответствуют И поисковому запросу, И meta запросу, но я также хотел бы, чтобы он возвращал записи, которые соответствуют любому из них.

Есть идеи?

1
Комментарии

То, что вы хотите сделать, невозможно выполнить с помощью только одного поискового запроса. Вам нужно будет выполнить оба запроса отдельно, а затем объединить их. Это описано в другом ответе. Он должен помочь вам разобраться, как это сделать. http://wordpress.stackexchange.com/questions/55519/can-i-merge-2-new-wp-queryvariable-s

Nick Perkins Nick Perkins
8 янв. 2013 г. 06:31:31
Все ответы на вопрос 14
6
31

Я потратил часы на поиск решения этой проблемы. Слияние массивов - не выход, особенно когда запросы сложные и вам нужно иметь возможность добавлять к мета-запросам в будущем. Решение, которое поразительно просто, заключается в изменении параметра 's' на такой, который позволяет искать как по заголовкам, так и по мета-полям.

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;

            // Выполняем только один раз:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Модифицируем WHERE условие
            $sql['where'] = sprintf(
                " AND ( %s OR %s ) ",
                $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
                mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
            );

            return $sql;
        });
    }
});

Использование:

$meta_query = array();
$args = array();
$search_string = "test";

$meta_query[] = array(
    'key' => 'staff_name',
    'value' => $search_string,
    'compare' => 'LIKE'
);
$meta_query[] = array(
    'key' => 'staff_email',
    'value' => $search_string,
    'compare' => 'LIKE'
);

// Если мета-запросов больше одного, объединяем их через OR
if(count($meta_query) > 1) {
    $meta_query['relation'] = 'OR';
}

// Формируем запрос
$args['post_type'] = "staff";
$args['_meta_or_title'] = $search_string; // больше не используем 's'
$args['meta_query'] = $meta_query;

$the_query = new WP_Query($args);
17 нояб. 2015 г. 13:35:31
Комментарии

это правильный путь,

Zorox Zorox
12 авг. 2016 г. 20:20:49

Фантастика, это отлично сработало для меня. Отличное решение! Спасибо!

Fabiano Fabiano
23 сент. 2017 г. 18:56:52

Это запрос, а не поиск. Если у вас есть плагины, которые работают на поиск, это не сработает. Я ошибаюсь?

marek.m marek.m
30 окт. 2017 г. 11:57:58

@marek.m вам потребуется настроить плагин (возможно, используя фильтр, если он доступен), чтобы добавить meta query.

FooBar FooBar
21 янв. 2020 г. 22:09:55

Не работает, если я добавляю параметр tax_query вместе с

Subhojit Mukherjee Subhojit Mukherjee
23 февр. 2022 г. 17:10:55

@SubhojitMukherjee Вы нашли решение, когда добавляете tax_query? У меня точно такая же проблема, как и у вас :)

mhsc90 mhsc90
18 дек. 2023 г. 11:24:45
Показать остальные 1 комментариев
1
11

Много кода можно сократить, используя модифицированную версию этого ответа.

$q1 = new WP_Query( array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    's' => $query
));

$q2 = new WP_Query( array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    'meta_query' => array(
        array(
           'key' => 'speel',
           'value' => $query,
           'compare' => 'LIKE'
        )
     )
));

$result = new WP_Query();
$result->posts = array_unique( array_merge( $q1->posts, $q2->posts ), SORT_REGULAR );
$result->post_count = count( $result->posts );
4 мар. 2014 г. 15:26:30
Комментарии

Это отлично сработало для меня (особенно потому, что мне нужно было использовать WP_Query вместо get_posts). Мне пришлось изменить строку post_count на: $result->post_count = count( $result->posts );, иначе я получал только 1 результат.

GreatBlakes GreatBlakes
27 мая 2015 г. 16:21:43
0

Я немного оптимизировал ответ от @Stabir Kira

function wp78649_extend_search( $query ) {
    $search_term = filter_input( INPUT_GET, 's', FILTER_SANITIZE_NUMBER_INT) ?: 0;
    if (
        $query->is_search
        && !is_admin()
        && $query->is_main_query()
        && //ваше дополнительное условие
    ) {
        $query->set('meta_query', [
            [
                'key' => 'meta_key',
                'value' => $search_term,
                'compare' => '='
            ]
        ]);

        add_filter( 'get_meta_sql', function( $sql )
        {
            global $wpdb;

            static $nr = 0;
            if( 0 != $nr++ ) return $sql;

            $sql['where'] = mb_eregi_replace( '^ AND', ' OR', $sql['where']);

            return $sql;
        });
    }
    return $query;
}
add_action( 'pre_get_posts', 'wp78649_extend_search');

Теперь вы можете осуществлять поиск по (заголовку, содержимому, excerpt) или (мета полю) или (обоим вариантам).

12 окт. 2016 г. 21:23:55
3

У меня была такая же проблема, для моего нового сайта я просто добавил новое мета-поле "title":

functions.php

add_action('save_post', 'title_to_meta');

function title_to_meta($post_id)
{
    update_post_meta($post_id, 'title', get_the_title($post_id)); 
}

А затем... просто добавил что-то вроде этого:

$sub = array('relation' => 'OR');

$sub[] = array(
    'key'     => 'tags',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$sub[] = array(
    'key'     => 'description',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$sub[] = array(
    'key'     => 'title',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$params['meta_query'] = $sub;

Что вы думаете об этом решении?

22 авг. 2016 г. 19:37:01
Комментарии

Это на самом деле неплохо, но требует либо повторного сохранения всех существующих записей, либо начала использования до того, как вы начнёте добавлять контент.

Berend Berend
6 дек. 2016 г. 13:55:24

@Berend, вы могли бы написать функцию, которая получает все записи, проходит по ним в цикле и обновляет post_meta для каждой. Включите её в пользовательский шаблон или функцию, запустите один раз, а затем удалите.

Slam Slam
23 мая 2018 г. 09:13:54

Лучший ответ: никаких ручных SQL-преобразований, никаких лишних видимых данных... Огромное спасибо!

jeanmatthieud jeanmatthieud
19 нояб. 2020 г. 12:22:17
2

Как предложил Ник Перкинс, мне пришлось объединить два запроса следующим образом:

$q1 = get_posts(array(
        'fields' => 'ids', // Получаем только ID постов
        'post_type' => 'post', // Тип записи - пост
        's' => $query // Поиск по строке запроса
));

$q2 = get_posts(array(
        'fields' => 'ids', // Получаем только ID постов
        'post_type' => 'post', // Тип записи - пост
        'meta_query' => array( // Запрос по метаполям
            array(
               'key' => 'speel', // Ключ метаполя
               'value' => $query, // Значение для поиска
               'compare' => 'LIKE' // Оператор сравнения
            )
         )
));

// Объединяем массивы ID и удаляем дубликаты
$unique = array_unique( array_merge( $q1, $q2 ) );

// Получаем полные данные постов по списку ID
$posts = get_posts(array(
    'post_type' => 'posts', // Тип записи
    'post__in' => $unique, // Фильтр по массиву ID
    'post_status' => 'publish', // Только опубликованные
    'posts_per_page' => -1 // Все подходящие посты
));

if( $posts ) : foreach( $posts as $post ) :
     setup_postdata($post);

     // теперь можно использовать стандартные функции цикла, например the_title() и другие

endforeach; endif;
9 янв. 2013 г. 00:37:46
Комментарии

Это до сих пор невозможно без слияния в 2016? Я редактирую поисковый запрос через pre_get_posts, так что это действительно не вариант...

trainoasis trainoasis
9 февр. 2016 г. 10:24:41

@trainoasis Я так не думаю. Я пытался сделать это последние 2 часа, и поиск в Google привел меня сюда.

Umair Khan Jadoon Umair Khan Jadoon
5 нояб. 2016 г. 12:40:35
0

Это своего рода хак, но он работает. Вам нужно добавить фильтр posts_clauses. Эта функция-фильтр проверяет, есть ли любое из слов запроса в пользовательском поле "speel", оставляя остальную часть запроса без изменений.

function custom_search_where($pieces) {

    // фильтр для вашего запроса
    if (is_search() && !is_admin()) {

        global $wpdb;

        $keywords = explode(' ', get_query_var('s'));
        $query = "";
        foreach ($keywords as $word) {

            // пропускаем возможные наречия и числа
            if (is_numeric($word) || strlen($word) <= 2) 
                continue;

            $query .= "((mypm1.meta_key = 'speel')";
            $query .= " AND (mypm1.meta_value  LIKE '%{$word}%')) OR ";
        }

        if (!empty($query)) {
            // добавляем к условию WHERE
            $pieces['where'] = str_replace("(((wp_posts.post_title LIKE '%", "( {$query} ((wp_posts.post_title LIKE '%", $pieces['where']);

            $pieces['join'] = $pieces['join'] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)";
        }
    }
    return ($pieces);
}
add_filter('posts_clauses', 'custom_search_where', 20, 1);
8 янв. 2013 г. 11:23:51
0

Вот еще один способ: изменить запрос с помощью фильтра 'posts_where_request'. Все останется по умолчанию, за исключением замены ('s' И 'meta_query') на ('s' ИЛИ 'meta_query').

AND ( ((posts.post_title LIKE 'Lily') OR (posts.post_excerpt LIKE 'Lily') OR (posts.post_content LIKE 'Lily')) )
AND ( ( postmeta.meta_key = 'author' AND postmeta.meta_value LIKE 'Lily' ) )

=>

AND ( 
    ( ( postmeta.meta_key = 'author' AND postmeta.meta_value LIKE 'Lily' ) )
    OR
    ((posts.post_title LIKE 'Lily') OR (posts.post_excerpt LIKE 'Lily') OR (posts.post_content LIKE 'Lily'))
)

Вот код:

function edit_request_wp_query( $where ) {
    global $wpdb;
    if ( strpos($where, $wpdb->postmeta.'.meta_key') && strpos($where, $wpdb->posts.'.post_title') ) {
        $string = $where;
        $index_meta = index_argument_in_request($string, $wpdb->postmeta.'.meta_key', $wpdb->postmeta.'.meta_value');
        $meta_query = substr($string, $index_meta['start'], $index_meta['end']-$index_meta['start']);
        $string = str_replace( $meta_query, '', $string );

        $meta_query = ltrim($meta_query, 'AND').' OR '; 
        $index_s = index_argument_in_request($string, $wpdb->posts.'.post_title');
        $insert_to = strpos($string, '(', $index_s['start'])+1;
        $string = substr_replace($string, $meta_query, $insert_to, 0);

        $where = $string;
    }
    return $where;
}
add_filter('posts_where_request', 'edit_request_wp_query');

function index_argument_in_request($string, $key_start, $key_end = '') {
    if (!$key_end) $key_end = $key_start;
    $index_key_start = strpos($string, $key_start);
    $string_before = substr($string, 0, $index_key_start);
    $index_start = strrpos($string_before, 'AND');

    $last_index_key = strrpos($string, $key_end);
    $index_end = strpos($string, 'AND', $last_index_key);

    return ['start' => $index_start, 'end' => $index_end];
}
19 февр. 2020 г. 12:33:57
0

Я не смог найти готового решения для поиска по нескольким ключевым словам, которые могут встречаться в заголовке записи, описании И/ИЛИ одном или нескольких мета-полях, поэтому создал собственное расширение функции поиска.

Всё, что вам нужно - добавить следующий код в файл function.php, и когда вы используете аргумент 's' в стандартной функции WP_Query() и хотите, чтобы поиск выполнялся также в одном или нескольких мета-полях, просто добавьте аргумент 's_meta_keys', который представляет собой массив ключей мета-полей, в которых нужно искать:

/************************************************************************\
|**                                                                    **|
|**  Позволяет функции поиска WP_Query() искать по нескольким ключевым **|
|**  словам в мета-полях в дополнение к post_title и post_content      **|
|**                                                                    **|
|**  By rAthus @ Arkanite                                              **|
|**  Created: 2020-08-18                                               **|
|**  Updated: 2020-08-19                                               **|
|**                                                                    **|
|**  Просто используйте стандартный аргумент 's' и добавьте аргумент   **|
|**  's_meta_keys' содержащий массив ключей мета-полей для поиска :)   **|
|**                                                                    **|
|**  Пример :                                                          **|
|**                                                                    **|
|**  $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'); // добавляем специальную функцию поиска к каждому запросу get_posts (включая 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']) { // если используется поиск с аргументом 's' и добавлен аргумент 's_meta_keys'
        global $wpdb;
        $search = $query->query_vars['s']; // получаем строку поиска
        $ids = array(); // инициализируем массив ID записей, соответствующих каждому ключевому слову
        foreach (explode(' ',$search) as $term) { // разбиваем ключевые слова и ищем совпадения для каждого
            $term = trim($term); // удаляем лишние пробелы
            if (!empty($term)) { // проверяем, что ключевое слово не пустое
                $query_posts = $wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_status='publish' AND ((post_title LIKE '%%%s%%') OR (post_content LIKE '%%%s%%'))", $term, $term); // ищем в заголовке и содержании как в стандартной функции
                $ids_posts = [];
                $results = $wpdb->get_results($query_posts);
                if ($wpdb->last_error)
                    die($wpdb->last_error);
                foreach ($results as $result)
                    $ids_posts[] = $result->ID; // собираем ID соответствующих записей
                $query_meta = [];
                foreach($query->query_vars['s_meta_keys'] as $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; // собираем ID соответствующих записей
                $merged = array_merge($ids_posts,$ids_metas); // объединяем ID из результатов поиска в заголовках, содержании и мета-полях
                $unique = array_unique($merged); // удаляем дубликаты
                if (!$unique)
                    $unique = array(0); // если нет результатов, добавляем ID "0", иначе будут возвращены все записи
                $ids[] = $unique; // добавляем массив ID в основной массив
            }
        }
        if (count($ids)>1)
            $intersected = call_user_func_array('array_intersect',$ids); // если несколько ключевых слов, оставляем только ID, которые есть во всех массивах результатов
        else
            $intersected = $ids[0]; // иначе оставляем единственный массив результатов
        $unique = array_unique($intersected); // удаляем дубликаты
        if (!$unique)
            $unique = array(0); // если нет результатов, добавляем ID "0", иначе будут возвращены все записи
        unset($query->query_vars['s']); // отключаем стандартный поиск
        $query->set('post__in',$unique); // добавляем фильтр по ID записей
    }
}

Пример использования:

$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);

Этот пример будет искать ключевые слова "ключевые слова для поиска" в заголовках записей, описаниях и мета-полях 'short_desc' и 'tags'.

Ключевые слова могут быть найдены в одном или нескольких полях, в любом порядке, функция вернет любую запись, которая содержит все ключевые слова в любом из указанных полей.

Вы можете, конечно, жестко задать список мета-полей для поиска в функции и убрать дополнительный аргумент, если хотите, чтобы ВСЕ поисковые запросы включали эти мета-поля :)

Надеюсь, это поможет тем, кто столкнулся с той же проблемой, что и я!

18 авг. 2020 г. 20:57:13
0

Я нашел чистое решение в ядре WordPress.

Разработчики WordPress уже сталкивались с этой проблемой при поиске в метаполях вложений _wp_attached_file и исправили её в этой функции:

_filter_query_attachment_filenames()

WordPress выполняет эту функцию

описание изображения

Взяв идею из этой функции, я написал следующий код для поиска в метаданных:

   /**
     * Включает поиск в таблицах postmeta и posts в одном запросе
     *
     * @see _filter_query_attachment_filenames()
     */
    add_filter( 'posts_clauses', function ( $clauses ) {

        global $wpdb;

        // Выполняется только один раз:
        static $counter = 0;
        if ( 0 != $counter ++ ) {
            return $clauses;
        }

        foreach (
            [
                'my_custom_meta_1',
                'my_custom_meta_2',
            ] as $index => $meta_key
        ) {

            // Добавляем LEFT JOIN таблицы postmeta, чтобы не перезаписывать существующие JOIN
            $clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS my_sql{$index} ON ( {$wpdb->posts}.ID = my_sql{$index}.post_id AND my_sql{$index}.meta_key = '{$meta_key}' )";

            $clauses['where'] = preg_replace(
                "/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
                "$0 OR ( my_sql{$index}.meta_value $1 $2 )",
                $clauses['where']
            );

        }
        
        return $clauses;
    }, 999 );
7 янв. 2022 г. 11:36:44
0

Все вышеперечисленные решения возвращают результаты только при наличии совпадения в мета-поле "speel". Если у вас есть результаты в других полях, но не в этом, вы ничего не получите. А это никому не нужно.

Необходим LEFT JOIN. Следующий код создаст его.

           $meta_query_args = array(
              'relation' => 'OR', // отношение между условиями - ИЛИ
              array(
                'key' => 'speel', // ключ мета-поля
                'value' => $search_term, // искомый термин
                'compare' => 'LIKE', // оператор сравнения - LIKE
              ),
              array(
                'key' => 'speel', // ключ мета-поля
                'compare' => 'NOT EXISTS', // проверка на отсутствие поля
              ),
            );
            $query->set('meta_query', $meta_query_args); // устанавливаем параметры мета-запроса
30 мая 2018 г. 10:39:38
4

Ответ от @satbir-kira работает отлично, но он выполняет поиск только по метаполям и заголовкам записей. Если вам нужно искать по метаполям, заголовкам и содержимому записи, вот модифицированная версия.

    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;

          // Выполняется только один раз:
          static $nr = 0;
          if( 0 != $nr++ ) return $sql;

          // Модифицированное условие WHERE
          $sql['where'] = sprintf(
              " AND ( (%s OR %s) OR %s ) ",
              $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
              $wpdb->prepare( "{$wpdb->posts}.post_content like '%%%s%%'", $title),
              mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
          );

          return $sql;
        });
      }
    });

Пример использования:

$args['_meta_or_title'] = $get['search']; // больше не используем 's'

$args['meta_query'] = array(
  'relation' => 'OR',
  array(
    'key' => '_ltc_org_name',
    'value' => $get['search'],
    'compare' => 'LIKE'
  ),
  array(
    'key' => '_ltc_org_school',
    'value' => $get['search'],
    'compare' => 'LIKE'
  ),
  array(
    'key' => '_ltc_district_address',
    'value' => $get['search'],
    'compare' => 'LIKE'
  )
);

Замените $get['search'] на ваше значение для поиска

16 янв. 2019 г. 18:02:38
Комментарии

Это не работает при добавлении аргументов tax_query

Subhojit Mukherjee Subhojit Mukherjee
23 февр. 2022 г. 17:09:34

@SubhojitMukherjee Вы нашли решение, когда добавляете tax_query? У меня точно такая же проблема, как у вас :)

mhsc90 mhsc90
18 дек. 2023 г. 11:25:10

Окей, нашел решение! Спасибо Sully (https://wordpress.stackexchange.com/questions/403040/query-to-get-result-by-title-or-meta-along-with-tax-query-parameter) Вот код, который нужно обновить, чтобы он работал с tax_query:

mhsc90 mhsc90
18 дек. 2023 г. 11:35:33

add_filter( 'get_meta_sql', function( $sql, $queries, $type ) use ( $title ){ global $wpdb; static $nr = 0; if( 'post' !== $type || 0 != $nr++ ) return $sql; $sql['where'] = sprintf( " AND ( %s OR %s ) ", $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title), mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) ) ); return $sql; }, 10, 3); }

mhsc90 mhsc90
18 дек. 2023 г. 11:37:06
0

Для меня отлично работает следующий код:

            // Получаем поисковый запрос из параметра id
            $search_word = $_GET['id'];
            // Декодируем и обрезаем пробелы у поискового запроса
            $data['words'] = trim(urldecode($search_word));

            // Первый запрос: поиск по заголовку и контенту
            $q1 = new WP_Query( array(
                'post_type' => array('notas', 'productos'),  // Типы записей: заметки и продукты
                'posts_per_page' => -1,  // Все записи без ограничения
                's' => $search_word  // Поисковый запрос
            ));

            // Второй запрос: поиск по произвольным полям
            $q2 = new WP_Query( array(
                'post_type' => array('notas', 'productos'),  // Типы записей: заметки и продукты
                'posts_per_page' => -1,  // Все записи без ограничения
                'meta_query' => array(
                    'relation' => 'OR',  // Логическое ИЛИ между условиями
                    array(
                       'key'   => 'subtitulo',  // Поле "подзаголовок"
                        'value' => $search_word,  // Значение для поиска
                        'compare' => 'LIKE'  // Поиск по частичному совпадению
                    ),
                    array(
                        'key'   => 'thumbnail_bajada',  // Поле "описание миниатюры"
                        'value' => $search_word,  // Значение для поиска
                        'compare' => 'LIKE'  // Поиск по частичному совпадению
                    )
                 )
            ));

            // Объединяем результаты двух запросов
            $result = new WP_Query();
            // Убираем дубликаты и сохраняем уникальные записи
            $result->posts = array_unique( array_merge( $q1->posts, $q2->posts ), SORT_REGULAR );
            // Обновляем счетчик записей
            $result->post_count = count( $result->posts );
19 мар. 2020 г. 15:21:57
0

Это отличное решение, но нужно исправить один момент. При вызове 'post__in' необходимо передать массив ID, а $unique является массивом постов.

Пример:

$q1 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        's' => $query
));

$q2 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        'meta_query' => array(
            array(
               'key' => 'speel',
               'value' => $query,
               'compare' => 'LIKE'
            )
         )
));

$unique = array_unique( array_merge( $q1->posts, $q2->posts ) );

$array = array(); // здесь инициализируем массив

foreach($posts as $post)
{
    $array[] = $post->ID; // заполняем массив ID постов
}


$posts = get_posts(array(
    'post_type' => 'posts',
    'post__in' => $array,
    'post_status' => 'publish',
    'posts_per_page' => -1
));
11 дек. 2018 г. 20:10:29
0

Я обнаружил, что ответ Асада Манзура сработал для меня. Если кому-то это нужно, моя версия требовала реализации параметра paged:

$search_query = trim(esc_html( get_search_query() ));
$posts_per_page = $wp_query->query_vars['posts_per_page'];
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$q1 = new WP_Query(array(
    's' => $search_query,
    'post_type' => array('page', 'post'),
    'posts_per_page' => -1,
    'fields' => 'ids'
));
$q2 = new WP_Query(array(
    'fields' => 'ids',
    'post_type' => array('page', 'post'),
    'posts_per_page' => -1,
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'custom_body',
            'value' => $search_query,
            'compare' => 'LIKE'
        )
    )
));

$unique = array_unique(array_merge($q1->posts, $q2->posts));

// Если записи не найдены, убедимся, что $query не выбирает все записи.
if (!$unique) {
    $unique = array(-1);
}

$query = new WP_Query(array(
    'post_type' => array('page', 'post'),
    'post__in' => $unique,
    'paged' => $paged,
    'post_status' => 'publish',
    'posts_per_page' => $posts_per_page
)); 
1 окт. 2024 г. 13:40:47