Поиск WordPress с использованием WP_Query для охвата нескольких типов записей и их пользовательских полей.

Вопрос или проблема

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

В своих аргументах к WP_Query я указываю все типы записей. Но не уверен, как точно указать все пользовательские поля с OR, потому что я по сути ищу контент в каждом типе записи.

Код ниже не работает, дает 0 результатов для ключевого слова качественный, например. Но прямой поиск в MySQL по таблице wp_postmeta показывает, что есть 12 записей со словом “качественный” в них. Я хочу, чтобы мой запрос вывел все эти записи.

Как правильным образом включить их в WP_Query?

  1. Без фильтров / действий
  2. Без плагинов. Я хотел бы сделать это непосредственно в WP_Query и это должно поддерживать два языка. Мне нужно будет запрашивать только один язык в каждом поисковом движке (PolyLang).

Код:

$SEARCH = $_GET['s']; 

$args = array(
's' => $SEARCH
,'orderby' => 'relevance'
,'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts')
,'post_status' => 'publish'
,'posts_per_page' => 15

,'meta_query' => array(
'relation' => 'OR'

// ПОИСК ПО ПОЛЯМ ПОЛЬЗОВАТЕЛЬСКИХ ТИПОВ ЗАПИСЕЙ "reports"
,array(
    'key'   => 'report_content',
    'value' => "$SEARCH",
    'compare' => 'LIKE'
    )
,array(
    'key'   => 'report_details',
    'value' => "$SEARCH",
    'compare' => 'LIKE'
    )

 // ПОИСК ПО ПОЛЯМ ПОЛЬЗОВАТЕЛЬСКИХ ТИПОВ ЗАПИСЕЙ "events" 
,array(
    'key'   => 'event_brief',
    'value' => "$SEARCH",
    'compare' => 'LIKE'
        )
    
)

);

Что я пытаюсь сделать выше – это искать слово в переменной $SEARCH внутри этих пользовательских полей.

РЕДАКТИРОВАТЬ: Просто добавлю, что индивидуальные отдельные запросы работают. Но вместо того, чтобы вызывать WP_Query три раза, я хотел бы объединить их в один. Я изучил множество постов на Stack Overflow на тему “Я хочу объединить meta_query и tax_query”, но кажется ни один из них не касается объединения разных типов записей в условии OR, как это нужно для поиска на сайте. Три из них, которые работают индивидуально:

// ОСНОВНОЙ ЗАПРОС
$args = array(
      's' => $SEARCH
     ,'orderby' => 'relevance'
     ,'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts')
     ,'post_status' => 'publish'
     ,'posts_per_page' => 15
);


// ПОИСК ПО REPORTS
$args2 = array(
          'post_type'  => 'reports'
          ,'meta_query' => array(
              'relation' => 'OR',
              array(
                      'key' => 'report_content',
                      'value' => "$SEARCH",
                      'compare' => 'LIKE',
              ),
              array(
                      'key' => 'report_details',
                      'value' => "$SEARCH",
                      'compare' => 'LIKE',
              ),
          ),
      );

// ПОИСК ПО EVENTS
$args3 = array(
            'post_type'  => 'events'
            ,'meta_query' => array(
                'relation' => 'OR',
                array(
                        'key' => 'event_brief',
                        'value' => "$SEARCH",
                        'compare' => 'LIKE',
                ),
                array(
                        'key' => 'event_instruction',
                        'value' => "$SEARCH",
                        'compare' => 'LIKE',
                ),
            ),
          );

Но объединение их этим топорным способом:

$wp_query       = new WP_Query( $args);
$wp_query2      = new WP_Query( $args2);
$wp_query3      = new WP_Query( $args3);

$posts          = $wp_query->posts;
$posts2         = $wp_query2->posts;
$posts3         = $wp_query3->posts;

$posts          = array_unique( array_merge(
                    $posts
                    ,$posts2
                    ,$posts3
                    ) );
                    
                    

Не работает. Выдает печальную ошибку:

Uncaught Error: Object of class WP_Post could not be converted to string

В любом случае, я хотел бы объединить эти meta_query с условием OR между ними. Я нашел несколько примеров meta_query, но они предполагают AND… как если бы все эти meta_query должны были совпадать. Это не то, что мне нужно. Большое спасибо.

Нашел способ объединить записи WP_Query:

$query1 = new WP_Query($args);
$query2 = new WP_Query($args2);
$query3 = new WP_Query($args3);

$combined = new WP_Query();

$combined->posts =   array_merge(
                           $query1->posts
                          ,$query2->posts
                          ,$query3->posts
                        );

Все еще не так элегантно, как выполнение одного WP_Query с всеми этими условиями в аргументах как OR… то есть, запрос должен соответствовать ЛЮБОМУ из этих вариантов в meta_query.

Также, каким-то образом обертка array_unique() к array_merge() выдает ошибку.

Ответ или решение

Создание более интеллектуального поиска в WordPress, включающего пользовательские поля, возможно с использованием WP_Query, но требует тщательной настройки параметров запроса. Рассмотрим как это сделать с учетом специфики задачи, избегая использование фильтров, действий и плагинов, а также поддерживая мультиязычность через PolyLang.

Основные шаги для расширенного поиска в WP_Query

  1. Правильная настройка аргументов WP_Query: Для успешного поиска через пользовательские поля необходимо корректно настроить meta_query. Это позволит вам искать ключевые слова внутри определенных пользовательских полей для всех указанных типов записей.

  2. Интеграция поиска по нескольким пользовательским полям: Важным аспектом является использование оператора OR внутри meta_query. Это позволит объединить критерии поиска по разным пользовательским полям, не требуя совпадения всех критериев одновременно.

Пример кода

$SEARCH = $_GET['s'];

$args = array(
    's' => $SEARCH,
    'orderby' => 'relevance',
    'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts'),
    'post_status' => 'publish',
    'posts_per_page' => 15,
    'meta_query' => array(
        'relation' => 'OR',
        // Найти совпадения в пользовательских полях для всех типов записей
        array(
            'relation' => 'OR',
            array(
                'key'   => 'report_content',
                'value' => $SEARCH,
                'compare' => 'LIKE',
            ),
            array(
                'key'   => 'report_details',
                'value' => $SEARCH,
                'compare' => 'LIKE',
            ),
            array(
                'key'   => 'event_brief',
                'value' => $SEARCH,
                'compare' => 'LIKE',
            ),
            array(
                'key'   => 'event_instruction',
                'value' => $SEARCH,
                'compare' => 'LIKE',
            ),
        ),
    ),
);

$search_query = new WP_Query($args);

Решение проблем и оптимизация

  1. Объединение результатов: Если хотите объединить результаты из нескольких WP_Query, используйте одинаковый массив posts для сборки конечного массива постов. Некорректное использование array_merge и array_unique может привести к ошибкам преобразования объектов.

  2. Улучшение производительности: Проверьте ограничение на количество записей в posts_per_page и убедитесь в его разумности. Это гарантирует скорость загрузки и стабильность работы на высоких нагрузках.

  3. Использование PolyLang: Убедитесь, что используете соответствующие языковые таксономии, чтобы ограничивать поиск записями на выбранном языке.

Заключение

Этот подход к WP_Query позволяет добиться более гибкого и комплексного поиска в WordPress, полностью базирующегося на возможностях встроенного API, без использования сторонних решений. Используйте мощные возможности meta_query и осмысленные настройки параметров для достижения требуемых результатов поиска.

Оцените материал
Добавить комментарий

Капча загружается...