Задать вопрос
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));


Может кто-то с таким уже сталкивался и есть решение?
  • Вопрос задан
  • 70 просмотров
Подписаться 1 Средний 4 комментария
Пригласить эксперта
Ответы на вопрос 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. так ли нужно пользователям такое усложнение поиска?
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы