admin管理员组文章数量:1334132
I have two meta_keys on a custom post type. I want to be able to query all of these posts, and order them by the two meta_key
, one taking precedence over the other.
I.e. I have one meta_key
called stickied
, these should always appear first. The second meta_key
is popularity
, which is a basic hit count for that post.
When I use meta_query
, it seems that posts without the meta keys initialized will not appear in the result set. I want all posts regardless of whether they have the meta_key
initialized or not, and then order them based on those meta_key
.
Is this possible?
I have two meta_keys on a custom post type. I want to be able to query all of these posts, and order them by the two meta_key
, one taking precedence over the other.
I.e. I have one meta_key
called stickied
, these should always appear first. The second meta_key
is popularity
, which is a basic hit count for that post.
When I use meta_query
, it seems that posts without the meta keys initialized will not appear in the result set. I want all posts regardless of whether they have the meta_key
initialized or not, and then order them based on those meta_key
.
Is this possible?
Share Improve this question edited Jul 18, 2017 at 3:55 Johansson 15.4k11 gold badges43 silver badges79 bronze badges asked Jul 18, 2017 at 2:26 Blaine LafreniereBlaine Lafreniere 1891 silver badge8 bronze badges 1 |4 Answers
Reset to default 2I had a similar issue but couldn't solved with the snippets on this thread.
I had to order a query by:
- all 'featured' posts first (is_it_a_featured_etf) and
- by a numeric field (etf_aum) in DESC order after the featured ones.
My solution:
'meta_query' => [
'relation' => 'OR',
'etf_aum' => array(
'key' => 'etf_aum',
'type' => 'NUMERIC',
'compare' => 'EXISTS',
),
'is_it_a_featured_etf' => array(
'key' => 'is_it_a_featured_etf',
'compare' => 'EXISTS',
'value' => '1',
'operator' => '=',
),
],
'orderby' => [
'is_it_a_featured_etf' => 'ASC',
'etf_aum' => 'DESC',
]
As I understand, you are trying to sort the post by meta values. In such cases, you can use 'orderby => 'meta_value'
. So your query will look like this:
$args = array(
'orderby' => 'meta_value',
'meta_key' => 'stickied',
);
$query = new WP_Query( $args );
Not that orderby
can accept multiple values, such as:
$args = array(
'post_type' => 'page',
'orderby' => array( 'title' => 'DESC', 'meta_value' => 'ASC' ),
'meta_key' => 'stickied',
);
However I'm not sure if you can use multiple meta values, but it is probably possible. At the moment I don't have such condition in my database to test it, but based on my example and this codex page you should be able to easily try it out.
Please let me know if sorting by multiple values worked for you based on above structure.
UPDATE
After digging for a while, I've found this answer and this code that provides a solution to this situation:
$args = array(
'post_type' => 'post',
'orderby' => 'meta_key',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key'=>'stickied',
'compare' => 'EXISTS'
),
array(
'key'=>'popularity',
'compare' => 'EXISTS'
)
),
'post_per_page'=>-1
);
$query = new WP_Query($args);
There are a number of ways to go about solving something like this. The real problem comes if/when you need to apply default pagination to the query.
The best way to handle this, and preserve the ability to paginate, would be to use a combination of meta_query clauses. Jack Johansson was on the right track, this just requires a bit more logic in the query. You may need to adjust the exact combination a bit to suit your needs, as this is just an estimated guess based on the info provided.
Try something like this:
$args = array(
'post_type' => 'post',
'meta_query' => array(
'relation' => 'OR',
'sticky_pop_clause' => array(
'relation' => 'AND',
'sp_sticky' => array(
'key' => 'stickied',
'compare' => 'EXISTS'
),
'sp_pop' => array(
'key' => 'popularity',
'compare' => 'EXISTS'
)
),
'sticky_clause' => array(
'key' => 'stickied',
'compare' => 'EXISTS'
),
'popular_clause' => array(
'key'=>'popularity',
'compare' => 'EXISTS'
),
'other_clause' => array(
'relation' => 'AND',
array(
'key'=>'stickied',
'compare' => 'NOT EXISTS'
),
array(
'key'=>'popularity',
'compare' => 'NOT EXISTS'
)
)
),
'orderby' => array(
'sp_pop' => 'DESC',
'sticky_clause' => 'ASC',
'popular_clause' => 'DESC',
'date' => 'DESC'
)
);
$query = new WP_Query($args);
You would need to check all (select) the posts with and without stickied
and popularity
with both EXISTS
and NOT EXISTS
. After that you sort it with orderby
.
Didn't test it. Modify it to your needs. I did smth similar. Results were okay.
$args = [
'meta_query' => [
'relation' => 'OR',
'with_stickied' => [
'key'=>'stickied',
'compare' => 'EXISTS'
],
'without_stickied' => [
'key'=>'stickied',
'compare' => 'NOT EXISTS'
],
'with_popularity' => [
'key'=>'popularity',
'compare' => 'EXISTS'
],
'with_popularity' => [
'key'=>'popularity',
'compare' => 'NOT EXISTS'
],
],
'orderby' => [
'with_stickied' => 'DESC',
'with_popularity' => 'DESC',
]
];
You might want to check "‘orderby’ with multiple ‘meta_key’s" from WP Codex.
本文标签:
版权声明:本文标题:wp query - How can I use order_by to order by two meta_keys without excluding posts that don't have those keys initializ 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742285080a2446784.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
INNER JOIN
between thewp_posts
andwp_postsmeta
tables where the IDs matchAND
themeta_key
exists. If youvar_export()
the query you can see it, and theorderby
applied at the end. I suppose you could force apopularity
and/orstickied
default value(s) at post creation though; a0
andfalse
, respectively. – hwl Commented Jul 18, 2017 at 3:21