Какво представляват HPOS Full-Text Search индексите
WooCommerce 9.0 въведе Full-Text Search (FTS) като експериментална функция за магазини, работещи с High-Performance Order Storage. FTS създава MySQL FULLTEXT индекси върху две ключови таблици – wp_wc_order_addresses и wp_woocommerce_order_items.
Старият механизъм за търсене разчита на LIKE '%search_term%' заявки, които принуждават MySQL да сканира всеки ред в таблицата. При магазин с 500 000 поръчки това означава пълно сканиране на стотици хиляди реда при всяко натискане на бутона Search в WooCommerce > Orders. FTS заменя този подход с MATCH...AGAINST синтаксис, който използва предварително изграден обърнат индекс (inverted index) и връща резултати за части от секундата.
Тестовете на WooCommerce екипа показват конкретни числа: при сайт с 500 000 поръчки и 30 000 продукта средното време за търсене пада драстично спрямо стандартното LIKE търсене.
Активиране на FTS индексите
Функцията изисква HPOS да бъде основното хранилище за поръчки. Отворете WooCommerce > Settings > Advanced > Features и проверете, че Order data storage е зададен на High-Performance Order Storage. В секцията Experimental features поставете отметка на HPOS Full-text search indexes.
След активиране WooCommerce създава FULLTEXT индекси в базата данни. Проверете дали индексите са създадени успешно с тази заявка:
SHOW INDEX FROM wp_wc_order_addresses WHERE Index_type = 'FULLTEXT';
SHOW INDEX FROM wp_woocommerce_order_items WHERE Index_type = 'FULLTEXT';
Ако резултатът е празен, нещо е блокирало създаването на индексите – най-честата причина е версия на MySQL между 8.0.29 и 8.0.35, където FULLTEXT за InnoDB има бъгове. Надградете до MySQL 8.0.36+ или MariaDB 10.6+.
Как MySQL FULLTEXT индексите работят с HPOS таблиците
HPOS съхранява адресните данни на поръчките в специализирана таблица wp_wc_order_addresses вместо в wp_postmeta. Тази нормализирана структура прави FULLTEXT индексирането изобщо възможно – при стария EAV модел в wp_postmeta създаването на FTS индекс върху цялата таблица би изисквало неприемливо количество RAM.
Когато FTS е активиран, WooCommerce превръща търсенията в Boolean Mode заявки:
SELECT o.id FROM wp_wc_orders o
INNER JOIN wp_wc_order_addresses a ON o.id = a.order_id
WHERE MATCH(a.first_name, a.last_name, a.company, a.address_1, a.address_2, a.city, a.state, a.postcode, a.country, a.email)
AGAINST('+ivan +petrov' IN BOOLEAN MODE)
ORDER BY o.date_created_gmt DESC
LIMIT 25;
Boolean Mode позволява комбиниране на оператори: + за задължително присъствие, - за изключване, * за частично съвпадение. Когато потребител търси „Ivan Petrov Sofia“, WooCommerce разделя низа на токени и генерира заявка, която изисква съвпадение на всеки от тях.
Конфигурация на MySQL за оптимална работа
Стойността по подразбиране на innodb_ft_min_token_size е 3 символа. Всичко по-кратко от три символа се игнорира при индексиране. Ако клиентите на магазина търсят с двубуквени кодове (BG, DE, UK), трябва да намалите тази стойност:
[mysqld]
innodb_ft_min_token_size=2
innodb_ft_max_token_size=84
Промяната изисква рестартиране на MySQL и преизграждане на FULLTEXT индексите:
ALTER TABLE wp_wc_order_addresses DROP INDEX ft_addresses;
ALTER TABLE wp_wc_order_addresses ADD FULLTEXT INDEX ft_addresses
(first_name, last_name, company, address_1, address_2, city, state, postcode, country, email);
Стоп-думите са друг фактор. MySQL поддържа вградена стоп-лист, която филтрира думи като „the“, „and“, „for“. При магазини с интернационална клиентела проверете дали търсени термини не попадат в стоп-листата:
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
Програмна проверка на FTS статуса
Разработчиците на плъгини и теми трябва да проверяват дали FTS е наличен преди да изграждат собствени заявки. WooCommerce записва статуса на индексите в две option стойности:
$address_fts = get_option('woocommerce_hpos_address_fts_index_created') === 'yes';
$items_fts = get_option('woocommerce_hpos_order_item_fts_index_created') === 'yes';
if ($address_fts) {
// Използвайте MATCH...AGAINST синтаксис
global $wpdb;
$results = $wpdb->get_results($wpdb->prepare(
"SELECT order_id FROM {$wpdb->prefix}wc_order_addresses
WHERE MATCH(first_name, last_name, email, city)
AGAINST(%s IN BOOLEAN MODE)",
'+' . $wpdb->esc_like($search_term) . '*'
));
} else {
// Fallback към LIKE търсене
$results = $wpdb->get_results($wpdb->prepare(
"SELECT order_id FROM {$wpdb->prefix}wc_order_addresses
WHERE first_name LIKE %s OR last_name LIKE %s",
'%' . $wpdb->esc_like($search_term) . '%',
'%' . $wpdb->esc_like($search_term) . '%'
));
}
За разширяване на търсенето в административния панел с допълнителни полета, WooCommerce предоставя два филтъра:
add_filter('woocommerce_hpos_admin_search_filters', function($filters) {
$filters[] = [
'label' => 'Custom Field',
'value' => 'my_custom_field',
];
return $filters;
});
add_filter('woocommerce_hpos_generate_where_for_search_filter', function($where, $search_term, $filter) {
if ($filter === 'my_custom_field') {
global $wpdb;
$where = $wpdb->prepare(
"EXISTS (SELECT 1 FROM {$wpdb->prefix}wc_orders_meta
WHERE order_id = orders.id AND meta_key = 'my_field'
AND meta_value LIKE %s)",
'%' . $wpdb->esc_like($search_term) . '%'
);
}
return $where;
}, 10, 3);
Известни проблеми и ограничения
Търсенето по телефонен номер не връща резултати при активиран FTS. Причината е в начина, по който MySQL токенизира цифрови низове – телефонните номера със специални символи (+359, 0888-123-456) не се разпознават като валидни токени от вградения парсер. Обходното решение е да изберете филтъра Customers вместо All при търсене по телефон.
Плъгини за поредни номера на поръчки (Sequential Order Numbers) имат конфликти с FTS. Те записват номера в order_number meta ключ, който не е част от FTS индекса. WooCommerce съветва разработчиците да мигрират към woocommerce_hpos_admin_search_filters и woocommerce_hpos_generate_where_for_search_filter вместо да пренаписват JS заявките.
MySQL версии от 8.0.29 до 8.0.35 съдържат бъгове в InnoDB FULLTEXT имплементацията. При тези версии индексите или не се създават, или връщат некоректни резултати.
WooCommerce използва вградения езиков парсер вместо n-gram парсера. N-gram би осигурил по-добро покритие за търсения с частични съвпадения, но заема значително повече дисково пространство. Ако вграденият парсер не покрива нуждите на конкретен магазин, ръчната миграция към n-gram е възможна, но не се поддържа официално.
Мониторинг и диагностика с Query Monitor
Инсталирайте Query Monitor и изпълнете търсене в WooCommerce > Orders. В панела Queries потърсете заявки, съдържащи MATCH и AGAINST. Присъствието им потвърждава, че FTS индексите се използват.
Ако вместо това виждате LIKE '%term%' заявки, проверете дали опциите в базата данни са коректни:
// Добавете в functions.php за бърза диагностика
add_action('admin_notices', function() {
if (!current_user_can('manage_woocommerce')) return;
$addr = get_option('woocommerce_hpos_address_fts_index_created');
$item = get_option('woocommerce_hpos_order_item_fts_index_created');
$hpos = get_option('woocommerce_custom_orders_table_enabled');
echo '<div class="notice notice-info"><p>';
echo "HPOS: {$hpos} | FTS Addresses: {$addr} | FTS Items: {$item}";
echo '</p></div>';
});
За магазини с над 100 000 поръчки следете размера на FTS индексите:
SELECT table_name, index_name, stat_value * @@innodb_page_size AS size_bytes
FROM mysql.innodb_index_stats
WHERE stat_name = 'size' AND index_name LIKE 'ft%';
Кога да активирате FTS на продукция
Функцията остава експериментална, но подобренията в скоростта са измерими. Тествайте задължително на staging среда. Проверете MySQL версията – 8.0.36+ или MariaDB 10.6+ са минималните препоръчителни. Деактивирайте и активирайте отново FTS, ако забележите проблеми – процесът не води до загуба на данни.
Магазини с под 10 000 поръчки няма да усетят значителна разлика – стандартното LIKE търсене е достатъчно бързо при тези обеми. FTS индексите показват реалната си стойност при 50 000+ поръчки, където всяко търсене в административния панел без тях отнема 4-7 секунди.
Често задавани въпроси
-
Какво е HPOS Full-Text Search в WooCommerce?
Експериментална функция от WooCommerce 9.0, която създава MySQL FULLTEXT индекси върху таблиците wp_wc_order_addresses и wp_woocommerce_order_items. Търсенето преминава от LIKE към MATCH…AGAINST синтаксис, което го прави многократно по-бързо.
-
Защо търсенето по телефонен номер не работи с FTS включен?
MySQL FULLTEXT парсерът токенизира по innodb_ft_min_token_size (по подразбиране 3 символа) и пропуска цифрови низове, които не отговарят на правилата за токени. За телефонни номера използвайте филтъра Customers вместо All при търсене.
-
Мога ли да ползвам FTS индексите с MariaDB?
MariaDB поддържа FULLTEXT за InnoDB, но WooCommerce екипът е открил несъответствия при различни версии. Тествайте на staging среда преди да активирате на продукция, особено при MariaDB под 10.6.
-
Как да проверя дали FTS индексите се използват от заявките?
Инсталирайте Query Monitor и потърсете MATCH…AGAINST синтаксис в SQL лога. Проверете и опциите woocommerce_hpos_address_fts_index_created и woocommerce_hpos_order_item_fts_index_created – стойността им трябва да е yes.
-
Какво се случва ако деактивирам FTS индексите след като съм ги използвал?
WooCommerce се връща към стандартното LIKE търсене. Настройката е обратно съвместима – можете да я включвате и изключвате без загуба на данни или необходимост от ресинхронизация.
