¿Puedo fusionar 2 WP_Query($variable)?

17 jun 2012, 13:53:15
Vistas: 44K
Votos: 27

Estoy ejecutando una red multisite y he configurado una consulta SQL que usa switch_to_blog(); y consulta los posts.

¿Hay alguna manera de que pueda declarar la consulta dentro de un nuevo WP_Query y realmente fusionarla con otra?

Básicamente si hago esto:

$number1 = new WP_Query($multisitequery);

¿Puedo fusionarlo con:

$number2 = new WP_Query($normalquery);

$normalquery contiene configuraciones como paginación, por página, extracto, título, etc... en un shortcode de portfolio.

Me gustaría que incluyera posts consultados desde mi nueva consulta $multisite.

¿Se puede lograr esto? Solo quiero evitar crear toda una nueva configuración de shortcode jaja

Muchas gracias de antemano. Rory

EDICIÓN========

Lo que tengo es:

$portfolio = array();
$portfolio = $settings;

Más abajo en mi función de portfolio "después de todas las $settings['options']" tengo:

$portfolio_query = new WP_Query( $portfolio );

El $portfolio_query usa un bucle en una plantilla de página.

Quiero agregar una consulta adicional así:

global $wpdb, $blog_id, $post;

$blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_blogs ORDER BY blog_id" ) );

$globalcontainer = array();

foreach ($blogs as $blog){
   // Cambiar al blog
   switch_to_blog($blog->blog_id);

   $globalquery = query_posts($args);

   $globalcontainer = array_merge( $globalcontainer, $globalquery );

   // Restaurar al blog actual
   restore_current_blog();
}

donde asumo que $globalcontainer sería el array para fusionar en el wp_query();.

Entonces, tomando en cuenta lo que has respondido, en teoría podría simplemente:

$mergedqueryargs = array_merge($portfolio , $globalcontainer);
$portfolio_query = new WP_query($mergedqueryargs);

¿Sería eso correcto?

Segundo, con respecto a la sobrescritura de claves del array_merge..... ¿Cómo podría evitar una sobrescritura?

0
Todas las respuestas a la pregunta 4
8
46

No basta con fusionar los argumentos, necesitas fusionar el array resultante de posts y el conteo de post_count. Esto es lo que me funciona:

//configura tus consultas como ya lo haces
$query1 = new WP_Query($args_for_query1);
$query2 = new WP_Query($args_for_query2);

//crea una nueva consulta vacía y rellénala con las dos anteriores
$wp_query = new WP_Query();
$wp_query->posts = array_merge( $query1->posts, $query2->posts );

//rellena el conteo de post_count para que el bucle funcione correctamente
$wp_query->post_count = $query1->post_count + $query2->post_count;
13 nov 2013 22:44:55
Comentarios

Esto se ve bien, pero estoy buscando una solución que pueda usarse con el hook pre_get_posts - es decir, necesito modificar un objeto WP_Query existente. He intentado usar '$wp_query->init();' en lugar de '$wp_query = new WP_Query();', pero eso parece causar problemas. ¿Alguna sugerencia?

Boycott A.I. Boycott A.I.
31 dic 2013 00:14:13

Deberías agregar una pregunta diferente ya que es una respuesta distinta, pero puedes usar este mismo código pero solo las partes de query2, modificando las partes ->posts y ->post_count del objeto $wp_query para tener la suma de la consulta original que te da pre_get_posts y la segunda consulta que quieres añadir.

guidod guidod
3 ene 2014 17:32:11

¿Cómo puedo eliminar duplicados de este array combinado?

roshan roshan
5 nov 2015 10:02:53

Gracias por esto. Tenía un meta_query problemático usando una relación OR. Lo dividí usando esta técnica y pasó de 41s a 0.01s.

Craig Harshbarger Craig Harshbarger
9 may 2016 00:48:59

@ban-geoengineering ¿Alguna vez lograste resolver esto? Estoy atascado con lo mismo.

harvey harvey
28 oct 2019 20:25:31

@harvey Lo siento, no encuentro ningún código relacionado con eso. (Fue hace unos años). Tu mejor opción podría ser publicar una nueva pregunta. Buena suerte. :-)

Boycott A.I. Boycott A.I.
28 oct 2019 23:46:43

Si terminas creando un nuevo array y eliminando duplicados usando algo como array_unique(), deberías poder poblar $wp_query->post_count con count($wp_query->posts)

armadadrive armadadrive
4 jun 2020 02:32:43

Además, también necesitarás actualizar "found_posts", como: $wp_query->found_posts = $promotor->found_posts + $other->found_posts;

Loosie94 Loosie94
26 nov 2020 12:03:58
Mostrar los 3 comentarios restantes
7
33

Generalmente fusiono sus arrays de IDs y hago una tercera consulta. Para mantener las primeras consultas ligeras, solo devuelvo sus IDs usando el parámetro fields así:

//configura tus consultas con el parámetro extra fields => ids
$query1 = new WP_Query(array('fields' => 'ids','other_parameters' => 'etc'));
$query2 = new WP_Query(array('fields' => 'ids','other_parameters'=>'etc'));

//ahora tienes los IDs de posts en $query->posts
$allTheIDs = array_merge($query1->posts,$query2->posts);

//nueva consulta, usando el parámetro post__in
$finalQuery = new WP_Query(array('post__in' => $allTheIDs));

Espero que esto ayude

---EDITADO---

Después de mi respuesta, la pregunta original fue editada con detalles sobre multisitio. En el caso de fusiones de posts en multisitio, esto no funciona.

30 jul 2015 20:19:43
Comentarios

Esta respuesta funciona bien y parece menos un truco que la solución principal. La usé hace un año más o menos y volví a utilizarla ahora. Gracias.

Davey Davey
5 jul 2017 14:01:46

¿Cómo puede funcionar esto correctamente cuando los post_ID no son únicos en el ámbito multisitio (son únicos por blog, pero varios posts pueden tener los mismos ID en toda la red)?

Adal Adal
6 oct 2017 00:41:11

@Adal La pregunta original fue editada después de mi respuesta, por lo que mi respuesta es relevante para el ámbito de un solo sitio. Con multisitio nunca intenté fusionar consultas y en ese caso obviamente esto no funcionará, las consultas deben hacerse por separado y luego fusionarse. Después de la fusión podrías intentar ordenarlas con funciones de ordenamiento de php (ordenar por fecha de publicación, etc.).

Bora Yalcin Bora Yalcin
6 oct 2017 15:20:43

Puedes preservar el ordenamiento usando 'orderby' => 'post__in' en la última consulta.

fregante fregante
23 feb 2018 12:00:25

Esto solo funciona para mí cuando establezco el post_type en el $finalQuery

RobbTe RobbTe
15 ene 2019 16:26:35

para custom post types, creo que el parámetro post_type lo necesita en cualquier caso, incluso cuando se pregunta por ids porque es post_type=post por defecto @RobbTe

Bora Yalcin Bora Yalcin
15 ene 2019 19:03:08

Asegúrate de verificar si el array de IDs fusionados está vacío. Porque una consulta post__in devuelve resultados si es un array vacío. Un error que WP se niega a corregir: https://core.trac.wordpress.org/ticket/28099

Sherri Sherri
25 mar 2025 16:05:45
Mostrar los 2 comentarios restantes
1

Entonces, si tienes esto:

$number1 = new WP_Query($multisitequery);

$number2 = new WP_Query($normalquery);

Asumo que defines estos en algún lugar anterior?

$multisitequery = array();
$normalquery = array();

...en cuyo caso, para combinar las dos consultas, solo necesitas array_merge() los dos arrays antes de pasarlos a new WP_Query():

$merged_query_args = array_merge( $normalquery, $multisitequery );

$merged_query = new WP_Query( $merged_query_args );

Nota que el orden es importante en la llamada a array_merge(). Si ambos tienen la misma clave de array, el segundo array sobrescribirá al primero.

17 jun 2012 21:57:06
Comentarios

Gracias por responder, Chip, te lo agradezco mucho. He editado mi pregunta original para darte una mejor idea de lo que tengo para trabajar. Muchas gracias de nuevo y espero con interés otra respuesta llena de conocimiento jaja Gracias

Rory Rothon Rory Rothon
18 jun 2012 01:17:54
0

De esta manera, puedes combinar dos consultas WP_Query con diferentes post_type u otros datos de ordenación, por ejemplo, y luego unirlas por ids en una sola consulta WP_Query que funcionará completamente - para preservar el orden al unirlas, necesitas especificar orderby => post__in

Mi ejemplo muestra cómo crea un nuevo ciclo WP_Query y puede afectar cualquier otro ciclo para mostrar publicaciones al llamar new global_change_of_sorting_posts->change_query_posts() => query_posts() ¡debes llamar esto antes de procesar el ciclo para mostrar las publicaciones!

class global_change_of_sorting_posts
{
    public function get_posts_ids()
    {
        $query1 = new WP_Query([
            'fields' => 'ids',
            'posts_per_page' => -1,
            'post_type' => 'post',
        ]);
        $query2 = new WP_Query([
            'posts_per_page' => -1,
            'fields' => 'ids',
            'post_type' => 'custom-post',
        ]);
        $merge_ids_posts = $query1->posts + $query2->posts;
        wp_reset_query();
        return $merge_ids_posts;
    }

    public function get_posts_wp_query()
    {
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $posts_per_page = 40;
        $wp_query = new WP_Query([
            'posts_per_page' => $posts_per_page,
            'paged' => $paged,
            'post__in' => $this->get_posts_ids(),
            'orderby' => 'post__in',
        ]);
        while ($wp_query->have_posts()) {
            $wp_query->the_post();

            var_dump(get_the_ID());
        }
    }

    public function change_query_posts($query_string)
    {
        parse_str($query_string, $args);
        $args['post__in'] = $this->get_posts_ids();
        $args['orderby'] = 'post__in';
        query_posts($args); # conversión de la consulta
    }
}
16 jul 2020 11:04:32