web-dev-qa-db-fra.com

meta_query: utiliser BETWEEN avec des flotteurs et/ou transtyper vers DECIMAL

Chaque post a une valeur lat/lng qui lui est attachée via postmeta. J'essaie de saisir tous les messages dans une valeur limite lat/lng. Voici la requête 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',
        ),
    ),
));

Etant donné que les valeurs postmeta sont stockées sous forme de chaînes, je me suis dit que je devrais transtyper en DECIMAL, mais cela semble simplement couper la valeur décimale de la chaîne en raison de l'absence de DECIMAL paramètres/paramètres de précision.

J'ai remarqué que la requête traitait les flottants dans le tableau value comme des chaînes, ce qui pourrait également être un autre point d'échec. L'exécution de la requête compilée sans les guillemets autour de chaque valeur flottante fonctionne comme prévu.

Je vais utiliser get_permalink() sur chaque poste. Je peux exécuter une requête personnalisée en dehors de get_posts (via $wpdb->get_results()) pour saisir correctement les publications dans le cadre de sélection, puis parcourir les publications et get_permalink, mais une requête de base de données supplémentaire est envoyée par publication pour créer le lien permanent, ce qui n'est pas un idéal. Solution!

Des idées?

5
Kevin

Vous pouvez filtrer le SQL généré et ajouter les paramètres de précision dont vous avez besoin.

Activez les filtres pour get_posts() en ajoutant ce qui suit à la requête:

'suppress_filters' => false,

Et:

add_filter('posts_where','cast_decimal_precision');

function cast_decimal_precision( $where ) {

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

Mettre à jour

Avec la suggestion de 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

A partir de 3.8 ( voir piste ), la précision peut être ajoutée au type de transtypage de la manière suivante:

$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