Make WordPress Core

Opened 2 years ago

Closed 3 weeks ago

Last modified 3 weeks ago

#56350 closed enhancement (fixed)

Allow exact search in REST API

Reported by: jimmyh61's profile jimmyh61 Owned by: flixos90's profile flixos90
Milestone: 6.7 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: good-first-bug has-patch has-unit-tests has-testing-info
Focuses: rest-api, performance Cc:

Description

Wordpress only allows full text search when using the REST API but doesn't allow exact search. Yet, the exact search is possible using a search query like:

http://website.com/?s=keyword&exact=1

When you have tens of thousands of posts, being forced to do a full text search can take several seconds and impacts the performance of the website.

It would be an improvement to allow exact search in the WP_REST_Posts_Controller in order to allow REST API requests like:

http://website.com/wp-json/wp/v2/posts?s=keyword&exact=1

Attachments (5)

56350.diff (977 bytes) - added by jimmyh61 2 years ago.
Add exact search to REST API
56350.tests.diff (2.3 KB) - added by johnregan3 2 years ago.
Same patch with Tests added.
56350.tests.improved.diff (2.6 KB) - added by johnregan3 2 years ago.
Improved testing.
56350-fix.diff (7.9 KB) - added by mehulkaklotar 23 months ago.
contains fixes for the tests failing
56350-latest.diff (7.9 KB) - added by mehulkaklotar 23 months ago.
latest changes

Download all attachments as: .zip

Change History (24)

#1 @TimothyBlynJacobs
2 years ago

  • Keywords good-first-bug added
  • Milestone changed from Awaiting Review to Future Release
  • Version changed from trunk to 4.7

Welcome to Trac @jimmyh61!

This seems sensible to me. Instead of just exact, I think we'd want to be a bit more specific, either exact_search or search_exact.

Do you want to work on a patch for thisr issue?

@jimmyh61
2 years ago

Add exact search to REST API

#2 @jimmyh61
2 years ago

Hi @TimothyBlynJacobs,

I created a patch and used the term exact_search like you suggested.

#3 @TimothyBlynJacobs
2 years ago

  • Keywords has-patch needs-unit-tests added

This looks good @jimmyh61! Are you interested in working on unit tests for this issue?

#4 @jimmyh61
2 years ago

@TimothyBlynJacobs,

I'm not familiar with unit tests. Can somebody else work on that?

#5 @ironprogrammer
2 years ago

  • Keywords needs-testing needs-testing-info added

@johnregan3
2 years ago

Same patch with Tests added.

#6 @johnregan3
2 years ago

  • Keywords needs-unit-tests removed

@ironprogrammer Tests Added.

@johnregan3
2 years ago

Improved testing.

#7 @ironprogrammer
2 years ago

  • Keywords has-unit-tests added

Great collaboration, @jimmyh61 and @johnregan3!

@johnregan3, would you be able to add "optional" $message params to the assertions in 56350.tests.improved.diff?

Why? Because the test contains multiple assertions, it's ideal for error messages to indicate why a particular assertion failed.

I'm not certain the third assertion is required, since that seems more like a test that $request didn't reset, which isn't the class under test in this context.

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

#8 @ironprogrammer
2 years ago

  • Keywords has-testing-info added; needs-testing-info removed

Test Report

This combined test report includes testing instructions and enhancement patch test results.

Patch tested: https://core.trac.wordpress.org/attachment/ticket/56350/56350.diff

LGTM 👍🏻 When it lands, it will need needs-user-docs.

Steps to Test

(Exact post content is at tester's discretion; samples provided are from the unit test. Just ensure that each post's title is unique and that there is a shared keyword between the content.)

  1. Create and publish a new post with title "Rye", and content "This is a post about Rye Bread".
  2. Create and publish a second post with title "Types of Bread", and content "Types of bread are White and Rye Bread". Note that the keyword "rye" is shared between the two posts.
  3. Regression Test: In a browser load the following URL: <your site>/wp-json/wp/v2/posts?search=rye

(The REST API search parameter corresponds to the WP_Query s parameter.)

  1. ✅ The JSON results should contain at least two (2) results, more if you have other posts containing "rye" (a JSON viewer extension may be helpful to view the results here).
  2. Enhancement Test: In a browser load the following URL: <your site>/wp-json/wp/v2/posts?search=rye&exact_search=true

(The patch's exact_search REST API parameter corresponds to the WP_Query exact parameter.)

  1. ✅ The exact search JSON results should contain just one (1) result: the "Rye" post.

Expected Results

  • ✅ Querying the API without the new API parameter should return all posts containing the search keyword.
  • ✅ Querying the API with exact_search should only return the post name matching the search keyword.

Environment

  • OS: macOS 12.5
  • Browser: Safari 15.6
  • Browser: Google Chrome 104.0.5112.79
  • Server: nginx/1.23.1
  • PHP: 7.4.30
  • WordPress: 6.1-alpha-53344-src

Actual Results

After applying patch...

  • ✅ Querying the API without the new API parameter returned all posts containing the search keyword.
  • ✅ Querying the API with exact_search only returned the post name matching the search keyword.

#9 @jimmyh61
2 years ago

Great collaboration!
I reproduced the steps to test and got the same results. Everything seems to work as expected.

#10 @mehulkaklotar
23 months ago

I have replicated the steps and got the correct results every time. Looks good on my end too. There were tests errors in the commit though.

I have pushed fixed changes in the PR now to test it with different versions of PHP.

Last edited 23 months ago by mehulkaklotar (previous) (diff)

@mehulkaklotar
23 months ago

contains fixes for the tests failing

@mukesh27 commented on PR #3677:


23 months ago
#12

@ironprogrammer @TimothyBJacobs What is your thoughts on https://github.com/WordPress/wordpress-develop/pull/3677#discussion_r1032178888?

@mehulkaklotar
23 months ago

latest changes

#13 @flixos90
3 weeks ago

  • Keywords needs-testing removed
  • Milestone changed from Future Release to 6.7
  • Owner set to flixos90
  • Status changed from new to reviewing

The PR looks good to me, and we already have test coverage as well as did testing. I just refreshed the patch on GitHub, and there's a test failure, but it looks like something we should be able to quickly fix.

Once that's done, I'd say this can be committed.

@TimothyBlynJacobs commented on PR #3677:


3 weeks ago
#14

Hm, though looking at this, if we do want to add sentence support, we probably want to change this to be something like search_semantics as an enum of either exact or sentence? So you could do search_semantics=exact,sentence?

@flixos90 commented on PR #3677:


3 weeks ago
#15

@TimothyBJacobs At this point, we'd probably only support the exact value though, right (as for this PR)? I'm okay choosing a future compatible path here, that said we could also go with the current pragmatic approach and if we want to support more later change it (e.g. deprecate the current one). What do you think?

@TimothyBlynJacobs commented on PR #3677:


3 weeks ago
#16

Yeah, I don't think this is _bad_ as is. A search_semantics style parameter is more forward compatible. I don't think we've officially deprecated any actual query parameters yet. But I don't think a search_exact and search_sentence is the worst thing.

#18 @flixos90
3 weeks ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 59034:

REST API: Support exact search in the REST API posts endpoint.

This changeset adds support for a new search_semantics enum query parameter that can be passed alongside the search string parameter. At this point, it only supports "exact" as possible value, but an enum is used for forward compatibility with potential enhancements like "sentence" search support. If search_semantics=exact is passed, it will look for an exact match rather than do a full text search, which for some use-cases is more appropriate and more performant.

Props mehulkaklotar, timothyblynjacobs, jimmyh61, ironprogrammer, johnregan3, mukesh27, costdev.
Fixes #56350.

Note: See TracTickets for help on using tickets.