Posted on

Indexing product codes with and without spaces

A Relevanssi Premium customer had a problem with product codes. The codes are in the format “ABC 100”, a group of letters and digits with a space in between. Users may search for the codes without the space, so the post should be found with “ABC 100” or “ABC100”.

The product codes don’t appear in a specific custom field but in the post titles and content. Thus the solution is to check both of those, and whenever something is found that matches the product code pattern, that string is indexed as is, but also with the space removed.

The code is relatively straightforward and uses the relevanssi_post_content and relevanssi_post_title_before_tokenize filter hooks:

add_filter( 'relevanssi_post_content', 'rlv_product_codes' );
add_filter( 'relevanssi_post_title_before_tokenize', 'rlv_product_codes' );
/**
 * Index product codes in the format "ABC 123" ie. group of letters,
 * a space, group of digits both ways, with or without the space, so
 * that the product can be found with either "ABC 123" or "ABC123" search
 * terms. This is applied to post content and titles.
 *
 * @param string $content The content to manipulate.
 *
 * @return string The content with the spaceless product codes added.
 */
function rlv_product_codes( $content ) {
	$pattern = '/(\w+) (\d+)/'; // Adjust pattern here if necessary.
	$hits    = preg_match_all( $pattern, $content, $matches );
	if ( $hits > 0 ) {
		$results  = array_map( function( $string ) { return str_replace( ' ', '', $string ); }, $matches[0] );
		$content .= ' ' . implode( ' ', $results );
	}
	return $content;
}

Add the code to your site and then rebuild the index to implement this.

WooCommerce SKUs

If the product codes are WooCommerce SKUs, the function is more straightforward.

add_filter( 'relevanssi_custom_field_value', function( $value, $field ) {
    if ( '_sku' === $field ) {
        $no_spaces = str_replace( ' ', '', $value );
        $value    .= " $no_spaces";
    }
    return $value;
}, 10, 2 );

This function indexes all SKUs with and without spaces. You don’t have to specify the structure of the SKU: if it’s “ABC 100”, it will be indexed as “ABC 100 ABC100”, and if it’s “PL ENV B 23”, it will be indexed as “PL ENV B 23 PLENVB23”.

8 comments Indexing product codes with and without spaces

  1. Can this code be edited to work for product titles? For example when I search for “8320 P” I get the correct set of results, however, if I search for “8320P” I get zero results.

    Any suggestions/help is greatly appreciated.

    1. No need for editing for that, it already works for titles (and post content). However, the code is currently looking for product codes that are in the format “(some letters) (some numbers)”, when you need it to be the other way around.

      Change the pattern $pattern = '/(\w+) (\d+)/'; to $pattern = '/(\d+) (\w+)/';.

      1. So I implemented this code, and it has fixed my issue of finding a product with the title containing “4 oz” when typing “4oz”, but now when I type “4 oz” it doesn’t return any results.

        1. Matthew, “4 oz” is simply not searchable with Relevanssi default settings, because the minimum word length is three characters. Add also this:

          add_filter( 'relevanssi_remove_punctuation', function( $a ) {
          $a = preg_replace( '/(\d+) oz/', '$1oz', $a );
          return $a;
          } );

          This finds all cases of numbers followed by a space and “oz” and removes the space. This is applied to the post content and the user search terms, so if someone searches for “4 oz” it becomes “4oz” automatically.

          1. I noticed the advanced tab after writing and was able to fix it by setting the minimum word length to two. Thank you for your help!

Leave a Reply

Are you a Relevanssi Premium customer looking for support? Please use the Premium support form.

Your email address will not be published. Required fields are marked *