web-dev-qa-db-ja.com

meta_query:BETWEENをフロートとともに使用する、またはDECIMALにキャストする

各投稿には、postmetaによってlat/lng値が添付されています。境界緯度/経度の値内ですべての投稿を取得しようとしています。これがget_postsクエリです。

$posts = get_posts(array(
    'posts_per_page' => 100,
    'post_type' => 'place',
    'post_status' => 'publish',
    'meta_query' => array(
        array(
            'key' => 'places_lat',
            'value' => array($lat_min, $lat_max),
            'compare' => 'BETWEEN',
            //'type' => 'DECIMAL',
        ),
        array(
            'key' => 'places_lng',
            'value' => array($lng_min, $lng_max),
            'compare' => 'BETWEEN',
            //'type' => 'DECIMAL',
        ),
    ),
));

ポストメタ値は文字列として格納されるので、DECIMALにキャストする必要があると考えましたが、DECIMAL引数/精度パラメータがないため、文字列から10進値を切り捨てるようです。

私は、クエリがvalue配列内のfloatを文字列として扱うことに気付きました。これもまた失敗の原因となる可能性があります。各浮動小数点値を引用符なしでコンパイルしたクエリを実行しても、期待通りに動作します。

各投稿でget_permalink()を使用します。 get_postsの外側で($wpdb->get_results()を介して)カスタムクエリを実行してバウンディングボックス内の投稿を適切に取得し、投稿とget_permalinkをループ処理することはできますが、最終的にはパーマリンクを構築するために投稿ごとに追加のデータベースクエリを起動します溶液!

何か案は?

5
Kevin

生成されたSQLをフィルタ処理し、必要な精度パラメータを追加できます。

Queryに以下を追加してget_posts()のフィルタを有効にします。

'suppress_filters' => false,

そして:

add_filter('posts_where','cast_decimal_precision');

function cast_decimal_precision( $where ) {

    return str_replace('DECIMAL','DECIMAL(10,3)',$where);
}

アップデート

Janの提案では:

add_filter('get_meta_sql','cast_decimal_precision');

function cast_decimal_precision( $array ) {

    $array['where'] = str_replace('DECIMAL','DECIMAL(10,3)',$array['where']);

    return $array;
}
8
Rarst

3.8以降( track を参照)、精度はキャストタイプに次のように追加できます。

$posts = get_posts(array(
    'posts_per_page' => 100,
    'post_type' => 'place',
    'post_status' => 'publish',
    'meta_query' => array(
        array(
            'key' => 'places_lat',
            'value' => array($lat_min, $lat_max),
            'compare' => 'BETWEEN',
            'type' => 'DECIMAL(10,3)',
        ),
        array(
            'key' => 'places_lng',
            'value' => array($lng_min, $lng_max),
            'compare' => 'BETWEEN',
            'type' => 'DECIMAL(10,3)',
        ),
    ),
));
0
SwitzerBaden