phpwordpress

Wordpress meta_query OR/AND relations not working


I have a search form with multiple options that are taxonomies. When I select all options, or just one, and click search it never returns any record. I have a problem with understanding relations, and how to properly set arrays.

$args = array('post_type' => array( 'property' ),
    'order'             =>  'DESC',
    'orderby'           =>  'post_date',
    'meta_query' => array(
        'relation' => 'AND',
         array(
             array(
                 'key'       => 'property_address_postal_code',
                 'value'     => $search,
                 'compare'   => 'LIKE',
             ),
             array(
                 'key'       => 'property_address_state',
                 'value'     => $search,
                 'compare'   => 'LIKE',
             ),
             array(
                'key'       => 'property_location',
                'value'     => $search,
                'compare'   => 'LIKE',
            ),
        ),
        array(
            'relation' => 'OR',
            array(
                'relation' => 'AND',
                array(
                    'key'       => 'property_price',
                    'value'     => array($_GET['min-price'],$_GET['max-price']),
                    'type'    => 'numeric',
                    'compare'   => 'BETWEEN',
                ),
            ),
            array(
                'relation' => 'AND',
                array(
                    'key'       => 'property_price',
                    'value'     => array($_GET['min-price'],$_GET['max-price']),
                    'type'    => 'numeric',
                    'compare'   => 'BETWEEN',
                ),
            ),
        )
    )
);

Solution

  • First off, I'm not sure if you're quite understanding how the relation property applies in this function. It applies AND/OR to other properties on the same level. So your very first relation => AND makes sure your $search variable matches one of the properties you specify AND that the property_price is between the min and max values.

    Secondly, with subsequent, nested meta queries, the default relation is AND, so when you try to match $search against different properties, you're actually trying to make sure that $search is matching ALL of the properties you specify. You can fix that by trying to match $search against one property OR another property.

    Thirdly, with your comparison of the price against the min and max price, the meta query is malformed, and both of those meta queries are identical. In that case, you don't need a relation since you only have to check against one value.

    You can simplify your code as such:

    $args = array('post_type' => array( 'property' ),
        'order'             =>  'DESC',
        'orderby'           =>  'post_date',
        'meta_query' => array(
            'relation' => 'AND',
             array(
                 'relation' => 'OR',
                 array(
                     'key'       => 'property_address_postal_code',
                     'value'     => $search,
                     'compare'   => 'LIKE',
                 ),
                 array(
                     'key'       => 'property_address_state',
                     'value'     => $search,
                     'compare'   => 'LIKE',
                 ),
                 array(
                    'key'       => 'property_location',
                    'value'     => $search,
                    'compare'   => 'LIKE',
                ),
            ),
            array(
                'key'       => 'property_price',
                'value'     => array($_GET['min-price'],$_GET['max-price']),
                'type'      => 'numeric',
                'compare'   => 'BETWEEN',
            )
        )
    );
    

    Now, you're making a query that checks if $search is like property_address_potal_code OR like property_address_state OR like property_location AND property_price is between the min and max price.

    You might still have to fiddle with it a bit depending on other logic in your code, but I think this should get you going in the right direction.