Refers only to FiboSearch Pro

How to change the order of search results?

FiboSearch calculates a score for every relevant product. The higher the score value, the higher the product will be in the search results. How FiboSearch calculate the score? Six main factors add a bonus to the score:

  1. Bonus for an exact match of product name
  2. Bonus for keywords position in product name
  3. Bonus for keywords position in product SKU
  4. Bonus for SKU exact match or containing the substring
  5. Bonus for an Attribute exact match or containing the substring
  6. Bonus for similarity between phrase and product name

Table of Contents

Custom weights and rules

You can add your own rules and demote products with “out of stock” status or promote products where the search phrase is the same as the custom field. We present few examples below.

Implementation (don’t skip it)

Below you will see examples of snippets. Some snippets must be running in special WordPress SHORTINIT mode and some as normal WordPress snippets e.g. in functions.php file. Look for information in the snippet comments.

The snippet includes [SHORTINIT MODE]:

Create a new empty file asfw-filters.php in the root directory of your child-theme and paste the snippet there

The snippet doesn’t include [SHORTINIT MODE]:

Apply it like a normal WordPress snippet e.g. in function.php in your child theme or via the CodeSnippet plugin.


[Example 1] Demoting “out of stock” products

In this example, we want to move products with “out of stock” status at the end of search results.

Step 1 – Save information about stock status in the search index

We have to save information about stock status in the search index for later use.

add_filter( 'dgwt/wcas/tnt/indexer/readable/product/data', function ( $data, $product_id, $product ) {

	if ( $product->getWooObject()->get_stock_status() === 'outofstock' ) {
		$data['meta']['out_of_stock'] = true;
	}

	return $data;
}, 10, 3 );

Step 2 – Rebuild the search index

Go to WooCommerce -> FiboSearch -> Indexer (tab), observe the status, and wait for finishing.

Step 3 – Deomote these products during a search

In step 1 we saved information in the search index about the stock status. Now we have to decrease the score for these products during a search.

<?php

// [SHORTINIT MODE] Run this snippet in the SHORTINIT mode (asfw-filters.php file). Take a look at the Implementation section above.

add_filter( 'dgwt/wcas/tnt/product/score', function ( $score, $product_id, $product ) {

	if ( ! empty( $product->meta['out_of_stock'] ) ) {
		$score -= 100;
	}

	return $score;

}, 10, 3 );

[Example 2] Increasing the weight of specific custom field

Let’s assume our products have a custom field “Year” with the key product_year. I someone type e.g. 2021, products with this year should get a bonus to the score. To achieve it follow these steps:

Step 1 – Save custom field values for later use

Add years to the database by following snippets. Add the following snippet to your functions.php file or use e.g. Code Snippet plugin. Replace book_author with your real taxonomy name.

add_filter( 'dgwt/wcas/tnt/indexer/readable/product/data', function ( $data, $product_id, $product ) {

	$value = $product->getCustomField( 'product_year' );

	if ( ! empty( $value ) ) {
		$data['meta']['product_year'] = $value;
	}
	return $data;
}, 10, 3 );

Step 2 – Rebuild the search index

Go to WooCommerce -> FiboSearch -> Indexer (tab), observe the status, and wait for finishing.

Step 3 – Add a bonus to the score

Now we have to increase the score for all products where search keywords are the same as the value of the custom field.

<?php

// [SHORTINIT MODE] Run this snippet in the SHORTINIT mode (asfw-filters.php file). Take a look at the Implementation section above.

add_filter( 'dgwt/wcas/tnt/product/score', function ( $score, $product_id, $product, $query ) {

	if ( ! empty( $product->meta['product_year'] ) ) {
		$field    = $product->meta['product_year'];
		$keywords = $query->breakIntoTokens( $query->getPhrase() );

		if ( ! empty( $keywords ) ) {
			foreach ( $keywords as $keyword ) {

				if ( ! empty( $keyword ) && $keyword === $field ) {
					$score += 50;
				}
			}
		}

	}

	return $score;

}, 10, 4 );

[Example 3] Promoting products assigned to a specific category

In this example, we want to promote all products assigned to a specific category.

Step 1 – Mark products that belong to a specific category

Every product from the category your-category-slug will have a meta field promote set to true in the search index.

add_filter( 'dgwt/wcas/tnt/indexer/readable/product/data', function ( $data, $product_id ) {

	$your_category_slug = 'your-category-slug'; // Replace with yours

	if(has_term($your_category_slug, 'product_cat', $product_id)){
		$data['meta']['promote'] = true;
	}

	return $data;
}, 10, 2 );

Step 2 – Rebuild the search index

Go to WooCommerce -> FiboSearch -> Indexer (tab), observe the status, and wait for finishing.

Step 3 – Promote these products during a search

In step 1 we saved information in the search index about promotion for products from a category your-category-slug. Now we have to increase the score for these products during searching.

<?php

// [SHORTINIT MODE] Run this snippet in the SHORTINIT mode (asfw-filters.php file). Take a look at the Implementation section above.

add_filter( 'dgwt/wcas/tnt/product/score', function ( $score, $product_id, $product ) {

	if ( ! empty( $product->meta['promote'] ) ) {
		$score += 100;
	}

	return $score;

}, 10, 3 );

[Example 4] Including menu_order in the search results order

Values of menu_order can affect the search results order by adding some snippets. The final score of every relevant product will be calculated including menu_order with a weight of 30%.

If you want to make menu_order a more important factor, increase its weight. Don’t overdo the weight of menu_order because there may be cases that the product with an exact match might be in the last place in the search results. Users will certainly be confused and disappointed because of this.

Step 1 – Calculate a menu order factor

add_filter( 'dgwt/wcas/tnt/indexer/readable/product/data', function ( $data, $product_id, $product ) {
	global $wpdb;

	$max        = absint($wpdb->get_var( "SELECT MAX(menu_order) FROM $wpdb->posts WHERE post_type = 'product'" ));
	$menu_order = $product->getWooObject()->get_menu_order();

	if ( empty( $max ) ) {
		$max = 1;
	}

	$factor_weight = 0.3;

	// 1 = the best
	// 0.7 = the worst
	$factor = 1 - ( $menu_order / $max * $factor_weight );

	$data['meta']['menu_order_factor'] = $factor;

	return $data;
}, 10, 3 );

Step 2 – Rebuild the search index

Go to WooCommerce -> FiboSearch -> Indexer (tab), observe the status, and wait for finishing.

Step 3 – Add a menu order factor as a part of the product score calculation

In step 1 we saved information about the menu order factor. Now we have to multiply the product score by this value.

<?php

// [SHORTINIT MODE] Run this snippet in the SHORTINIT mode (asfw-filters.php file). Take a look at the Implementation section above.

add_filter( 'dgwt/wcas/tnt/product/score', function ( $score, $product_id, $product ) {

	$factor = isset( $product->meta['menu_order_factor'] ) ? (float) $product->meta['menu_order_factor'] : 0;

	return $score * $factor;

}, 10, 3 );

In this example, we want to promote popular products in the search results. The scoring of each product is multiplied by the weight of WooCommerce total_sales field. The total_sales factor affects product score up to 30% of the origin score.

Let’s assume there are two relevant products with a score of 100. The first product has the lowest value of total_sales and the second product has the highest value. As a result, the first product will have 70 points and the second 100 points.

Step 1 – Calculate the total sales factor

add_filter( 'dgwt/wcas/tnt/indexer/readable/product/data', function ( $data, $product_id, $product ) {
	global $wpdb;

	$max        = absint($wpdb->get_var( "SELECT MAX(meta_value) FROM $wpdb->postmeta WHERE meta_key = 'total_sales'" ));
	$sales = $product->getWooObject()->get_total_sales();

	if ( empty( $max ) ) {
		$max = 1;
	}

	$factor_weight = 0.3;

	// 1 = the best
	// 0.7 = the worst
	$factor = 1 - ( (1 - ($sales / $max)) * $factor_weight );

	$data['meta']['total_sales_factor'] = $factor;

	return $data;
}, 10, 3 );

Step 2 – Rebuild the search index

Go to WooCommerce -> FiboSearch -> Indexer (tab), observe the status, and wait for finishing.

Step 3 – Add the total sales factor as a part of the product score calculation

In step 1 we saved information about the total_sales factor. Now we have to multiply the product score by this value.

// [SHORTINIT MODE] Run this snippet in the SHORTINIT mode (asfw-filters.php file). Take a look at the Implementation section above.

add_filter( 'dgwt/wcas/tnt/product/score', function ( $score, $product_id, $product ) {

	$factor = isset( $product->meta['total_sales_factor'] ) ? (float) $product->meta['total_sales_factor'] : 0;

	return $score * $factor;

}, 10, 3 );