Make WordPress Core

Changeset 59034


Ignore:
Timestamp:
09/17/2024 09:56:18 PM (2 weeks ago)
Author:
flixos90
Message:

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.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r58783 r59034  
    336336                $args['post__not_in'] = array_merge( $args['post__not_in'], $sticky_posts );
    337337            }
     338        }
     339
     340        if (
     341            isset( $registered['search_semantics'], $request['search_semantics'] )
     342            && 'exact' === $request['search_semantics']
     343        ) {
     344            $args['exact'] = true;
    338345        }
    339346
     
    28872894        }
    28882895
     2896        $query_params['search_semantics'] = array(
     2897            'description' => __( 'How to interpret the search input.' ),
     2898            'type'        => 'string',
     2899            'enum'        => array( 'exact' ),
     2900        );
     2901
    28892902        $query_params['offset'] = array(
    28902903            'description' => __( 'Offset the result set by a specific number of items.' ),
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r58612 r59034  
    230230                'search',
    231231                'search_columns',
     232                'search_semantics',
    232233                'slug',
    233234                'status',
  • trunk/tests/phpunit/tests/rest-api/rest-pages-controller.php

    r58326 r59034  
    8686                'search',
    8787                'search_columns',
     88                'search_semantics',
    8889                'slug',
    8990                'status',
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r58326 r59034  
    207207                'search',
    208208                'search_columns',
     209                'search_semantics',
    209210                'slug',
    210211                'status',
     
    764765            $this->assertNotEquals( $draft_id, $post['id'] );
    765766        }
     767    }
     768
     769    /**
     770     * @ticket 56350
     771     *
     772     * @dataProvider data_get_items_exact_search
     773     *
     774     * @param string $search_term  The search term.
     775     * @param bool   $exact_search Whether the search is an exact or general search.
     776     * @param int    $expected     The expected number of matching posts.
     777     */
     778    public function test_get_items_exact_search( $search_term, $exact_search, $expected ) {
     779        self::factory()->post->create(
     780            array(
     781                'post_title'   => 'Rye',
     782                'post_content' => 'This is a post about Rye Bread',
     783            )
     784        );
     785
     786        self::factory()->post->create(
     787            array(
     788                'post_title'   => 'Types of Bread',
     789                'post_content' => 'Types of bread are White and Rye Bread',
     790            )
     791        );
     792
     793        $request           = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     794        $request['search'] = $search_term;
     795        if ( $exact_search ) {
     796            $request['search_semantics'] = 'exact';
     797        }
     798        $response = rest_get_server()->dispatch( $request );
     799        $this->assertCount( $expected, $response->get_data() );
     800    }
     801
     802    /**
     803     * Data provider for test_get_items_exact_search().
     804     *
     805     * @return array[]
     806     */
     807    public function data_get_items_exact_search() {
     808        return array(
     809            'general search, one exact match and one partial match' => array(
     810                'search_term'  => 'Rye',
     811                'exact_search' => false,
     812                'expected'     => 2,
     813            ),
     814            'exact search, one exact match and one partial match' => array(
     815                'search_term'  => 'Rye',
     816                'exact_search' => true,
     817                'expected'     => 1,
     818            ),
     819            'exact search, no match and one partial match' => array(
     820                'search_term'  => 'Rye Bread',
     821                'exact_search' => true,
     822                'expected'     => 0,
     823            ),
     824        );
    766825    }
    767826
  • trunk/tests/qunit/fixtures/wp-api-generated.js

    r59032 r59034  
    363363                            "required": false
    364364                        },
     365                        "search_semantics": {
     366                            "description": "How to interpret the search input.",
     367                            "type": "string",
     368                            "enum": [
     369                                "exact"
     370                            ],
     371                            "required": false
     372                        },
    365373                        "offset": {
    366374                            "description": "Offset the result set by a specific number of items.",
     
    17201728                            "required": false
    17211729                        },
     1730                        "search_semantics": {
     1731                            "description": "How to interpret the search input.",
     1732                            "type": "string",
     1733                            "enum": [
     1734                                "exact"
     1735                            ],
     1736                            "required": false
     1737                        },
    17221738                        "offset": {
    17231739                            "description": "Offset the result set by a specific number of items.",
     
    28192835                            },
    28202836                            "default": [],
     2837                            "required": false
     2838                        },
     2839                        "search_semantics": {
     2840                            "description": "How to interpret the search input.",
     2841                            "type": "string",
     2842                            "enum": [
     2843                                "exact"
     2844                            ],
    28212845                            "required": false
    28222846                        },
     
    35723596                            "required": false
    35733597                        },
     3598                        "search_semantics": {
     3599                            "description": "How to interpret the search input.",
     3600                            "type": "string",
     3601                            "enum": [
     3602                                "exact"
     3603                            ],
     3604                            "required": false
     3605                        },
    35743606                        "offset": {
    35753607                            "description": "Offset the result set by a specific number of items.",
     
    43834415                            "required": false
    43844416                        },
     4417                        "search_semantics": {
     4418                            "description": "How to interpret the search input.",
     4419                            "type": "string",
     4420                            "enum": [
     4421                                "exact"
     4422                            ],
     4423                            "required": false
     4424                        },
    43854425                        "offset": {
    43864426                            "description": "Offset the result set by a specific number of items.",
     
    69967036                            "required": false
    69977037                        },
     7038                        "search_semantics": {
     7039                            "description": "How to interpret the search input.",
     7040                            "type": "string",
     7041                            "enum": [
     7042                                "exact"
     7043                            ],
     7044                            "required": false
     7045                        },
    69987046                        "offset": {
    69997047                            "description": "Offset the result set by a specific number of items.",
     
    78137861                            "required": false
    78147862                        },
     7863                        "search_semantics": {
     7864                            "description": "How to interpret the search input.",
     7865                            "type": "string",
     7866                            "enum": [
     7867                                "exact"
     7868                            ],
     7869                            "required": false
     7870                        },
    78157871                        "offset": {
    78167872                            "description": "Offset the result set by a specific number of items.",
     
    80168072                            },
    80178073                            "default": [],
     8074                            "required": false
     8075                        },
     8076                        "search_semantics": {
     8077                            "description": "How to interpret the search input.",
     8078                            "type": "string",
     8079                            "enum": [
     8080                                "exact"
     8081                            ],
    80188082                            "required": false
    80198083                        },
Note: See TracChangeset for help on using the changeset viewer.