• moultrex

    (@moultrex)


    Hello.

    We use advanced custom fields and we have 2 fields inside every post.

    min_number and max_number custom fields.

    So for example. Post-1 has min_number:100 and max_number:150, Post-2 has min_number:200 and max_number:250 as custom fields.

    We index these fields with relevanssi but we want to somehow hook to the search engine and when the user searches for 130, Post-1 will return, if he searches 238, Post-2 will return.

    This is by checking to see if the search number value is between min_number and max_number range.

    We have a draft of the custom php function that we want to use but we do not know what hook to use it with relevanssi.

    The function will be something like

    function getPostbyRange($inputNumber, $postsArray) {
        $result = [];
    
        foreach ($postsArray as $post) {
            $min_num = $acf['min_number'];
            $max_num = $acf['max_number'];
    
            if ($inputNumber >= $min_num && $inputNumber <= $max_num) {
                $result[] = $post;
            }
        }
    
        return $result;
    }

    Thank you.

Viewing 1 replies (of 1 total)
  • Plugin Author Mikko Saari

    (@msaari)

    Two options here: either you can filter this before the search or after the search.

    If you do it before the search, you create a meta_query out of it:

    add_filter( 'relevanssi_modify_wp_query', function( $query ) {
      if ( is_numeric( $query->query_vars['s'] ) ) {
        $input      = intval( $query->query_vars['s'] );
        $meta_query = array(
          array(
            'key' => 'min_number',
            'value' => $input,
            'compare' => '>=',
            'type' => 'numeric',
          ),
          array(
            'key' => 'max_number',
            'value' => $input,
            'compare' => '<=',
            'type' => 'numeric',
          ),
          'relation' => 'AND',
        ); 
        $query->set( 'meta_query', $meta_query );
      }
      return $query; 
    } );

    The other way is to filter the results like this:

    add_filter( 'relevanssi_hits_filter', function( $hits, $query ) {
      if ( is_numeric( $query->query_vars['s'] ) ) {
        $input = intval( $query->query_vars['s'] );
        $in_range = array();
        foreach ( $hits[0] => $hit ) {
          $min_number = get_post_meta( $hit->ID, 'min_number', true );
          if ( $input < $min_number ) {
            continue;
          }
          $min_number = get_post_meta( $hit->ID, 'max_number', true );
          if ( $input > $max_number ) {
            continue;
          }
          $in_range[] = $hit;
        }
        $hits[0] = $in_range;
      }
      return $hits;
    }, 10, 2 );

    Using meta_query can be slow – it’s usually the slowest filtering method you can use – but the second method causes a lot of extra database queries (for each get_post_meta(), which is why you first check the minimum and only check the maximum when necessary), so your mileage may vary. You can check which method is faster.

Viewing 1 replies (of 1 total)
  • The topic ‘Manipulate Search’ is closed to new replies.