Complex custom_field search with meta_query Complex custom_field search with meta_query wordpress wordpress

Complex custom_field search with meta_query


I've been there... trying to put all in one complex meta query. At the end you need to manually process the generated SQL - moving brackets, replacing operators, quotes, etc.

At the end the query is so complex and have multiple JOINS to the postmeta table it becomes too expensive and slow.

I've chosen to achieve this by choosing slightly different approach.So, what you can do is divide the query to several sub-queries and combine them later with post__in and post__not_in,

For Example for Problem part 1:

/* Filter by class */$history_students_ids = get_posts(array(    'post_type'      => 'student',    'fields'         => 'ids',    'posts_per_page' => -1,    'meta_query'     => array(        array(            'key'=>'attendance_%_class',            'compare'=>'=',            'value'=>'History 101'        ),    )));/* Filter by date */$students = get_posts(array(    'post_type' => 'student',    'post__in' => $history_students_ids,    'meta_query' => array(        array(            'key'=>'attendance_%_date',            'compare'=>'>=',            'value'=>'20170101'        )    )));

The same goes for Problem part 2

$not_attended_history_students_ids = get_posts(array(    'post_type' => 'student',    'post__in' => $history_students_ids,    'fields'         => 'ids',    'posts_per_page' => -1,    'meta_query' => array(        array(            'key'=>'attendance_%_date',            'compare'=>'NOT EXISTS'        )    )));$students = get_posts(array(    'post_type' => 'student',    'post__in' => $not_attended_history_students_ids,    'meta_query' => array(        array(            'key'=>'attendance_%_date',            'compare'=>'>=',            'value'=>'20170101'        )    ))); 

You can reverse attendance condition to be EXISTS and use post__not_in... I hope you have managed to understand the idea.