Задать вопрос
nipopadyuk
@nipopadyuk

Как выполнить поиск данных, если в базе данных указан шаблон?

Имеется сайт на WP, у которого есть тысячи кастомных записей, и почти у каждой записи есть ACF поле VIN.
По сути, это VIN номер автомобиля, и хранится он в виде W1K253???1???????, W1N253???1??????? и т.д.

Вопросительные знаки означают, что там может быть любое числовое или буквенное значение, но не более количества вопросительных знаков. Так же, в разных моделях ТС вопросительные знаки могут находится в разных частях VIN номера, т.е. единого шаблона поиска у нас нету.

Нам нужно сделать поиск по этому полю, при том, что пользователь будет вводить полный вин номер своей машины, например, W1K25312311234567, и по этому коду, должны выйти записи, где есть такое: W1K253???1???????

Пробовал сделать так, он мне выдал вообще все записи:
$vin_regex = str_replace(array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'), '.', $vin_regex);

    
    $meta_query = array(
        array(
            'key' => 'vin',
            'value' => $vin_regex,
            'compare' => 'REGEXP', 
        ),
    );

    $args = array(
        'post_type' => 'product',
        'posts_per_page' => 10,
        'paged' => $paged,
        'meta_query' => $meta_query,
    );

    $query = new WP_Query($args);


Пробовал так, результат нулевой
$query = "
        SELECT DISTINCT p.ID
        FROM {$wpdb->posts} p
        INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
        WHERE p.post_type = 'product'
          AND p.post_status = 'publish'
          AND pm.meta_key = 'vin'
          AND pm.meta_value LIKE REPLACE(%s, '?', '_')
        LIMIT 10 OFFSET %d
    ";

    $results = $wpdb->get_col($wpdb->prepare($query, $vin_input, $offset));


Может кто-то с таким уже сталкивался и есть решение?
  • Вопрос задан
  • 112 просмотров
Подписаться 1 Средний 4 комментария
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 2
хранится он в виде W1K253???1???????, W1N253???1???????

Насколько я вижу, эти шаблоны одинаковы, то есть:
  1. 6 фиксированных символов
  2. 3 произвольных символа
  3. 1 фиксированный символ
  4. 7 произвольных символов

При этом произвольные символы обозначены знаком "?".
Тогда можно сделать такой регуляркой:
<?php
$requestedVin = 'W1K25312311234567';
$pattern = preg_replace('/^([A-Z\d]{6})[A-Z\d]{3}([A-Z\d])[A-Z\d]{7}$/', '$1???$2???????', $requestedVin);

$query = "
        SELECT DISTINCT p.ID
        FROM {$wpdb->posts} p
        INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
        WHERE p.post_type = 'product'
          AND p.post_status = 'publish'
          AND pm.meta_key = 'vin'
          AND pm.meta_value = %s
        LIMIT 10 OFFSET %d
    ";

$results = $wpdb->get_col($wpdb->prepare($query, $pattern, $offset));
Ответ написан
Комментировать
@rPman
Вам нужно сначала определить, к какому шаблону соответствует введенный пользователем запрос, для этого этот список шаблонов должен быть определен в программе, например регулярными выражениями, для каждого по очереди нужно будет делать проверку запроса пользователя, соответственно порядок этих проверок нужно будет тщательно продумать, например если один шаблон включается в другой, то он должен быть выше по списку (например a???b и a?c?b - второй шаблон тут должен проверяться первым).

Каждому шаблону нужно будет дать соответствие строку sql запроса в базе данных (либо подстрокой выражения)

p.s. так ли нужно пользователям такое усложнение поиска?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽