Pot să combin 2 interogări WP_Query($variable)?
Administrez o rețea multisite și am configurat o interogare SQL care folosește switch_to_blog(); și interoghează postările.
Există vreo modalitate prin care pot declara interogarea într-un nou WP_Query și să o combin efectiv cu alta?
Practic, dacă fac asta:
$number1 = new WP_Query($multisitequery);
O pot combina cu:
$number2 = new WP_Query($normalquery);
$normalquery
conține setări precum paginare, per pagină, extras, titlu etc... într-un shortcode de portofoliu.
Aș dori să includă postările interogate din noua mea interogare $multisite
.
Se poate realiza acest lucru? Vreau doar să evit crearea unei configurații complete noi pentru shortcode.
Mulțumesc anticipat. Rory
EDITARE========
Ce am eu este:
$portfolio = array();
$portfolio = $settings;
Mai jos în funcția mea de portofoliu "după toate $settings['options']" am:
$portfolio_query = new WP_Query( $portfolio );
$portfolio_query
folosește o buclă într-un șablon de pagină.
Vreau să adaug o interogare suplimentară astfel:
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){
switch_to_blog($blog->blog_id);
$globalquery = query_posts($args);
$globalcontainer = array_merge( $globalcontainer, $globalquery );
restore_current_blog();
}
unde presupun că $globalcontainer
ar fi array-ul de combinat în wp_query();
.
Deci, ținând cont de ce ai răspuns, teoretic aș putea simplu să:
$mergedqueryargs = array_merge($portfolio , $globalcontainer);
$portfolio_query = new WP_query($mergedqueryargs);
Ar fi corect acest lucru?
În al doilea rând, referitor la suprascrierea cheilor array-ului la array_merge..... Cum aș putea preveni o suprascriere?
Nu vei obține prea multe rezultate doar prin combinarea argumentelor, trebuie să fuzionezi array-ul de postări rezultat și numărul post_count. Acest lucru funcționează pentru mine:
//configurează-ți interogările așa cum ai făcut deja
$query1 = new WP_Query($args_for_query1);
$query2 = new WP_Query($args_for_query2);
//creează o nouă interogare goală și umple-o cu celelalte două
$wp_query = new WP_Query();
$wp_query->posts = array_merge( $query1->posts, $query2->posts );
//completează numărul post_count pentru ca bucla să funcționeze corect
$wp_query->post_count = $query1->post_count + $query2->post_count;

Arată bine, dar caut o soluție care poate fi folosită cu hook-ul pre_get_posts - adică trebuie să modific un obiect WP_Query existent. Am încercat să folosesc '$wp_query->init();' în loc de '$wp_query = new WP_Query();', dar asta pare să încurce lucrurile. Aveți sugestii?

Ar trebui să adaugi o altă întrebare deoarece este un alt răspuns, dar poți folosi același cod doar părțile pentru query2, modificând părțile ->posts și ->post_count ale obiectului $wp_query pentru a avea suma întrebării originale pe care ți-o oferă pre_get_posts și a doua interogare pe care dorești să o adaugi.

Mulțumesc pentru asta. Aveam o problemă cu un meta_query folosind o relație OR. Am rezolvat-o folosind această tehnică și timpul de execuție a scăzut de la 41s la 0.01s.

@ban-geoengineering Ai reușit să rezolvi problema? Sunt blocat și eu cu asta.

@harvey Îmi pare rău, nu mai găsesc codul legat de asta. (A fost acum câțiva ani.) Cel mai bine ar fi să postezi o nouă întrebare. Succes. :-)

Dacă ajungi să creezi un nou array și să elimini duplicatele folosind ceva de genul array_unique()
, ar trebui să poți popula $wp_query->post_count
cu count($wp_query->posts)

De obicei îmbin array-urile cu ID-uri și fac o a treia interogare. Pentru a menține primele interogări eficiente, returnez doar ID-urile folosind parametrul fields astfel:
//configurează interogările cu parametrul suplimentar fields => ids
$query1 = new WP_Query(array('fields' => 'ids','other_parameters' => 'etc'));
$query2 = new WP_Query(array('fields' => 'ids','other_parameters'=>'etc'));
//acum avem ID-urile postărilor în $query->posts
$allTheIDs = array_merge($query1->posts,$query2->posts);
//noua interogare, folosind parametrul post__in
$finalQuery = new WP_Query(array('post__in' => $allTheIDs));
Sper că acest lucru vă ajută
---EDITARE---
După răspunsul meu, întrebarea originală a fost editată cu detalii despre multisite. În cazul combinării postărilor din mai multe site-uri, această metodă nu funcționează.

Acest răspuns funcționează bine și pare mai puțin o soluție improvizată decât cea din top. L-am folosit acum aproximativ un an și am revenit să-l folosesc din nou acum. Mulțumesc.

Cum poate funcționa corect acest lucru atunci când post_ID-urile nu sunt unice în contextul multisite (sunt unice pe blog, dar mai multe articole pot avea aceleași ID-uri în întreaga rețea)?

@Adal Întrebarea originală a fost editată după răspunsul meu, deci răspunsul meu este relevant pentru un singur site. În cazul multisite, nu am încercat niciodată să îmbin interogările, iar în acest caz, evident, acest lucru nu va funcționa. Interogările trebuie făcute separat și apoi îmbinate. După îmbinare, poți încerca să le ordonezi folosind funcțiile de sortare din PHP (sort după data publicării etc).

Poți păstra sortarea folosind 'orderby' => 'post__in'
în ultima interogare.

Aceasta funcționează pentru mine doar când setez post_type în $finalQuery

pentru postări personalizate, cred că parametrul post_type are nevoie de asta în orice caz, chiar și atunci când ceri după id-uri, deoarece implicit este post_type=post @RobbTe

Asigură-te că verifici dacă array-ul de ID-uri îmbinate este gol. Deoarece o interogare post__in returnează rezultate dacă este un array gol. Un bug pe care WP refuză să-l rezolve: https://core.trac.wordpress.org/ticket/28099

Deci, dacă ai asta:
$number1 = new WP_Query($multisitequery);
$number2 = new WP_Query($normalquery);
Presupun că le-ai definit undeva anterior?
$multisitequery = array();
$normalquery = array();
...în acest caz, pentru a combina cele două interogări, doar array_merge()
cele două array-uri înainte de a le transmite către new WP_Query()
:
$merged_query_args = array_merge( $normalquery, $multisitequery );
$merged_query = new WP_Query( $merged_query_args );
Reține că ordinea este importantă în apelul array_merge()
. Dacă ambele au aceeași cheie de array, al doilea array va suprascrie primul array.

Astfel, puteți combina două interogări WP_Query cu diferite post_type sau alte criterii de sortare, de exemplu, și apoi le puteți uni prin ids într-o singură interogare WP_Query care va funcționa integral - pentru a păstra sortarea la unire, trebuie să specificați orderby => post__in
Exemplul meu arată cum creează un nou ciclu WP_Query și poate afecta orice alt ciclu pentru afișarea postărilor prin apelarea new global_change_of_sorting_posts->change_query_posts() => query_posts() pe care trebuie să-l apelați înainte de procesarea ciclului pentru afișarea postărilor!
class global_change_of_sorting_posts
{
public function get_posts_ids()
{
$query1 = new WP_Query([
'fields' => 'ids', // Returnează doar ID-urile postărilor
'posts_per_page' => -1, // Toate postările
'post_type' => 'post', // Tipul postărilor standard
]);
$query2 = new WP_Query([
'posts_per_page' => -1, // Toate postările
'fields' => 'ids', // Returnează doar ID-urile postărilor
'post_type' => 'custom-post', // Tipul personalizat de postări
]);
$merge_ids_posts = $query1->posts + $query2->posts; // Combină ID-urile
wp_reset_query(); // Resetează interogarea
return $merge_ids_posts;
}
public function get_posts_wp_query()
{
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // Pagina curentă
$posts_per_page = 40; // Numărul de postări pe pagină
$wp_query = new WP_Query([
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'post__in' => $this->get_posts_ids(), // ID-urile combinate
'orderby' => 'post__in', // Păstrează ordinea din array
]);
while ($wp_query->have_posts()) {
$wp_query->the_post();
var_dump(get_the_ID()); // Afișează ID-ul postării
}
}
public function change_query_posts($query_string)
{
parse_str($query_string, $args); // Parsează șirul de interogare
$args['post__in'] = $this->get_posts_ids(); // Adaugă ID-urile combinate
$args['orderby'] = 'post__in'; // Păstrează ordinea din array
query_posts($args); // Modifică interogarea globală
}
}
