How to limit the number of fetched items by a WP_Query - php

The 'posts_per_page' is not limiting the number of items WP_Query will fetch.
Which is OK, however I need to find a way how to break the WP_Query with some limit or break like attribute after 3 items are fetched. I have many items and to fetch 3 items it get all the 1000+ items in my database, which is slowing down the page in the end.
Any idea how to limit the query to get only 3 instead of all items from the db?
$args = array(
'post_type' => array( 'books' ),
'meta_query' => array(
array(
'key' => 'book_state',
'value' => 'sold'
)
),
'posts_per_page' => 3,
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
$booksNumber = $the_query->found_posts; // returns 1282 instead of 3
...

found_posts returns the total number of posts matching the query parameters.
post_count returns the total number of posts being displayed. I believe what you want to do is:
$booksNumber = $the_query->post_count;
If that doesn't work, I would try using get_posts instead of WP_Query:
$postslist = get_posts($args);
$booksNumber = count($postslist);

It looks like you're only using one meta query, so try using get_posts.
Normally, I'd recommend WP_Query, but I can see how it can be confusing. If you run the following code you will see something more like what you're expecting:
$args = array(
'post_type' => 'books',
'meta_key' => 'book_state',
'meta_value' => 'sold',
'posts_per_page' => 3,
);
$posts = get_posts($args);
echo count($posts);
var_dump($posts);

Related

WordPress: Combine two loops with different amount of posts

I want to show a random selection of 4 new products in WooCommerce.
For that I'm using a first loop to get the 20 newest products.
Like this:
$args= array(
'post_type' => 'product',
'posts_per_page' => 20,
'orderby' => 'date',
);
Now I've a second loop to reduce the products to 4 in a random order:
$args_new = array(
'posts_per_page' => 4,
'orderby' => 'rand',
);
In the end I merge the two loops:
$final_args = array_merge( $args, $args_new );
But that doesn't work. Is there any other way to achieve it?
General knowledge
The post_type argument accept String or Array.
Argument
Description
post_type
(String/Array) – use post types. Retrieves posts by post types, default value is post. If tax_query is set for a query, the default value becomes any.
Source # https://developer.wordpress.org/reference/classes/wp_query/#post-type-parameters
Merging queries
In crude terms we want to combine 2 posts queries, retrieve each posts ID, push them to a new array and open a new query.
Keep in mind that if you want your 4 posts to be random (as you stated in the comments) they might be some duplicates of the last 20 from the first query. Don't forget to offset the second query.
<?php
// First query
$args_1 = get_posts( array(
'post_type' => 'dogs',
'post_status' => 'publish',
'post_count' => 20,
) );
// Second query
$args_2 = get_posts( array(
'post_type' => 'dogs',
'post_status' => 'publish',
'post_count' => 4,
'offset' => 20,
'orderby' => RAND,
) );
// Merge queries
$posts = array_merge( $args_1, $args_2 );
// Push posts IDs to new array
$identifiers = array();
foreach ( $posts as $post ) {
array_push( $identifiers, $post->ID );
};
// Third query
$query = new WP_Query( array(
'post_status' => 'publish',
'post_count' => 24,
'post_in' => array_unique( $identifiers ),
) );
var_dump( $query );

Wordpress arguments to filter WP query

I'm currently grabbing some posts using SQL. I am wanting to use some arguments in the posts I have grabbed. Is this possible? I'm trying to limit the amount of posts returned per page to paginate it. I usually use the args array. Can the args array work with this?
$get_posts = $wpdb->get_results("SELECT id FROM wp_posts WHERE post_type = 'job_listing'");
Of course it can, you just need to get the IDs from the database in a flat array, but you don't really need to query the database directly.
$args = array(
'post_type' => 'job_listing',
'post_status' => 'publish',
'posts_per_page' => 10,
'paged' => get_query_var('paged', 1),
'post__in' => $get_posts,
);
Complete reference

Wordpress posts count with comman tags within specific category

i have two categories 'A' and 'B'. Both have 5 posts(each) with tag 'C'. How i can display the number of posts as 5 in Category 'A' or 'B' page. It showing total number of post with tag 'C' as 10. I need to show it as 5. How i can pass category variable to display exact count with tag within specific category. Here is my current code:
$tag = get_term_by('name', $tags,'post_tag');
$count = $tag->count;
reference: https://codex.wordpress.org/Function_Reference/get_term_by
This is not possible with the get_term_by() method.
Try this:
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND', // only posts that have both taxonomies will return.
array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => 'TAG_C', // you can also use an array with tags.
),
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'CATEGORY_B', // you can also use an array with categories.
),
),
);
$posts = get_posts($args);
$count = count($posts);
I haven't tested this code, but it should work. Ofcourse you do have
to set the correct terms.
UPDATE
When dealing with many posts I would create a $wpdb sql query that counts the rows, so only a number is returned and not all the posts. You can find an sql count example here.
You can use "found_posts" property of the WP_Query class object.
$args = array(
'posts_per_page' => 10,
'category_name' => 'aaa', // category slug
'tag' => 'ccc' // tag slug
);
$wp_query = new WP_Query( $args );
echo "Total posts count: ".$wp_query->found_posts;

Show a post from selected categories wordpress

I'm trying to show one post from several categories. My code just shows the first category post :\ any advice?
<?php
$args = array(
'cat' => 1,15,
'post_type' => 'post',
'posts_per_page' => '1',
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ($query->the_post()):
the_title();
the_post_thumbnail(array(200, 200));
?>
<?php endwhile;
endif;?>
Please follow the code to understand how to show post items from selected category items by passing the category ID.
$args = array(
'post_type' => 'post', // post type
'posts_per_page' => -1, // number of post items
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => array( 16, 244 ) // pass the ID of the post category, separated by a comma.
)
)
);
You defined 'posts_per_page' => '1' so you are getting exactly what you ask: 1 post. Either from category 1 or 15, whichever is the most recent post.
If you want 1 post from EACH category, I would just loop your code, with a different category each time (just 1).
Only thing is, that will be in order of the category IDs you give and not sorted on date on something else. Also, if you have a post in multiple categories, you might end up with the same post twice.

Exclude post_type or pages

I am trying to exclude a specific post_type or pages, but I am not sure if I am thinking correctly. The issue is that all my pages comes up in my while query which is supposed to be dedicated for (almost) all my posts.
Here is what I am dealing with:
$args = array(
'post_type' => 'any',
'posts_per_page' => '-1',
'post_taxonomy' => 'any',
'cat' => -14,
);
I was thinking about writing 'post_type' => 'any' into posts, but as I remember that didn't work with my custom posts.
Do anyone have a working solution?
Thanks
If you are talking about filtering post with WP_Query you should read something here https://codex.wordpress.org/Class_Reference/WP_Query
Basically you can use a lot of filters, for example:
$args = array(
'post_type' => 'post',
'cat' => -14,
'post__not_in' => array( 2, 5 )
);
$query = new WP_Query( $args );
This will find only posts (not pages), not in category with id 14 and not those with post ID 2 or 5.
Now if you could be more precise in your question I could give you the exact array you need to obtain it.

Categories