it-swarm.com.de

meta_query: Verwendung von BETWEEN mit Floats und/oder Casting nach DECIMAL

Jedem Post ist ein Lat/Lng-Wert per Postmeta zugeordnet. Ich versuche, alle Posts innerhalb eines begrenzten Lat/Lng-Werts zu erfassen. Hier ist die get_posts Abfrage:

$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',
        ),
    ),
));

Da Postmeta-Werte als Zeichenfolgen gespeichert werden, dachte ich, ich sollte auf DECIMAL umwandeln, aber es scheint nur, als würde der Dezimalwert aus der Zeichenfolge abgeschnitten, da DECIMAL Argumente/Genauigkeitsparameter fehlen.

Mir ist aufgefallen, dass die Abfrage die Floats innerhalb des Arrays value als Zeichenfolgen behandelt, was auch eine andere Fehlerquelle sein kann. Das Ausführen der kompilierten Abfrage ohne die Anführungszeichen um jeden gleitenden Wert funktioniert wie erwartet.

Ich werde get_permalink() für jeden Beitrag verwenden. Ich kann eine benutzerdefinierte Abfrage außerhalb von get_posts ausführen (über $wpdb->get_results()), um die Beiträge innerhalb des Begrenzungsrahmens ordnungsgemäß zu erfassen, dann die Beiträge und den get_permalink zu durchlaufen. Am Ende wird jedoch eine zusätzliche Datenbankabfrage pro Beitrag ausgelöst, um den Permalink zu erstellen - kein Ideal Lösung!

Irgendwelche Ideen?

5
Kevin

Sie können generiertes SQL filtern und benötigte Präzisionsparameter hinzufügen.

Aktivieren Sie die Filter für get_posts(), indem Sie Folgendes zur Abfrage hinzufügen:

'suppress_filters' => false,

Und:

add_filter('posts_where','cast_decimal_precision');

function cast_decimal_precision( $where ) {

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

Update

Mit Jan's Vorschlag:

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

Ab 3.8 ( siehe Track ) kann die Präzision wie folgt zum Cast-Typ hinzugefügt werden:

$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