Использование DISTINCT в wp_query для исключения дубликатов

22 мая 2014 г., 21:51:51
Просмотры: 15.5K
Голосов: 2

Мне нужно создать систему, где пользователь сначала выбирает штат, затем город, а затем видит информацию о магазинах в этом городе.

Для этого я создал пользовательский тип записи (CPT) под названием store с 2 метаполями: state (штат) и city (город).

Для первого выпадающего списка я использую WP_Query со следующими аргументами:

$args = array(
    'post_type' => 'store',
    'posts_per_page' => -1,
    'meta_key' => 'state',
    'orderby' => 'meta_value', 
    'order' => ASC,
);

Но запрос возвращает повторяющиеся штаты, потому что в одном штате находится более одного магазина.

Как это можно исправить? Я думал об использовании DISTINCT из MySQL, но не знаю, возможно ли это.

ОБНОВЛЕНИЕ

Полный цикл:

$args = array(
    'post_type' => 'store',
    'posts_per_page' => -1,
    'meta_key' => 'state',
    'orderby' => 'meta_value', 
    'order' => ASC,
);

 function search_distinct() { return "DISTINCT"; }
 add_filter('posts_distinct', 'search_distinct');
 $the_query = new WP_Query( $args );

 if ( $the_query->have_posts() ) {
   echo '<ul>';
   while ( $the_query->have_posts() ) {
      $the_query->the_post();
      echo '<li>' . get_custom_field('estado') . '</li>';
   }
   echo '</ul>';
 }
 wp_reset_postdata();
 remove_filter('posts_distinct', 'search_distinct');

Но фильтр не срабатывает

0
Все ответы на вопрос 2
12

Я сам не пробовал, но похоже, что для этого подойдут фильтры posts_distinct или posts_groupby:

function search_distinct() {
    return "DISTINCT";
}
add_filter('posts_distinct', 'search_distinct');
22 мая 2014 г. 22:15:10
Комментарии

Привет, Пим. Как я могу связать этот фильтр с запросом?

marcelo2605 marcelo2605
22 мая 2014 г. 22:17:37

Тебе нужно будет использовать условные теги WordPress, в зависимости от того, где ты хочешь использовать запрос (например, is_post_type_archive('store') ), или ты можешь добавить фильтр напрямую в шаблон, чтобы он вызывался только там.

Pim Pim
22 мая 2014 г. 22:20:52

Я буду использовать этот запрос в простом цикле.

marcelo2605 marcelo2605
22 мая 2014 г. 22:29:39

Попробуйте добавить его прямо перед запросом, затем вызовите remove_filter('posts_distinct', 'search_distinct'); сразу после завершения цикла.

Pim Pim
22 мая 2014 г. 22:37:07

Я добавил фильтр, как вы сказали (см. выше), но ничего не происходит.

marcelo2605 marcelo2605
22 мая 2014 г. 22:49:50

С вашим обновленным кодом ситуация совсем другая... Вы говорите, что state повторяется, верно? Так что нет необходимости в "distinct" постах. Но что такое get_custom_field()? Это не выглядит стандартным.

Pim Pim
22 мая 2014 г. 23:27:08

Ваш запрос действительно создает дублирующиеся записи "магазин"? Или просто повторяются метаданные?

Pim Pim
22 мая 2014 г. 23:35:41

get_custom_filed() - это функция для получения значений метаданных записи.

marcelo2605 marcelo2605
22 мая 2014 г. 23:44:57

Например: У меня три магазина. Один в SP и два в MG. Запрос возвращает SP, MG, MG.

marcelo2605 marcelo2605
22 мая 2014 г. 23:46:19

В чем именно проблема? Это ожидаемый результат данного запроса. Запрос не возвращает штаты, у вас 3 магазина, поэтому он возвращает 3 результата. Вы делаете запрос к постам. Как бы вы хотели, чтобы он работал? Возвращал только один пост на штат? На основании каких условий? Ваш вопрос слишком неясен.

Pim Pim
23 мая 2014 г. 00:05:42

Вы правы. Поэтому я преобразовал штаты и города в таксономии. Спасибо.

marcelo2605 marcelo2605
23 мая 2014 г. 00:17:18

@Pim Спасибо за этот ответ, именно то, что мне нужно для проекта

phatskat phatskat
9 июн. 2014 г. 18:33:30
Показать остальные 7 комментариев
0

Я не уверен, что это лучший способ добиться этого, но вы можете использовать сырой запрос, например:

$states = $wpdb->get_results("SELECT DISTINCT meta_value 
                              FROM wp_postmeta 
                              WHERE meta_key = 'state'
                              ORDER BY meta_value");

Вышеуказанный код вернет массив уникальных значений метаданных state, которые затем можно отобразить в виде списка с помощью:

if (count($states)) {
  print '<ul>';
  foreach ($states as $state) {
    print '<li>' . $state->meta_value . '</li>';
  }
  print '</ul>';
}
23 мая 2014 г. 04:37:09