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”.
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.
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+)/';
.Thank you so much! Works perfectly!
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.
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.
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!
Will this work for Free version?
Yes, this works the same in the free version.
Dear Mikko,
I tried to use the code above modified like this:
<?php
add_filter( 'relevanssi_custom_field_value', function( $value, $field ) {
if ( '_sku' === $field ) {
$result = number_format($value, 0, ',', ' ');
$value .= " $result";
}
return $value;
}, 10, 2 );
My plan was to add SKUs with spaces. It is not working and I don't know why. The indexing is not tarting when this code is active.
My other plan was to check if the searched text contains only numbers and spaces then I would delete spaces and the searched text will match my SKUs in database without spaces. I couldn't find a solution for that also. Do You think there is a quick solution for oane of the way searching, please.
Thank You, Andrew
Andrew, if the indexing doesn’t work, that suggests there’s an error in the code. It seems fine to me, but check the server PHP error log to see if there’s something, like nasty invisible characters.
You can modify the search terms with
relevanssi_modify_wp_query
(see documentation). The search terms are in$query->query_vars['s']
, you can modify that.