How do I add advanced custom fields / meta fields to Elasticsearch?

I am using the plugin ElasticPress. I’d like it to index some extra (advanced custom) fields. The only info I can find is this comment by one of the developers:

[…]if you would like to add additional fields that are not already being
brought over (ElasticPress natively brings over any non-protected,
i.e. non underscore prefixed meta fields) you simply need to filter
the ep_post_sync_args filter and add them yourself.

I augmented my code as per ialocin’s instructions. Now the standard fields get indexed, no error messages, but the custom fields still do not appear in the ElasticSearch index.

function update_ep_sync_args( $post_args, $post_id ) {
$oldPreparedMeta = $post_args[ 'post_meta' ];
$additionalPreparedMeta = array();
$post = get_post( $post_id );
if( have_rows('content',$post->ID) ):
 // loop through the rows of data
while ( have_rows('content',$post->ID) ) : the_row();
    // BODY TEXT
    if( get_row_layout() == 'text' ):
        $additionalPreparedMeta['text'] = get_sub_field('text') . ' ';
    elseif( get_row_layout() == 'subHeading' ):
        $text = get_sub_field('text');
        $additionalPreparedMeta['text'] = $text . ' ';
$newPreparedMeta = array_merge( $oldPreparedMeta, $additionalPreparedMeta );
$post_args[ 'post_meta' ] = $newPreparedMeta;
return $post_args;
add_filter( 'ep_post_sync_args', 'update_ep_sync_args', 10, 2 );

This issue on gitHub references ep_config_mapping. Do I need to do something with that as well?

Can anyone with more experience with ElasticPress point me in the right direction?


ialocin’s instructions are, in fact, correct. This is the way to add stuff to the search index. My problem lies elsewhere.

Solutions Collecting From Web of "How do I add advanced custom fields / meta fields to Elasticsearch?"

Lets break this down, Advanced Custom Fields (ACF) does save the data as custom field/post meta, I guess it seems all to obvious, but it is better to confirm it, and ElasticPress does set up custom fields automatically to include them into the search index. ElasticPress does this unless the meta data is hidden, which is the case if the custom field name is prefixed by an underscore – _.

As it is the case, that is just what ACF does, it prefixes its fields with _ making them hidden. Explained e.g. at the documentation page for update_field(), shortly summarized you read there the field_key is _ + field_name. Actually it does not or at least not for all. Not sure what the reason is, because I can’t take a look at the set-up. Anyway, the meta data gets correctly indexed, but the search doesn’t work, which will be resolved in another – link is following – question. All this is still apllying to adding additional, not automatically indexed, search data, like hidden custom fields.

In reverse having the consequence that ACF fields are not being indexed by ElasticPress. As we can see if taking a look at the EP_API class. The post meta does get included to the index like this:

'post_meta' => $this->prepare_meta( $post ),

So we take a closer look at the prepare_meta() method, where we see:

if ( ! is_protected_meta( $key ) ) {
  $prepared_meta[$key] = maybe_unserialize( $value );

Which confirms the suspected circumstance.

You have found the right place/hook to add the data nonetheless, being the ep_post_sync_args filter. But you did not do it correctly, especially, you are trying to append a string to an array – see above code block and source. (Note: If you had debugging enabled you would have been bugged about doing something wrong.) This won’t work of course, you need to add to the $prepared_meta array. I don’t know that much about ACF, so I leave that part out, but if you know how to get the data, then below exemplary code should make it pretty obvious to you, how to add the extra fields to the search index.

add_filter( 'ep_post_sync_args', 'wpse194785_ep_post_sync_args', 10, 2 );  
function wpse194785_ep_post_sync_args( $post_args, $post_id ) {
  $old_prepared_meta = $post_args[ 'post_meta' ];
  $additional_prepared_meta = array();
  // code to get up additional meta
  // set up data like this:
  // $additional_prepared_meta[ $key ] = array( $value );
  // note that the value is enclosed into an array
  // you can add one or multiple new elements by key => value association to the array
  // afterwards merge new and old data
  $new_prepared_meta = array_merge( $old_prepared_meta, $additional_prepared_meta );
  $post_args[ 'post_meta' ] = $new_prepared_meta;
  return $post_args;