Как выбрать записи с определенными тегами/категориями в WordPress
Вопрос
Это очень конкретный вопрос, касающийся MySQL как это реализовано в WordPress.
Я пытаюсь разработать плагин, который будет показывать (выбирать) сообщения с определеннымитеги'и принадлежать к конкретному'категории' (оба множественные)
Мне сказали, что это невозможно, потому что категории и теги хранятся так:
wp_posts
содержит список сообщений, каждое сообщение имеет «ID»wp_terms
содержит список терминов (как категорий, так и тегов).Каждый термин имеет TERM_IDwp_term_taxonomy
имеет список терминов с их TERM_ID и определение таксономии для каждого из них (категории или тега).wp_term_relationships
имеет ассоциации между терминами и сообщениями
Как мне объединить таблицы, чтобы получить все сообщения с тегами "Ядерная энергия"? и «Сделки», которые также относятся к категории «Категория 1»?
Решение
Я не так тебя поняла.Я думал, ты хочешь Nuclear или Deals.Приведенное ниже должно дать вам только Nuclear и Deals.
select p.*
from wp_posts p, wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr,
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2
where p.id = tr.object_id and t.term_id = tt.term_id and tr.term_taxonomy_id = tt.term_taxonomy_id
and p.id = tr2.object_id and t2.term_id = tt2.term_id and tr2.term_taxonomy_id = tt2.term_taxonomy_id
and p.id = tr3.object_id and t3.term_id = tt3.term_id and tr3.term_taxonomy_id = tt3.term_taxonomy_id
and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name = 'Nuclear')
and (tt3.taxonomy = 'post_tag' and tt3.term_id = t3.term_id and t3.name = 'Deals')
Другие советы
Какая грубая структура БД.
В любом случае, я бы сделал что-то вроде этого (обратите внимание, что я предпочитаю EXISTS соединениям, но вы можете переписать их как соединения, если хотите;большинство анализаторов запросов в любом случае сворачивают их в один и тот же план запроса).Возможно, вам придется так или иначе проделать некоторые дополнительные манипуляции, чтобы это заработало...
SELECT *
FROM wp_posts p
WHERE EXISTS( SELECT *
FROM wp_term_relationship tr
WHERE tr.object_id = p.id
AND EXISTS( SELECT *
FROM wp_term_taxonomy tt
WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
AND tt.taxonomy = 'category'
AND EXISTS( SELECT *
FROM wp_terms t
WHERE t.term_id = tt.term_id
AND t.name = "Category1"
)
)
AND EXISTS( SELECT *
FROM wp_term_taxonomy tt
WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
AND tt.taxonomy = 'post_tag'
AND EXISTS( SELECT *
FROM wp_terms t
WHERE t.term_id = tt.term_id
AND t.name = "Nuclear"
)
AND EXISTS( SELECT *
FROM wp_terms t
WHERE t.term_id = tt.term_id
AND t.name = "Deals"
)
)
)
Поэтому я попробовал оба варианта в своей базе данных WordPress.В своих сообщениях я искал категорию «Технологии» с тегами «Perl» И «Программирование».
Эрика сработало, как только я добавил недостающую запятую в исходный оператор выбора.Он вернул 3 записи.Проблема в том, что раздел, который ищет «post_tag», на самом деле работает как опция ИЛИ.В одном из моих постов был только один тег, а не оба.Также было бы хорошо сделать SELECT DISTINCT.
Я пытался Мэтт версию, но она продолжала возвращать пустой набор.Возможно, я попробую с этим «жонглировать».
Попробуй это:
select p.*
from wp_posts p,
wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2
where p.id = tr.object_id
and t.term_id = tt.term_id
and tr.term_taxonomy_id = tt.term_taxonomy_id
and p.id = tr2.object_id
and t2.term_id = tt2.term_id
and tr2.term_taxonomy_id = tt2.term_taxonomy_id
and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name in ('Nuclear', 'Deals'))
По сути, я использую две копии соответствующих дочерних таблиц: term, term_taxonomy и term_relationship.В одной копии применяется ограничение «Категория 1», в другой — ограничение «Ядерная энергетика» или «Сделки».
Кстати, что это за проект с постами о ядерных сделках?Вы пытаетесь внести нас в какой-то правительственный список?;)
Спасибо @Eric, это работает!Всего несколько исправлений кода для дальнейшего использования:
- первые операторы выбора пропускают запятую после wp_term_relationship tr2
- В том же операторе выбора необходимо изменить следующее:
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship
tr2
должно быть
wp_terms t3, wp_term_taxonomy tt3, wp_term_relationship
tr3
Действительно такой отличный ответ..мне очень помогло..
отлично, потому что это дало мне базовый подход к построению моего сложного запроса!
небольшая поправка для таких готовых пользователей, как я :)
"WP_Term_relationship" даст «не существует ошибки» ..использовать wp_term_relationships так как это правильное имя таблицы.
Спасибо, Эрик.