Elasticpress: Ignore certain posts when indexing

Created on 28 Apr 2015  Â·  7Comments  Â·  Source: 10up/ElasticPress

Just starting a discussion here.

Our site has a lot of private pages that we don't want to show up in the SERP, but we don't set these to private status in WP because we often direct non-users to them. I'm thinking a per-post meta-box that includes an option to exclude the post from the ES index.

Is this a potential for core EP? Or would it be better suited for a plugin. Anyone have additional thoughts?

question

Most helpful comment

You are correct. That filter would work on the initial index.
You would probably want to tap into the 'ep_post_sync_kill' filter as well; which would stop a post from indexing on create/update:

function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
    if ( 37 == $post_id ) {
        return true;
    }
    return $return_val;
}

add_filter( 'ep_post_sync_kill',  'my_ep_stop_sync', 10, 3 );
  • Where 37 is the post ID you wish to not index.

One idea: you could implement a custom field on the post to toggle whether or not the post should be indexed on ElasticSearch like so:

/**
 * Filters WP_Query arguments for initial ElasticPress indexing.
 * Searches for posts with 'do_not_index' and adds those post IDs to 'posts__not_in' argument.
 * @param array $args
 * @return array
 */
function my_ep_filter( $args ) {
    $query   = new WP_Query( array( 'meta_key' => 'do_not_index', 'meta_value' => 'true', 'fields' => 'ids' ) );
    $exclude = array();
    if ( 0 != $query->post_count ) {
        $args[ 'post__not_in' ] = $query->posts;
    }
    return $args;
}

add_filter( 'ep_index_posts_args', 'my_ep_filter' );

/**
 * Filter to determine if a post should not be indexed.
 * @param bool $return_val Default is false.
 * @param array $post_args
 * @param int $post_id
 * @return boolean
 */
function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
    $to_index    = get_post_meta( $post_id, 'do_not_index', true );
    $to_index    = filter_var( $to_index, FILTER_VALIDATE_BOOLEAN );
    if ( false === boolval( $to_index ) ) {
        return false;
    }
    /**
     * OPTIONAL: Delete the post from the index...
     */
    if ( function_exists( 'ep_delete_post' ) ) {
        ep_delete_post( $post_id );
    }

    return true;
}

add_filter( 'ep_post_sync_kill', 'my_ep_stop_sync', 10, 3 );

Please let me know if that resolves your issue.

-Allan

All 7 comments

Hello,
You can accomplish this with a plugin using the 'ep_index_posts_args' filter by setting the 'post__not_in' argument.

For example:

function my_ep_filter( $args ) {
    $args[ 'post__not_in' ] = array( 13, 28, 14 );
    return $args;
}

add_filter( 'ep_index_posts_args', 'my_ep_filter' );

Hope this helps.

-Allan

Thanks for that. Wouldn't this just ingore the posts only on initial indexing? (Not on post create/update?)

You are correct. That filter would work on the initial index.
You would probably want to tap into the 'ep_post_sync_kill' filter as well; which would stop a post from indexing on create/update:

function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
    if ( 37 == $post_id ) {
        return true;
    }
    return $return_val;
}

add_filter( 'ep_post_sync_kill',  'my_ep_stop_sync', 10, 3 );
  • Where 37 is the post ID you wish to not index.

One idea: you could implement a custom field on the post to toggle whether or not the post should be indexed on ElasticSearch like so:

/**
 * Filters WP_Query arguments for initial ElasticPress indexing.
 * Searches for posts with 'do_not_index' and adds those post IDs to 'posts__not_in' argument.
 * @param array $args
 * @return array
 */
function my_ep_filter( $args ) {
    $query   = new WP_Query( array( 'meta_key' => 'do_not_index', 'meta_value' => 'true', 'fields' => 'ids' ) );
    $exclude = array();
    if ( 0 != $query->post_count ) {
        $args[ 'post__not_in' ] = $query->posts;
    }
    return $args;
}

add_filter( 'ep_index_posts_args', 'my_ep_filter' );

/**
 * Filter to determine if a post should not be indexed.
 * @param bool $return_val Default is false.
 * @param array $post_args
 * @param int $post_id
 * @return boolean
 */
function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
    $to_index    = get_post_meta( $post_id, 'do_not_index', true );
    $to_index    = filter_var( $to_index, FILTER_VALIDATE_BOOLEAN );
    if ( false === boolval( $to_index ) ) {
        return false;
    }
    /**
     * OPTIONAL: Delete the post from the index...
     */
    if ( function_exists( 'ep_delete_post' ) ) {
        ep_delete_post( $post_id );
    }

    return true;
}

add_filter( 'ep_post_sync_kill', 'my_ep_stop_sync', 10, 3 );

Please let me know if that resolves your issue.

-Allan

Looks great to me. My initial question was whether something like this
should be part of the core plugin. I appreciate your work! I will test it
out and let you know how that goes. Thanks!

On Mon, May 4, 2015 at 4:11 PM, Allan Collins [email protected]
wrote:

You are correct. That filter would work on the initial index.
You would probably want to tap into the 'ep_post_sync_kill' filter as
well; which would stop a post from indexing on create/update:

function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
if ( 37 == $post_id ) {
return true;
}
return $return_val;
}

add_filter( 'ep_post_sync_kill', 'my_ep_stop_sync', 10, 3 );

  • Where 37 is the post ID you wish to not index.

One idea: you could implement a custom field on the post to toggle whether
or not the post should be indexed on ElasticSearch like so:

/**

  • Filters WP_Query arguments for initial ElasticPress indexing.
  • Searches for posts with 'do_not_index' and adds those post IDs to 'posts__not_in' argument.
  • @param array $args
  • @return array
    */
    function my_ep_filter( $args ) {
    $query = new WP_Query( array( 'meta_key' => 'do_not_index', 'meta_value' => 'true', 'fields' => 'ids' ) );
    $exclude = array();
    if ( 0 != $query->post_count ) {
    $args[ 'post__not_in' ] = $query->posts;
    }
    return $args;
    }

add_filter( 'ep_index_posts_args', 'my_ep_filter' );

/**

  • Filter to determine if a post should not be indexed.
  • @param bool $return_val Default is false.
  • @param array $post_args
  • @param int $post_id
  • @return boolean
    _/
    function my_ep_stop_sync( $return_val, $post_args, $post_id ) {
    $to_index = get_post_meta( $post_id, 'do_not_index', true );
    $to_index = filter_var( $to_index, FILTER_VALIDATE_BOOLEAN );
    if ( false === boolval( $to_index ) ) {
    return false;
    }
    /_*

    • OPTIONAL: Delete the post from the index...

      */

      if ( function_exists( 'ep_delete_post' ) ) {

      ep_delete_post( $post_id );

      }

return true;
}

add_filter( 'ep_post_sync_kill', 'my_ep_stop_sync', 10, 3 );

Please let me know if that resolves your issue.

-Allan

—
Reply to this email directly or view it on GitHub
https://github.com/10up/ElasticPress/issues/253#issuecomment-98881570.

I personally think the filters provided are sufficient. Happy to discuss further.

I'm having trouble with the my_ep_stop_sync function. I've provided a true/false custom field which returns a boolean, however, when updating the post, I'm redirected to wp-admin/post.php with a blank white screen, regardless of the value of the custom field.

I think a better solution for my case is to just use pre_get_posts to not exclude posts with the assigned custom field.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

emmerich picture emmerich  Â·  8Comments

brunocrosier picture brunocrosier  Â·  3Comments

mbanusic picture mbanusic  Â·  3Comments

blindpet picture blindpet  Â·  7Comments

JJJ picture JJJ  Â·  5Comments