Jak ograniczyć liczbę postów otrzymywanych przez WP_Query?

25

Badam Google i WPSE i jedyne, co widzę wielokrotnie, to używanie showposts, które jest przestarzałe.

Jestem zaznajomiony WP_Queryi pomyślałem, że jeśli ustawię posts_per_pageswój limit (tj. 5), i nopagingtak true, stanie się coś w rodzaju „ Ok, dam ci tylko 5 postów ”. Ale to nie działa.

wprowadź opis zdjęcia tutaj

W jaki sposób mogę to zrobić?

EliasNS
źródło
Po prostu'posts_per_page=5'
Pieter Goosen
Używam tego, ale znalazłem wszystkie posty. Jeśli mam dostęp do found_postswłaściwości, jest to liczba większa niż 5. Chcę, aby moje zapytanie zawierało tylko 5 postów. Czy to możliwe? @PieterGoosen
EliasNS
Nie powinieneś ustawiać nopagingparametru, ustawienie tego na true oznacza, że ​​otrzymujesz wszystkie posty
Pieter Goosen
@PieterGoosen Jeśli nie ustawię nopagingparametru, zostanie on ustawiony domyślnie false, więc strona główna pokazuje 5 postów, ale zapytanie zawiera więcej. Dodaję zdjęcie do pytania.
EliasNS,
Twoje komentarze są mylące, poprosiłeś o ograniczenie liczby postów wyświetlanych na stronie do 5, czyli to, co otrzymujesz. Teraz mówisz (ponownie przeczytaj poprzedni komentarz :-)), zapytanie zawiera więcej. Proszę wytłumacz. Nie możesz ustawić post_per_page, a następnie użyć parametru no_paging ustawionego na true w tym samym zapytaniu, jest to albo post_per_page LUB nopaging ustawiony na true
Pieter Goosen

Odpowiedzi:

43

Myślę, że teraz rozumiem, co próbujesz zrobić. Gdy uruchomisz niestandardowe zapytanie z WP_Queryustawionym limitem, aby uzyskać tylko 5 postów na stronę, zapytanie będzie pobierało tylko 5 postów, a to zapytanie będzie zawierało tylko 5 postów, ALE ze względu na paginację, WP_Querynadal działa w całej bazie danych i zlicza wszystkie posty spełniające kryteria zapytania.

Można to zobaczyć, patrząc na $found_postsi $max_num_pageswłaściwości zapytania. Weźmy przykład:

Masz 20 postów należących do domyślnego typu postu post. Ty tylko potrzebujesz najnowszych 5 posty bez paginacji. Twoje zapytanie wygląda następująco

$q = new WP_Query( 'posts_per_page=5' );
  • var_dump( $q->posts ) da ci 5 najnowszych postów zgodnie z oczekiwaniami
  • echo $q->found_posts da tobie 20
  • echo $q->max_num_pages da tobie 4

Wpływ tej dodatkowej pracy jest minimalny na witryny zawierające tylko kilka postów, ale może to być kosztowne, jeśli prowadzisz witrynę z setkami lub tysiącami postów. Jest to marnowanie zasobów, jeśli kiedykolwiek będziesz potrzebować tylko 5 najnowszych postów

Istnieje nieudokumentowany parametr o nazwie, no_found_rowsktóry używa wartości boolowskich, których można użyć do zwolnienia zapytania po znalezieniu 5 potrzebnych postów. Zmusi to WP_Querynie szukać więcej postów spełniających kryteria po tym, jak pobierze liczbę zapytań. Ten parametr jest już wbudowany get_posts, dlatego get_postsjest nieco szybszy niż WP_Querychociaż get_postsużywaWP_Query

Wniosek

Podsumowując, jeśli nie zamierzasz używać paginacji w zapytaniu, zawsze mądrze jest 'no_found_rows=true'w zapytaniu przyspieszyć i zaoszczędzić na marnowaniu zasobów.

Pieter Goosen
źródło
3

Po rozmowie z @Pieter Goosen na temat komentarzy do pytania, myślę, że mogę odpowiedzieć na pytanie i wyjaśnić swój błąd.

Kluczem jest to, że found_postsmnie zaskoczył. Sądzę, że ta liczba to pobrane posty, ale nie jest. Jest to liczba postów spełniających kryteria . To tak, jakby WP_Querymiał 2 części: jedną do znajdowania (wszystkich) postów, a drugą do pobierania zawartości, gdy sprawdza paginationparametry. Mamy więc $post_countwłaściwość, która jest liczbą pobranych postów (kodeks mówi The number of posts being displayed), która oczywiście jest równa liczbie posts_per_pageparametrów i liczbie elementów we $postswłaściwości tablicy.

Więc WP_Querynie robi żadnej bezużytecznej pracy, jak myślałem ^^

Mam nadzieję, że to pomaga innym!

EliasNS
źródło
Zobacz moją odpowiedź. Myślę, że rozumiem, co masz na myśli :-)
Pieter Goosen
Tak! Zrobiłeś to bardzo dobrze: D W końcu udało mi się to zrobić i rozumiem wszystko = D Dzięki @PieterGoosen!
EliasNS,
Gotowy! Rozszerzył moją własną odpowiedź ^^ @PieterGoosen
EliasNS
1

Ok, pozwala ci mieć typ postu o nazwie „blog_posts” i chcesz pobrać 5 postów tego typu. Oto, co musisz zrobić

$args = array(
        'post_type' => 'blog_posts',
        'posts_per_page' => '5',
);


$query = new WP_Query($args);

Powyższe zapytanie zwróci 5 postów typu „blog_posts”, jeśli nie jest to niestandardowy typ postów, po prostu zamień w ten sposób, 'post_type' => 'posts',jeśli chcesz pobrać wszystkie posty, a następnie zamień w ten sposób 'posts_per_page' => '-1',, aby uzyskać więcej informacji Zapytanie WP

shuvroMithun
źródło
Popatrz na komentarze do pytania.
EliasNS,
1

Wiem, że @ user1750063 wspomniał o kodzie, ale spróbuj tego

$args = array (
    'post_type'              => 'custom_post',
    'nopaging'               => false,
    'posts_per_page'         => '5',
    'order'                  => 'DESC',
    'orderby'                => 'ID',
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        // display content
    }
} else {
    // display when no posts found
}

wp_reset_postdata();     // Restore original Post Data
Shreyo Gi
źródło
idjest niepoprawny jako orderbywartość i paginationjest niepoprawnym parametrem
Pieter Goosen
paginationnie jest prawidłowym parametrem. Masz na myśli 'nopaging' => true? Jeśli tak, to dostanę WSZYSTKIE posty. Nie tego chcę. @PieterGoosen Myślę, że on ma na myśli ID.
EliasNS,
orderby służy do wyświetlania zamówienia, prawda? Nie narusza wartości / parametru braku stronicowania. @PieterGoosen, dlaczego ID i zamówienie są nieprawidłowe? Czy możesz wyjaśnić tę kwestię?
Shreyo Gi
Powinno być ID, nieid
Pieter Goosen