I have one post id x, one category id y. I want to retrieve the position at which the post will appear in the category.
- It is confirmed that the post is from the category
- Post order will be based on a numeric value set in post meta, meta key ‘facebook_shares’
- Category have more that 1k other posts.
I am looking for a best solution which could consume less database query usage and single query will be the best.
Thanks in advance.
If I understand well, you need to retrieve all the posts having category ‘y’ and also meta key ‘facebook_shares’, after that, you need the position of a specific post.
My proposal is:
WP_Query
and filter the results for required category and meta field. This class should also filter the SQL query to set the meta value as a property of post objects returned byWP_Query::get_posts
compare
method looking at meta properties of post objects. SplHeap has the propery of automatic order elements passed inserted in it.And only one db query is done.
Let’s code.
First of all write our
SplHeap
implementation:Now the class that extends
WP_Query
to get the posts. Constructor of this class accept a category term, that can be passed as category id, a category slug or even a category object.By default the
'post_type'
argument is set to ‘post’, but that can be overriden passing a second argument to constructor.Then the class that “glues” previous:
Finally, a function that work as façade to the 3 classes. It accepts a post (id or object) and a category (id, slug or object):
Usage Example
Returning values:
If the query return some posts and the post given is one of them, then the function returns the post order in the post collection, looking at ‘facebook_shares’ meta key.
E.G. the query returns 3 posts, having values of ‘facebook_shares’ respectively: 10, 15, 30
and you pass to function the id of post that has ‘facebook_shares’ = 15, then the function return 2, because the post is the second in order.
If the query returns no posts, then the function return -1.
If the query returns some posts, but the wanted posts is not present among them, the function return false.
Caveats
There are some issues on core WP_Query using meta_query without specific values (‘compare’ = EXIST or NOT EXIST) specially if the query contains also a tax query.
To avoid them, in the class that extends WP query use some filters on SQL query, and where clause is setted “manually”. However, if there are some external code (plugin, themes) adding custom filters on query (using posts_where, posts_join and similar filter hooks) that code can break the call behaviour.
The code is very quicky tested, and seems to work, however.. no warranty.