Skip to content

Commit

Permalink
Merge pull request #2857 from rebeccahum/add/weighting_change_disable…
Browse files Browse the repository at this point in the history
…_weighting_filter

Weighting: Add ep_enable_do_weighting to check for request type and re-factor with apply_weighting() into do_weighting()
  • Loading branch information
felipeelia committed Jun 30, 2022
2 parents 395cd18 + 9834b62 commit ad3a7a2
Showing 1 changed file with 102 additions and 73 deletions.
175 changes: 102 additions & 73 deletions includes/classes/Feature/Search/Weighting.php
Original file line number Diff line number Diff line change
Expand Up @@ -585,98 +585,127 @@ public function do_weighting( $formatted_args, $args ) {
* @hook ep_weighting_configuration_for_search
* @param {array} $weight_config Current weight config
* @param {array} $args WP Query arguments
* @return {array} New configutation
* @return {array} New configuration
*/
$weight_config = apply_filters( 'ep_weighting_configuration_for_search', $weight_config, $args );

if ( Utils\is_integrated_request( 'weighting', [ 'public', 'rest' ] ) && ! empty( $args['s'] ) ) {
/*
* This section splits up the single query clause for all post types into separate nested clauses (one for each post type)
* which then get combined into one result set. By having separate clauses for each post type, we can then
* weight fields such as post_title per post type so that we can have fine grained control over weights by post
* type, rather than globally on the query
*/
$new_query = [
'bool' => [
'should' => [],
],
];
$should_do_weighting = Utils\is_integrated_request( 'weighting', [ 'public', 'rest' ] ) && ! empty( $args['s'] );

// grab the query and keep track of whether or not it is nested in a function score
$function_score = isset( $formatted_args['query']['function_score'] );
$query = $function_score ? $formatted_args['query']['function_score']['query'] : $formatted_args['query'];
/**
* Filter whether to enable weighting configuration
*
* @hook ep_enable_do_weighting
* @since 4.3.0
* @param {bool} Whether to enable weight config, defaults to true for search requests that are public or REST
* @param {array} $weight_config Current weight config
* @param {array} $args WP Query arguments
* @param {array} $formatted_args Formatted ES arguments
* @return {bool} Whether to use weighting configuration
*/
if ( apply_filters( 'ep_enable_do_weighting', $should_do_weighting, $weight_config, $args, $formatted_args ) ) {
$formatted_args = $this->apply_weighting( $formatted_args, $args, $weight_config );
}

foreach ( (array) $args['post_type'] as $post_type ) {
if ( false === $this->post_type_has_fields( $post_type, $args ) ) {
continue;
}
// Copy the query, so we can set specific weight values
$current_query = $query;
return $formatted_args;
}

if ( isset( $weight_config[ $post_type ] ) ) {
// Find all "fields" values and inject weights for the current post type
$this->recursively_inject_weights_to_fields( $current_query, $weight_config[ $post_type ] );
} else {
// Use the default values for the post type
$this->recursively_inject_weights_to_fields( $current_query, $this->get_post_type_default_settings( $post_type ) );
}
/**
* Applies weighting based on ES args
*
* @since 4.3.0
* @param array $formatted_args Formatted ES args
* @param array $args WP_Query args
* @param array $weight_config Weight configuration to apply
*
* @return array $formatted_args Formatted ES args with weightings applied
*/
protected function apply_weighting( $formatted_args, $args, $weight_config ) {
/*
* This section splits up the single query clause for all post types into separate nested clauses (one for each post type)
* which then get combined into one result set. By having separate clauses for each post type, we can then
* weight fields such as post_title per post type so that we can have fine grained control over weights by post
* type, rather than globally on the query
*/
$new_query = [
'bool' => [
'should' => [],
],
];

// Check for any segments with null fields from recursively_inject function and remove them
if ( isset( $current_query['bool'] ) && isset( $current_query['bool']['should'] ) ) {
foreach ( $current_query['bool']['should'] as $index => $current_bool_should ) {
if ( isset( $current_bool_should['multi_match'] ) && null === $current_bool_should['multi_match'] ) {
unset( $current_query['bool']['should'][ $index ] );
}
}
}
// grab the query and keep track of whether or not it is nested in a function score
$function_score = isset( $formatted_args['query']['function_score'] );
$query = $function_score ? $formatted_args['query']['function_score']['query'] : $formatted_args['query'];

/**
* Filter weighting query for a post type
*
* @hook ep_weighted_query_for_post_type
* @param {array} $query Weighting query
* @param {string} $post_type Post type
* @param {array} $args WP Query arguments
* @return {array} New query
*/
$new_query['bool']['should'][] = apply_filters(
'ep_weighted_query_for_post_type',
[
'bool' => [
'must' => [
$current_query,
],
'filter' => [
[
'match' => [
'post_type.raw' => $post_type,
],
],
],
],
],
$post_type,
$args
);
foreach ( (array) $args['post_type'] as $post_type ) {
if ( false === $this->post_type_has_fields( $post_type, $args ) ) {
continue;
}
// Copy the query, so we can set specific weight values
$current_query = $query;

// put the new query back in the correct location
if ( $function_score ) {
$formatted_args['query']['function_score']['query'] = $new_query;
if ( isset( $weight_config[ $post_type ] ) ) {
// Find all "fields" values and inject weights for the current post type
$this->recursively_inject_weights_to_fields( $current_query, $weight_config[ $post_type ] );
} else {
$formatted_args['query'] = $new_query;
// Use the default values for the post type
$this->recursively_inject_weights_to_fields( $current_query, $this->get_post_type_default_settings( $post_type ) );
}

// Check for any segments with null fields from recursively_inject function and remove them
if ( isset( $current_query['bool'] ) && isset( $current_query['bool']['should'] ) ) {
foreach ( $current_query['bool']['should'] as $index => $current_bool_should ) {
if ( isset( $current_bool_should['multi_match'] ) && null === $current_bool_should['multi_match'] ) {
unset( $current_query['bool']['should'][ $index ] );
}
}
}

/**
* Hook after weighting is added to Elasticsearch query
* Filter weighting query for a post type
*
* @hook ep_weighting_added
* @param {array} $formatted_args Elasticsearch query
* @hook ep_weighted_query_for_post_type
* @param {array} $query Weighting query
* @param {string} $post_type Post type
* @param {array} $args WP Query arguments
* @return {array} New query
*/
do_action( 'ep_weighting_added', $formatted_args, $args );
$new_query['bool']['should'][] = apply_filters(
'ep_weighted_query_for_post_type',
[
'bool' => [
'must' => [
$current_query,
],
'filter' => [
[
'match' => [
'post_type.raw' => $post_type,
],
],
],
],
],
$post_type,
$args
);
}

// put the new query back in the correct location
if ( $function_score ) {
$formatted_args['query']['function_score']['query'] = $new_query;
} else {
$formatted_args['query'] = $new_query;
}

/**
* Hook after weighting is added to Elasticsearch query
*
* @hook ep_weighting_added
* @param {array} $formatted_args Elasticsearch query
* @param {array} $args WP Query arguments
*/
do_action( 'ep_weighting_added', $formatted_args, $args );

return $formatted_args;
}

Expand Down

0 comments on commit ad3a7a2

Please sign in to comment.