WPクエリー順によるメタキーの自然なソート?
私はこのコードを持っています:
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_key' => 'custom key',
'orderby' => 'meta_value',
'order' => 'ASC',
'no_found_rows' => true,
'cache_results' => false,
'include_children' => false,
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($cat_id)
)
)
);
$loop = new WP_Query($args);
カスタムキーが似ているとき
FA3
FA1
FA10
wp query orderbyパラメータはこれを以下のようにソートします。
FA1
FA10
FA3
nsort-algoritmが欲しい時は
FA1
FA3
FA10
WP_Query
でこれを達成する方法はありますか? (または、配列を作成し、その配列をnsort()
でソートする唯一のオプションです。)
いいえ、まっすぐなWP_Queryとしてではありません。これはいくつかの要因によるものですが、主な要因は、mySQLが英数字列に対して自然なソートを行わないことです。
WordPressはorderbyパラメータに "meta_value_num"をサポートしています。これはソートを実行するために値をnumericにキャストするようにします。と数字、あなたはそれを使用することはできません。
posts_orderby
にフィルタを追加して、orderby句を直接書き換えて、好きなようにすることができます。データが常に "FA"で始まる場合は、フィルタに次のようなものを返させることができます。
LENGTH(meta_value) ASC, meta_value ASC
それは最初に長さによって、次に値によってソートします。短いアイテムが最初に来て、あなたに半自然な種類を与えます。
誰かがこれに遭遇した場合、私はあなたに解決策を与えるつもりです、それは「偽の自然なソート」(Ottoのおかげで)を使用します、しかしそれは複数のカスタムフィールドによるソートも持っています。
function orderbyreplace($orderby ) {
global $wpdb;
$new = str_replace($wpdb->prefix.'postmeta.meta_value ASC', 'LENGTH(mt1.meta_value) ASC, mt1.meta_value ASC, mt2.meta_value ASC', $orderby);
return $new;
}
function get_posts_by_tax_cat($taxonomy, $parent_cat_id) {
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_key' => 'flansoppning',
'meta_query' => array(
array(
'key' => 'flansoppning',
'value' => '',
'compare' => 'LIKE'
),
array(
'key' => 'gangstorlek_mm',
'value' => '',
'compare' => 'LIKE'
)
),
'no_found_rows' => true,
'cache_results' => false,
'include_children' => false,
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($parent_cat_id)
)
)
);
//Filter makes it possible to sort on flansoppning (length() gives natural sort) first and then gangstorlek_mm
add_filter('posts_orderby','orderbyreplace');
$loop = new WP_Query( $args );
remove_filter('posts_orderby','orderbyreplace');
$posts = $loop->posts;
if(!empty($posts)) {
return $posts;
}
return array();
}
Ottoの答えを補完するために、製品のpost_typeのみのクエリを変更する必要がある場合は、次の手順を試してください。
add_filter( 'posts_orderby', 'modify_posts_orderby', 10, 2 );
function modify_posts_orderby( $orderby_statement, $wp_query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $orderby_statement;
}
// only modify queries for 'product' post type
if( $wp_query->get( 'post_type' ) === 'product' ) {
$orderby_statement = "LENGTH(meta_value) DESC, meta_value DESC";
}
return $orderby_statement;
}