Usando meta query ('meta_query') con una consulta de búsqueda ('s')

8 ene 2013, 04:32:40
Vistas: 106K
Votos: 40

Estoy tratando de construir una búsqueda que no solo busque en los valores predeterminados (título, contenido, etc.) sino también en un campo personalizado específico.

Mi consulta actual:

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

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

Esto devuelve las entradas que coinciden tanto con la consulta de búsqueda Y la meta query, pero también me gustaría que devolviera entradas donde simplemente coincida con cualquiera de ellas.

¿Alguna idea?

1
Comentarios

Lo que deseas hacer no es posible utilizando solo una consulta de búsqueda. Necesitarías ejecutar ambas consultas por separado y luego combinarlas. Esto se ha descrito en esta otra respuesta. Debería ayudarte con cómo hacerlo. http://wordpress.stackexchange.com/questions/55519/can-i-merge-2-new-wp-queryvariable-s

Nick Perkins Nick Perkins
8 ene 2013 06:31:31
Todas las respuestas a la pregunta 14
6
31

He estado buscando durante horas una solución a este problema. La fusión de arrays no es el camino a seguir, especialmente cuando las consultas son complejas y necesitas poder añadir más consultas meta en el futuro. La solución, que es sencillamente hermosa, es cambiar 's' por uno que permita buscar tanto en títulos como en campos meta.

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;

            // Solo se ejecuta una vez:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // WHERE modificado
            $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;
        });
    }
});

Uso:

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

// Si hay más de una consulta meta, usar 'OR'
if(count($meta_query) > 1) {
    $meta_query['relation'] = 'OR';
}

// La Consulta
$args['post_type'] = "staff";
$args['_meta_or_title'] = $search_string; //ya no se usa 's'
$args['meta_query'] = $meta_query;

$the_query = new WP_Query($args);
17 nov 2015 13:35:31
Comentarios

esta es la forma correcta,

Zorox Zorox
12 ago 2016 20:20:49

¡Fantástico, esto funcionó muy bien para mí! ¡Gran solución! ¡Gracias!

Fabiano Fabiano
23 sept 2017 18:56:52

Esta es una consulta, no una búsqueda. Si tienes plugins que funcionan en búsquedas, no funcionará. ¿Estoy equivocado?

marek.m marek.m
30 oct 2017 11:57:58

@marek.m necesitarías personalizar el plugin (quizás usando un filtro si está disponible) para agregar la consulta de metadatos.

FooBar FooBar
21 ene 2020 22:09:55

No funciona si agrego el parámetro tax_query junto con

Subhojit Mukherjee Subhojit Mukherjee
23 feb 2022 17:10:55

@SubhojitMukherjee ¿Encontraste una manera cuando agregas un tax_query? Tengo exactamente el mismo problema que tú :)

mhsc90 mhsc90
18 dic 2023 11:24:45
Mostrar los 1 comentarios restantes
1
11

Mucho código puede reducirse usando una versión modificada de esta respuesta.

$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 mar 2014 15:26:30
Comentarios

Esto funcionó genial para mí (especialmente porque necesitaba usar WP_Query en lugar de get_posts). Tuve que modificar tu línea post_count para que fuera: $result->post_count = count( $result->posts ); porque de lo contrario solo obtenía 1 resultado.

GreatBlakes GreatBlakes
27 may 2015 16:21:43
0

He optimizado un poco la respuesta de @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()
        && //tu condición adicional
    ) {
        $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');

Ahora puedes buscar por (título, contenido, extracto) o (campo meta) o (ambos).

12 oct 2016 21:23:55
3

Tuve el mismo problema, para mi nuevo sitio simplemente agregué un nuevo meta "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)); 
}

Y luego... simplemente agregué algo como esto:

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

¿Qué opinas sobre esta solución alternativa?

22 ago 2016 19:37:01
Comentarios

En realidad no está mal, pero requiere que vuelvas a guardar todas las entradas existentes o que comiences a usarlo antes de empezar a agregar contenido.

Berend Berend
6 dic 2016 13:55:24

@Berend probablemente podrías escribir una función que obtenga todas las entradas y las recorra actualizando el post_meta para cada una. Inclúyela en una plantilla o función personalizada, ejecútala una vez y luego descártala.

Slam Slam
23 may 2018 09:13:54

La mejor respuesta de todas: sin transformaciones SQL manuales, sin datos visibles adicionales... ¡Muchas gracias!

jeanmatthieud jeanmatthieud
19 nov 2020 12:22:17
2

Siguiendo la sugerencia de Nick Perkins, tuve que combinar dos consultas de la siguiente manera:

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

$posts = get_posts(array(
    'post_type' => 'posts',
    'post__in' => $unique,
    'post_status' => 'publish',
    'posts_per_page' => -1
));

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

     // ahora usa funciones estándar del loop como the_title() etc.     

endforeach; endif;
9 ene 2013 00:37:46
Comentarios

¿Sigue sin ser posible sin fusionar en 2016? Estoy editando la consulta de búsqueda a través de pre_get_posts, así que esto realmente no es una opción...

trainoasis trainoasis
9 feb 2016 10:24:41

@trainoasis No lo creo. Lo he estado intentando durante las últimas 2 horas y una búsqueda en Google me trajo aquí.

Umair Khan Jadoon Umair Khan Jadoon
5 nov 2016 12:40:35
0

Bueno, es un poco un truco pero funciona. Necesitas agregar el filtro posts_clauses. Esta función de filtro verifica si alguna de las palabras de la consulta existe en el campo personalizado "speel" y el resto de la consulta permanece intacta.

function custom_search_where($pieces) {

    // filtro para tu consulta
    if (is_search() && !is_admin()) {

        global $wpdb;

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

            // omitir posibles adverbios y números
            if (is_numeric($word) || strlen($word) <= 2) 
                continue;

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

        if (!empty($query)) {
            // agregar a la cláusula 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 ene 2013 11:23:51
0

Aquí hay otra forma, simplemente cambia la solicitud con el filtro 'posts_where_request'. Todo seguirá siendo el valor predeterminado excepto ('s' Y 'meta_query') => ('s' O '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'))
)

este es el código

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 feb 2020 12:33:57
0

No encontré una solución para buscar múltiples palabras clave que puedan estar mezcladas en el título de la publicación, la descripción Y/O una o varias metadatos, así que hice mi propia adición a la función de búsqueda.

Todo lo que necesitas es agregar el siguiente código en function.php, y cada vez que uses el argumento 's' en una función estándar WP_Query() y quieras que también busque en uno o varios campos de metadatos, simplemente agregas un argumento 's_meta_keys' que es un array de la(s) clave(s) de metadatos donde quieres buscar:

/************************************************************************\
|**                                                                    **|
|**  Permitir que la función de búsqueda de WP_Query() busque         **|
|**  múltiples palabras clave en metadatos además de post_title y     **|
|**  post_content                                                    **|
|**                                                                    **|
|**  Por rAthus @ Arkanite                                            **|
|**  Creado: 2020-08-18                                               **|
|**  Actualizado: 2020-08-19                                          **|
|**                                                                    **|
|**  Solo usa el argumento habitual 's' y añade un argumento          **|
|**  's_meta_keys' que contenga un array de la(s) clave(s) de         **|
|**  metadatos donde quieres buscar :)                                **|
|**                                                                    **|
|**  Ejemplo :                                                        **|
|**                                                                    **|
|**  $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'); // agregar la función de búsqueda especial en cada consulta get_posts (esto incluye 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']) { // si estamos buscando usando el argumento 's' y añadimos un argumento 's_meta_keys'
        global $wpdb;
        $search = $query->query_vars['s']; // obtener la cadena de búsqueda
        $ids = array(); // iniciar array de IDs de publicaciones coincidentes por palabra clave buscada
        foreach (explode(' ',$search) as $term) { // separar palabras clave y buscar resultados coincidentes para cada una
            $term = trim($term); // eliminar espacios innecesarios
            if (!empty($term)) { // verificar que la palabra clave no esté vacía
                $query_posts = $wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_status='publish' AND ((post_title LIKE '%%%s%%') OR (post_content LIKE '%%%s%%'))", $term, $term); // buscar en título y contenido como lo hace la función normal
                $ids_posts = [];
                $results = $wpdb->get_results($query_posts);
                if ($wpdb->last_error)
                    die($wpdb->last_error);
                foreach ($results as $result)
                    $ids_posts[] = $result->ID; // recoger IDs de publicaciones coincidentes
                $query_meta = [];
                foreach($query->query_vars['s_meta_keys'] as $meta_key) // ahora construir una consulta de búsqueda para buscar en cada clave de metadatos deseada
                    $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; // recoger IDs de publicaciones coincidentes
                $merged = array_merge($ids_posts,$ids_metas); // combinar los IDs de título, contenido y metadatos resultantes de ambas consultas
                $unique = array_unique($merged); // eliminar duplicados
                if (!$unique)
                    $unique = array(0); // si no hay resultados, agregar un ID "0" de lo contrario se devolverán todas las publicaciones
                $ids[] = $unique; // agregar array de IDs coincidentes al array principal
            }
        }
        if (count($ids)>1)
            $intersected = call_user_func_array('array_intersect',$ids); // si hay varias palabras clave, mantener solo IDs que estén en todos los arrays coincidentes
        else
            $intersected = $ids[0]; // de lo contrario, mantener el único array de IDs coincidentes
        $unique = array_unique($intersected); // eliminar duplicados
        if (!$unique)
            $unique = array(0); // si no hay resultados, agregar un ID "0" de lo contrario se devolverán todas las publicaciones
        unset($query->query_vars['s']); // eliminar consulta de búsqueda normal
        $query->set('post__in',$unique); // agregar un filtro por ID de publicación en su lugar
    }
}

Ejemplo de uso:

$search= "palabras clave a buscar";

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

Este ejemplo buscará las palabras clave "palabras clave a buscar" en los títulos de las publicaciones, descripciones y las claves de metadatos 'short_desc' y 'tags'.

Las palabras clave pueden encontrarse en uno o varios de los campos, en cualquier orden, devolverá cualquier publicación que tenga todas las palabras clave en cualquiera de los campos designados.

Obviamente puedes forzar la búsqueda en una lista de claves de metadatos que incluyas en la función y deshacerte de los argumentos adicionales si quieres que TODAS las consultas de búsqueda incluyan estas claves de metadatos :)

¡Espero que esto ayude a cualquiera que enfrente el mismo problema que yo!

18 ago 2020 20:57:13
0

Encontré una solución limpia en el núcleo de WordPress. Los desarrolladores de WordPress ya tuvieron este problema para buscar en archivos adjuntos _wp_attached_file meta y solucionaron este problema en esta función:

_filter_query_attachment_filenames()

WordPress ejecuta esta función

descripción de la imagen aquí

Tomando la idea de esta función, escribí el siguiente código para buscar en metadatos:

   /**
     * Habilita la búsqueda en tablas postmeta y posts en una sola consulta
     *
     * @see _filter_query_attachment_filenames()
     */
    add_filter( 'posts_clauses', function ( $clauses ) {

        global $wpdb;

        // Solo se ejecuta una vez:
        static $counter = 0;
        if ( 0 != $counter ++ ) {
            return $clauses;
        }

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

            // Añade un LEFT JOIN de la tabla postmeta para no afectar los JOINs existentes.
            $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 ene 2022 11:36:44
0

Todas las soluciones anteriores solo devuelven resultados si existe una coincidencia en la meta clave "speel". Si tienes resultados en otros lugares pero no en este campo, no obtendrás nada. Nadie quiere eso.

Se necesita un LEFT JOIN. El siguiente código creará uno.

           $meta_query_args = array(
              'relation' => 'OR',
              array(
                'key' => 'speel',
                'value' => $search_term,
                'compare' => 'LIKE',
              ),
              array(
                'key' => 'speel',
                'compare' => 'NOT EXISTS',
              ),
            );
            $query->set('meta_query', $meta_query_args);
30 may 2018 10:39:38
4

La respuesta de @satbir-kira funciona muy bien pero solo buscará en los metadatos y el título de la publicación. Si deseas que busque en metadatos, título y contenido, aquí está la versión modificada.

    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;

          // Solo se ejecuta una vez:
          static $nr = 0;
          if( 0 != $nr++ ) return $sql;

          // WHERE modificado
          $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;
        });
      }
    });

Y aquí está su uso:

$args['_meta_or_title'] = $get['search']; //ya no se usa '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'
  )
);

Reemplaza $get['search'] con tu valor de búsqueda

16 ene 2019 18:02:38
Comentarios

No funciona cuando agregas argumentos tax_query

Subhojit Mukherjee Subhojit Mukherjee
23 feb 2022 17:09:34

@SubhojitMukherjee ¿Encontraste una solución cuando agregas un tax_query? Tengo exactamente el mismo problema que tú :)

mhsc90 mhsc90
18 dic 2023 11:25:10

¡Ok, encontré mi solución! Gracias a Sully (https://wordpress.stackexchange.com/questions/403040/query-to-get-result-by-title-or-meta-along-with-tax-query-parameter) Aquí el código para actualizar y que funcione con tax_query:

mhsc90 mhsc90
18 dic 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 dic 2023 11:37:06
0

para mí funciona perfectamente el siguiente código:

            $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 mar 2020 15:21:57
0

Esta es una gran solución pero necesitas corregir una cosa. Cuando llamas a 'post__in' necesitas establecer un array de IDs y $unique es un array de posts.

ejemplo:

$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(); //aquí inicializas tu array

foreach($posts as $post)
{
    $array[] = $post->ID; //llena el array con los IDs de los posts
}


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

Descubrí que la respuesta de Asad Manzoors funcionó para mí. Si alguien la necesita, mi versión requería implementar 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));

// Si no se encuentran posts, asegurarse de que $query no seleccione todos los posts.
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 oct 2024 13:40:47