8
votes

This question seems to be unanswered on the internet, perhaps because it is not possible. I simply want to query all posts where the repeater field 'has rows'. i.e.

$args = array(
'meta_query'        => array(
'relation' => 'AND',
    array(
        'key'       => 'repeater_field',
        'value'     => '',
        'compare'   => '=!'
    )
);

I know an alternative is to run if statements inside the loop to filter them out, but that messes with some other logic which is based off of the number of posts in the query.

Does anyone have any thoughts on this?

3
Are you querying the posts that only have this specific repeater field?Alex Rindone
That's what I am trying to achieve, yes. Query all posts that have a value in 'repeater_field'.Nick
If you use the above query, the key is the name of your repeater field like this '_repeater_field_name' and your value will be the actual key like 'field_534eeaaa74199'. It will always have field_ and then the numbers and letters.Alex Rindone
Unfortunately that doesn't work Alex, have tried many different variations of 'compare' as well (exists, =, LIKE, !=, not exists etc - nothing having an impact)Nick

3 Answers

8
votes

Let's consider you have a Repeater Field labeled My Repeater Field and this repeater contains at least one field labeled A Field on the Repeater.

Assuming you have the default wp_ table prefix, you need to look at the DB's wp_postmeta table to notice that values for this field on the repeater are stored with the meta_key:

NAME_OF_THE_REPEATER_index_NAME_OF_FIELD_ON_THE_REPEATER

So, in our case, if a post has 3 rows on the repeater field, its values will be stored as:

my_repeater_field_0_a_field_on_the_repeater
my_repeater_field_1_a_field_on_the_repeater
my_repeater_field_2_a_field_on_the_repeater

Knowing this, if you want to query all posts having at least ONE row on the repeater, you could do:

$meta_query = [
    [
        'key'     => 'my_repeater_field_0_a_field_on_the_repeater',
        'compare' => 'EXISTS',
    ]
];

$args = [
    'posts_per_page'   => -1,
    'orderby'          => 'date',
    'order'            => 'DESC',
    'meta_query'       => $meta_query,
    'post_type'        => 'post',
    'post_status'      => 'publish',
];

$posts_array = get_posts( $args );

Note: As stated on WP Docs, you can only use the EXISTS comparison on WP >= 3.5 and you don't need to specify a value when using the 'EXISTS' or 'NOT EXISTS' comparisons in WordPress 3.9 and up. I'm also assuming you are using PHP >= 5.4 so you can use short array syntax. If not, just replace [] for array().

1
votes

You can query the wordpress database using the $wpdb object. ACF fields are saved in prod_postmeta on the database so that is where you will run your query. Your meta_value will be the key of your repeater field, so make sure you replace that in the query below. All keys for any ACF field with start out with field_ and then random characters/digits will follow like seen below. Then once you have the post id, you can run get_post() on those post ids. Let me know if you need anything else or have questions.

global $wpdb;
$results = $wpdb->get_results("SELECT post_id from prod_postmeta WHERE meta_value = 'field_534eeaaa74199'");
$echo $results;
0
votes

This works. I have test it. Only by the "Welcome World" post it doesn't work.

$args = array(
    'post_type'=> 'post', 
    'posts_per_page' => -1,
    'meta_query'        => array(
        'relation' => 'AND',
        array(
            'key'       => 'repeater_field',
            'value'     => '0',
            'compare'   => '!='
        )
));
$the_query = new WP_Query( $args );

The "repeater_field" is the name of the field, not the field_key. Here is the count of the rows.