WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#33988 closed enhancement (fixed)

New param for search in WP Query

Reported by: sebastian.pisula Owned by: boonebgorges
Milestone: 4.4 Priority: normal
Severity: normal Version:
Component: Query Keywords: has-patch
Focuses: Cc:

Description

s => search post with phrase
without_s => without phrase

For example:

  1. I want find movies without phrase "blood" in title or content. (without_s => blood)
  2. I wand find movies with phrase "tiger" and without "die" in title or content. (without_s => die, s => tiger)

I think that good idea is, if param "s" will be have support for array. For example:

I can find post with words s = array('tiger', 'lion', 'dog')

Attachments (2)

33988.patch (2.0 KB) - added by akibjorklund 4 years ago.
33988.diff (3.7 KB) - added by boonebgorges 4 years ago.

Download all attachments as: .zip

Change History (13)

#1 follow-up: @boonebgorges
4 years ago

  • Milestone changed from Awaiting Review to Future Release

I think that good idea is, if param "s" will be have support for array.

Use search_terms. get_posts( array( 'search_terms' => array( 'tiger', 'lion', 'dog' ) ) )

I like the idea of NOT LIKE searches, but I wonder if we can come up with a more elegant syntax than 'without_s'. For example, we have 'search_terms'; maybe we could add something like 'search_terms__not_in'. Or maybe we could add boolean operators to the search, so that 'search_terms' => array( '-tiger', 'lion' ) will match posts *with* 'lion' but *without* 'tiger'. See https://support.google.com/websearch/answer/2466433?hl=en for a list of what Google supports.

Last edited 4 years ago by DrewAPicture (previous) (diff)

#2 in reply to: ↑ 1 @DrewAPicture
4 years ago

Replying to boonebgorges:

I think that good idea is, if param "s" will be have support for array.

Use search_terms. get_posts( array( 'search_terms' => array( 'tiger', 'lion', 'dog' ) ) )

I like the idea of NOT LIKE searches, but I wonder if we can come up with a more elegant syntax than 'without_s'. For example, we have 'search_terms'; maybe we could add something like 'search_terms__not_in'. Or maybe we could add boolean operators to the search, so that 'search_terms' => array( '-tiger', 'lion' ) will match posts *with* 'lion' but *without* 'tiger'. See https://support.google.com/websearch/answer/2466433?hl=en for a list of what Google supports.

What about search_terms_exclude as an argument name? I also like the boolean operator approach, especially since it's already in use other places in core. The latter seems like a more-elegant approach.

#3 @boonebgorges
4 years ago

  • Keywords needs-patch needs-unit-tests added

@akibjorklund
4 years ago

#4 @akibjorklund
4 years ago

  • Keywords has-patch added; needs-patch removed

Terms that begin with a dash made most sense to me too.

I've attached a patch that implements this functionality as a first draft of what it might look like.

#5 @boonebgorges
4 years ago

So, it turns out that search_terms is listed in the docs, but doesn't actually work. WP_Query does pass around an internal tool called search_terms, but it can't be configured by parameter.

@boonebgorges
4 years ago

#6 @boonebgorges
4 years ago

  • Keywords needs-unit-tests removed
  • Milestone changed from Future Release to 4.4

Thanks, akibjorklund! Looks like it ended up being easier than I thought it'd be. 33988.diff cleans up the first part of your patch, and adds a unit test.

I think that your changes in parse_search_order() aren't quite right. parse_search_order() converts s to a couple of ORDER BY clauses: one for an exact match in the title, a few for combinations of single words in the title, and one for an exact match in the content. We don't want any exact matches, though. If you search foo -bar baz, you don't want to match a post that contains the sentence foo -bar baz. And you also don't want to match a post that has foo baz, which is what your patch will do. I think the right answer in these cases is to skip the sentence matches, but to keep the single word matches (negative terms already having been filtered out by this point). Does this seem right to others?

This is a neat little improvement. Let's try to do it for 4.4.

#7 @akibjorklund
4 years ago

Thanks for the feedback @boonebgorges! Your version looks good to me.

Only one small thought: If we skip the sentence match in ordering, then search results with negative terms will have different sorting. Consider first querying for foo bar and then altering that to filter out baz: foo bar -baz – now we present the results quite possibly in different order and also not in the best possible order of relevance – intuitively at the very least. But most likely the issue I described is so minor that it is not worth looking into.

#8 @boonebgorges
4 years ago

Only one small thought: If we skip the sentence match in ordering, then search results with negative terms will have different sorting. Consider first querying for foo bar and then altering that to filter out baz: foo bar -baz – now we present the results quite possibly in different order and also not in the best possible order of relevance – intuitively at the very least. But most likely the issue I described is so minor that it is not worth looking into.

Hrm. Yeah, I agree it's slightly strange. But at the same time, I think it makes sense that the NOT operator would sorta override the rest of the query. It doesn't seem obvious to me what the expected behavior in this case *ought* to be. So I think that what's in the patch is probably as good as anything.

#9 @boonebgorges
4 years ago

  • Owner set to boonebgorges
  • Resolution set to fixed
  • Status changed from new to closed

In 34934:

Allow excluded keywords when searching posts.

Pass a keyword with a leading hyphen to exclude posts containing that keyword.
For example, 'taco -onions' will return posts that contain the word 'taco' but
do not contain the word 'onions'.

Props akibjorklund.
Fixes #33988.

#10 follow-up: @GaryJ
4 years ago

Fantastic improvement folks.

Is a unit test needed to clarify behaviour when the search field only contains negated terms? i.e.

  • -foo
  • -foo -bar

#11 in reply to: ↑ 10 @boonebgorges
4 years ago

Replying to GaryJ:

Fantastic improvement folks.

Is a unit test needed to clarify behaviour when the search field only contains negated terms? i.e.

  • -foo
  • -foo -bar

I don't know that it's needed, but if you wrote these tests, I would add them :)

Note: See TracTickets for help on using tickets.