Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#54853 new defect (bug)

Search only searching phrases and not searching individual terms

Reported by: jchang's profile jchang Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.8.3
Component: Query Keywords: needs-patch
Focuses: Cc:

Description

get_posts(array(
  "post_type" => "fruit",
  "s" => "apple orange banana"
));

should search for each term separately, but it does not. It searches the entire string as a phrase.

Issue is within /wp-includes/class-wp-query.php line 1398. It's a simple change:

$searchand = ' AND ';
to
$searchand = ' OR ';

Change History (4)

#1 in reply to: ↑ description @parinpanjari
2 years ago

The function we check that we are NOT viewing the admin area, that we ARE constructing the main query and that we ARE making a search.

add_filter('posts_search', 'my_search_is_exact', 20, 2);
function my_search_is_exact($search, $wp_query){

global $wpdb;

if(empty($search))

return $search;

$q = $wp_query->query_vars;
$n = !empty($qexact?) ? : '%';

$search = $searchand = ;

foreach((array)$qsearch_terms? as $term) :

$term = esc_sql(like_escape($term));

$search.= "{$searchand}($wpdb->posts.post_title REGEXP ':<:?{$term}:>:?') OR ($wpdb->posts.post_content REGEXP ':<:?{$term}:>:?')";

$searchand = ' AND ';

endforeach;

if(!empty($search)) :

$search = " AND ({$search}) ";
if(!is_user_logged_in())

$search .= " AND ($wpdb->posts.post_password = ) ";

endif;

return $search;

}

Version 0, edited 2 years ago by parinpanjari (next)

#2 follow-up: @SergeyBiryukov
2 years ago

  • Severity changed from blocker to normal

Hi there, welcome to WordPress Trac! Thanks for the ticket.

get_posts(array(
  "post_type" => "fruit",
  "s" => "apple orange banana"
));

should search for each term separately, but it does not. It searches the entire string as a phrase.

Just noting that the search ordering logic is slightly more advanced.

Some history here:

  • [4426] / #3177 (WordPress 2.1+) allowed "quoted strings" to be used in searches for exact matches.
  • [25632] / #7394 (WordPress 3.7+) orders search results by relevance, rather than by date.

The ordering logic is as follows:

  • Full sentence matches in post titles.
  • All search terms in post titles.
  • Any search terms in post titles.
  • Full sentence matches in post content.

Each section and any remaining posts are then sorted by date.

Additionally, WP_Query::parse_query() has a 'sentence' argument that controls whether to search by phrase.

So it seems to me that the default search behavior works as intended and documented, I don't see a bug here. As noted above, this can be customized using the posts_search or posts_search_orderby filters.

Last edited 2 years ago by SergeyBiryukov (previous) (diff)

#3 @thelovekesh
2 years ago

Implemented logic seems nice to me. If you keep $searchand = ' OR ' then it will lookup according to the words for each search statement. In many scenarios, a post title can be passed to search, and you don't want to see results based on words at that time.

#4 in reply to: ↑ 2 @jchang
2 years ago

Replying to SergeyBiryukov:

Hi there, welcome to WordPress Trac! Thanks for the ticket.

get_posts(array(
  "post_type" => "fruit",
  "s" => "apple orange banana"
));

should search for each term separately, but it does not. It searches the entire string as a phrase.

Just noting that the search ordering logic is slightly more advanced.

Some history here:

  • [4426] / #3177 (WordPress 2.1+) allowed "quoted strings" to be used in searches for exact matches.
  • [25632] / #7394 (WordPress 3.7+) orders search results by relevance, rather than by date.

The ordering logic is as follows:

  • Full sentence matches in post titles.
  • All search terms in post titles.
  • Any search terms in post titles.
  • Full sentence matches in post content.

Each section and any remaining posts are then sorted by date.

Additionally, WP_Query::parse_query() has a 'sentence' argument that controls whether to search by phrase.

So it seems to me that the default search behavior works as intended and documented, I don't see a bug here. As noted above, this can be customized using the posts_search or posts_search_orderby filters.

If left as it is, the "sentence" argument would have no effect on the outcome of a search. The documented behavior says it should search each term individually unless "sentence" is set to true (defaults to false).

Note: See TracTickets for help on using tickets.