Kuinka toteuttaa custom search-ratkaisu WordPressiin

WordPressin oletushaku toimii pienissä sivustoissa riittävän hyvin, mutta kun sisältöä, tuotteita tai taksonomioita alkaa olla paljon...
WordPressin oletushaku toimii pienissä sivustoissa riittävän hyvin, mutta kun sisältöä, tuotteita tai taksonomioita alkaa olla paljon, siitä tulee nopeasti hidas, epätarkka ja vaikeasti hallittava.
Custom search -ratkaisu tarkoittaa käytännössä sitä, että korvataan tai ohitetaan WP_Query-pohjainen perushaku omalla logiikalla, joka on optimoitu juuri kyseisen sivuston datamallille.
Miksi WordPressin oletushaku ei skaalaudu hyvin
Oletushaku:
- tekee raskaita
LIKE '%term%'-kyselyjä - skannaa
wp_postsjawp_postmeta-tauluja - ei ole semanttinen
- ei priorisoi tuloksia järkevästi
- ei hyödynnä erillistä hakemistoa
Suurissa sivustoissa tämä johtaa:
- hitaisiin queryihin
- korkeaan DB-kuormaan
- epätarkkoihin tuloksiin
- huonoon käyttäjäkokemukseen
Custom searchin arkkitehtuurivaihtoehdot
WordPressissä custom search voidaan toteuttaa usealla tasolla:
1. WP_Query optimointi (kevyt ratkaisu)
2. erillinen hakutaulu (medium skaalautuvuus)
3. full-text index MySQL:ssä
4. ulkoinen search engine (paras skaalautuvuus)
- Elasticsearch
- Meilisearch
- Algolia
- Typesense
WP_Query-pohjainen custom search
Perusoptimoitu versio:
$args = [
'post_type' => 'post',
's' => $search_term,
'posts_per_page' => 20,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false
];
$query = new WP_Query($args);
Tärkeimmät optimoinnit:
no_found_rowsvähentää COUNT-queryä- meta cache pois päältä
- term cache pois päältä
Search queryn korvaaminen kokonaan
WordPressin oletushaku voidaan ohjata uudelleen:
add_action('pre_get_posts', function($query) {
if (!is_admin() && $query->is_search()) {
$query->set('posts_per_page', 20);
$query->set('no_found_rows', true);
}
});
Tämä on hyvä “first step”, mutta ei vielä custom search.
Custom search query builder
Parempi lähestymistapa on rakentaa oma query-logiikka.
Esimerkki:
function my_custom_search($term) {
global $wpdb;
$term = '%' . $wpdb->esc_like($term) . '%';
return $wpdb->get_results($wpdb->prepare("
SELECT ID, post_title
FROM {$wpdb->posts}
WHERE post_status = 'publish'
AND post_title LIKE %s
LIMIT 20
", $term));
}
Tämä ohittaa WP_Queryn kokonaan.
Full-text search MySQL:ssä
Parempi suorituskyky kuin LIKE-haulla.
Indeksin luonti:
ALTER TABLE wp_posts
ADD FULLTEXT(post_title, post_content);
Haku:
$results = $wpdb->get_results($wpdb->prepare("
SELECT ID, post_title,
MATCH(post_title, post_content) AGAINST (%s IN NATURAL LANGUAGE MODE) AS score
FROM {$wpdb->posts}
WHERE MATCH(post_title, post_content) AGAINST (%s IN NATURAL LANGUAGE MODE)
ORDER BY score DESC
LIMIT 20
", $term, $term));
Hyödyt:
- nopeampi kuin LIKE
- relevanssipohjainen järjestys
- skaalautuu paremmin
Hakutulosten priorisointi
Custom searchissä tärkeää on relevanssi:
Esimerkki painotuksesta:
- otsikko = 5x paino
- excerpt = 3x paino
- content = 1x paino
Tämä voidaan tehdä SQL-scorella tai PHP-rankingilla.
REST API -pohjainen search
Moderni WordPress-tapa:
add_action('rest_api_init', function() {
register_rest_route('search/v1', '/items', [
'methods' => 'GET',
'callback' => 'my_search_endpoint'
]);
});
function my_search_endpoint($request) {
$term = $request->get_param('q');
return my_custom_search($term);
}
Tämä mahdollistaa:
- frontendin eriyttämisen
- AJAX search
- headless käytön
Debounce ja frontend optimointi
Hakua ei pidä lähettää jokaisella näppäimellä ilman rajoitusta.
let timeout;
input.addEventListener('input', function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
fetch('/wp-json/search/v1/items?q=' + this.value);
}, 300);
});
Cache custom search
Hakutulokset voidaan cachettaa transientteihin:
$key = 'search_' . md5($term);
$results = get_transient($key);
if (!$results) {
$results = my_custom_search($term);
set_transient($key, $results, HOUR_IN_SECONDS);
}
Redis + search cache
Redis tekee search-cachesta erittäin nopean:
- lähes muistinopeus
- ei DB-kuormaa
- hyvä high-traffic sivustoille
Elasticsearch / Meilisearch integraatio
Suurissa järjestelmissä paras ratkaisu:
Hyödyt:
- lähes reaaliaikainen haku
- relevanssialgoritmit
- typo tolerance
- faceted search
- erittäin nopea
WordPress toimii tällöin vain datalähteenä.
Search index rakentaminen
Tyypillinen pipeline:
- post save hook
- data push search engineen
- index päivittyy
- haku kohdistuu indexiin
add_action('save_post', function($post_id) {
// push to search index
});
Faceted search (suodattimet)
Esimerkkejä:
- kategoriat
- tagit
- hinta
- custom fields
- post type
Tämä ei ole mahdollista tehokkaasti oletus-WP-haulla.
Search performance ongelmat
Yleisimmät pullonkaulat:
- wp_postmeta-scan
- LIKE-haku
- puuttuvat indeksit
- liian laajat queryt
- ei cachea
- REST API ilman rajoituksia
Turvallisuus custom searchissä
Muista:
- aina
$wpdb->prepare() - input sanitization
- rate limiting API:ssa
- ei suoria SQL-stringejä
Yleisimmät virheet
- käytetään WP_Queryta kaikkeen
- ei full-text indexiä
- ei cachea
- liian raskaat meta_queryt
- hakua ei eroteta frontendistä
- ei debouncea frontendissä
Paras käytäntö
Skaalautuva custom search:
- REST API -kerros
- optimoitu SQL tai search engine
- full-text index tai external engine
- Redis cache
- debounce frontendissä
- ranking-logiikka
- lightweight queryt
Yhteenveto
WordPressin custom search kannattaa suunnitella aina käyttötapauksen mukaan. Pienissä sivustoissa WP_Query riittää optimoituna, mutta suuremmissa järjestelmissä tarvitaan full-text indexeitä tai erillistä search engineä.
Kun haku erotetaan omaksi palvelutasokseen ja siihen lisätään cache, ranking ja API-kerros, WordPressistä voidaan rakentaa erittäin nopea ja skaalautuva hakujärjestelmä.
