Skip to content
Matt Boynes edited this page May 18, 2017 · 2 revisions

Faceted search (aggregations) is one of the most powerful features Elasticsearch brings to the table. SearchPress makes it relatively easy to add aggregations to your search queries and then collect the resulting data to use in your search UI.

Facets are defined with search args, and like many other customizations can be manipulated using the sp_search_wp_query_args filter. The arguments array takes a 'facets' key, which takes an array of facet options. The format is "label" => [ "type" => $type, "count" => ## ] and the type can be taxonomy, post_type, author, or date_histogram.

  • If taxonomy, you must also pass "taxonomy" => $taxonomy.
  • If date_histogram, you must also pass "interval" => $interval, where $interval is either "year", "month", or "day". You can also pass "field" to date histograms, specifying any date field (e.g. post_modified). Default is post_date.

Here are some examples:

add_filter( 'sp_search_wp_query_args', function( $wp_args ) {
	$wp_args['facets'] = [
		'Category' => [
			'type' => 'taxonomy',
			'taxonomy' => 'category',
			'count' => 10,
		],
		'Tag' => [
			'type' => 'taxonomy',
			'taxonomy' => 'post_tag',
			'count' => 10,
		],
		'Post Type' => [
			'type' => 'post_type',
			'count' => 10,
		],
		'Year' => [
			'type' => 'date_histogram',
			'interval' => 'year',
			'count' => 10,
		],
		'Author' => [
			'type' => 'author',
			'count' => 10,
		]
	];

	return $wp_args;
} );

Query Argument Detection

When you register a facet for the site search, SearchPress will automatically look for that facet's query args in the current request and add it to the search to filter the search results. In other words, if the current page's request is ?s=wordpress&category_name=tips-tricks, if the category taxonomy is registered as a facet, the search query will automatically recognize the tips-tricks category in the request and add it to the Elasticsearch query. If you didn't register the category taxonomy as a facet, it will be ignored in the Elasticsearch query.

Getting the Facet Results

After the search query runs, you can access the facet data by calling the get_facet_data() method on the SP_WP_Search object. If this is for an automatically-integrated site search, that search object is accessible via SP_Integration()->search_obj. For instance,

$facet_data = SP_Integration()->search_obj->get_facet_data();

This return an array of normalized data following the format:

[
	'Label' => [
		'type'     => [type requested],
		'count'    => [count requested],
		'taxonomy' => [taxonomy requested, if applicable],
		'interval' => [interval requested, if applicable],
		'field'    => [field requested, if applicable],
		'items'    => [
			[
				'query_vars' => [ [query_var] => [value] ],
				'name' => [formatted string for this facet],
				'count' => [number of results in this facet],
			],
		],
	],
]

Template Example

Let's look at example of using this data to create a list of links to category facets to narrow down the search results.

$facet_data = SP_Integration()->search_obj->get_facet_data();
if ( ! empty( $facet_data['Category']['items'] ) ) :
	foreach ( $facet_data['Category']['items'] as $cat ) :
		?>
		<li>
			<a href="<?php echo esc_url( add_query_arg( $cat['query_vars'] ) ) ?>">
				<?php echo esc_html( $cat['name'] ) ?>
				<span class="count">(<?php echo intval( $cat['count'] ) ?>)</span>
			</a>
		</li>
		<?php
	endforeach;
endif;

Hooks and Methods

Filters:

  • sp_search_facet_datum Override the default processing for an aggregation response.
    • false|array $datum If this is anything other than false, the facet datum will not be processed by SearchPress and it's value will be passed along as the $facet_data for that item (that is, appended to $facet_data[ $label ]['items']. While the values and format can be anything you'd like, to ensure compatiblity, it's best to maintain the form:

       [
       	'query_vars' => [ 'qv1' => 'value' ], // array of query vars
       	'name'       => $name,                // name to display
       	'count'      => $item['doc_count'],   // document count
       ]
    • array $item Individual bucket raw response from Elasticsearch (docs), an item from the array aggregations.{name}.buckets.

    • array $facets Registered facets in the search.

  • sp_search_facet_data
    • array $facet_data The facet data. This array is indexed by label, and each of those entries is an array with the original arguments used to register the facet as well as the processed facet results (in the items key). items is a collection of processed data (which can be overridden prior to processing using the sp_search_facet_datum as noted above).

Methods:

  • SP_WP_Search::get_facet_data() Returns the facet data (as filtered by sp_search_facet_data).
  • SP_WP_Search::get_results( 'facets' ) Gets the raw aggregation data from the Elasticsearch response. SP_WP_Search::get_facet_data() uses this method to get the data to process.