В WordPress часто возникает ситуация, когда в базе данных появляются дублирующиеся записи, отличающиеся только значением одного из произвольных полей (custom fields). Это может привести к проблемам с SEO, путанице в админке и увеличению размера базы данных. В этой статье разберём, как найти и удалить такие дубли по кастомному полю с помощью кода и подскажем полезные плагины.
Почему в WordPress появляются дублирующиеся записи по пользовательскому полю
Дублирование записей по пользовательским полям может происходить по разным причинам:
- Автоматический импорт контента с ошибками, когда одинаковые записи создаются несколько раз.
- Ошибки в кастомных формах и плагинах, которые не проверяют существование записи перед созданием новой.
- Неправильная логика работы с мета-полями, приводящая к созданию копий.
Чтобы не допускать накопления таких дублирующих записей, важно периодически проводить их поиск и удаление.
Как найти дублирующие записи по произвольному полю в WordPress
Для начала нужно получить список значений пользовательского поля, по которому будем искать дубли. Допустим, у нас есть мета-поле с ключом wpmart_custom_key.
Через прямой SQL-запрос можно получить повторы:
SELECT meta_value, COUNT(*) as count FROM wp_postmeta WHERE meta_key = 'wpmart_custom_key' GROUP BY meta_value HAVING count > 1;Этот запрос показывает значения поля, которые встречаются более одного раза. После этого нам нужно получить ID постов с этими значениями, чтобы удалить лишние дубли.
Пример функции для поиска и удаления дублей
Ниже пример PHP-функции, которую можно добавить в файл functions.php вашей темы или использовать в виде плагина. Она ищет дубли по заданному мета-ключу и удаляет все записи, кроме одной для каждого значения.
function wpmart_remove_duplicate_posts_by_meta( $meta_key ) {
global $wpdb;
// Получаем все значения, которые дублируются
$duplicates = $wpdb->get_results( $wpdb->prepare(
"SELECT meta_value, COUNT(*) as count FROM {$wpdb->postmeta} WHERE meta_key = %s GROUP BY meta_value HAVING count > 1",
$meta_key
) );
foreach ( $duplicates as $dup ) {
// Получаем ID постов с этим значением
$post_ids = $wpdb->get_col( $wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s",
$meta_key, $dup->meta_value
) );
// Оставляем первый пост, удаляем остальные
$keep = array_shift($post_ids);
foreach ($post_ids as $post_id) {
wp_delete_post( $post_id, true );
}
}
}
// Пример вызова
wpmart_remove_duplicate_posts_by_meta('wpmart_custom_key');Обратите внимание, что функция удаляет записи без возможности восстановления, поэтому обязательно сделайте резервную копию базы данных перед выполнением.
Автоматизация удаления дублей с помощью плагинов
Если вы не хотите писать код, можно использовать плагины, которые помогают находить и удалять дублирующий контент:
- Remove Duplicate Posts — простой плагин для удаления дублирующих записей по заголовку и другим критериям.
- Clearfy Pro — мощный плагин оптимизации, в котором есть инструменты для очистки базы данных, включая удаление дублей.
Для поиска дублей по мета-полям в плагинах часто требуется дополнительная настройка или кастомизация, так как стандартная функциональность ориентирована на заголовки или контент.
Как защититься от появления дублей в будущем
Чтобы минимизировать появление дублированных записей, рекомендуем:
- Добавлять уникальные ключи на уровне базы данных — например, создать уникальный индекс для
meta_key + meta_valueвwp_postmeta. Это можно сделать через SQL, но требует осторожности и резервного копирования. - Проверять наличие записи с таким же значением перед вставкой новой в коде вашего плагина или темы.
- Использовать хук
save_postдля валидации данных и предотвращения создания дублей.
Пример проверки перед сохранением записи
function wpmart_prevent_duplicate_post_save( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) return;
$meta_key = 'wpmart_custom_key';
$value = get_post_meta( $post_id, $meta_key, true );
if ( empty( $value ) ) return;
$args = [
'post_type' => 'any',
'meta_key' => $meta_key,
'meta_value' => $value,
'post__not_in' => [ $post_id ],
'fields' => 'ids',
'posts_per_page' => 1,
];
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
wp_die( 'Ошибка: запись с таким значением пользовательского поля уже существует.' );
}
}
add_action( 'save_post', 'wpmart_prevent_duplicate_post_save' );Этот код прерывает сохранение записи, если уже есть пост с таким же значением пользовательского поля.
Итоги и рекомендации
Удаление дублей по произвольным полям в WordPress — задача, требующая аккуратного подхода. Ключевые моменты:
- Сначала анализируем базу и находим дубли с помощью SQL-запросов.
- Используем код для массового удаления, обязательно с резервным копированием.
- Рассматриваем плагины, например Clearfy Pro, для упрощения задач оптимизации.
- Внедряем защитные механизмы от повторного появления дублей.
Такой подход поможет держать базу данных в порядке и улучшит стабильность и производительность сайта на WordPress.