Поиск сообщений с определенными тегами - PullRequest
2 голосов
/ 21 апреля 2019

Я разрешаю моим пользователям следить за определенными категориями и другими объектами на моей платформе.Например, каждая категория в этой системе имеет уникальный tag_id (показывать в скобках).

Billiards (1)
    Pool (2)
        9-Ball (3)
        8-Ball (4)
    Snooker (5)
Cycling (6)
    Mountain Biking (7)
        Cross Country (8)
        Downhill (9)
        Dual Slalom (10)
        Trials (11)
    Road Racing (12)
    Velodrome (13)

Если пользователь хочет следовать Cycling > Mountain Biking > Downhill, я сохраню 9, 76 в user_tags таблицу:

user_tags

user_id  | tag_id
---------|-----------
1        | 9
1        | 7
1        | 6

Это означает, что если кто-то публикует что-то всего за Cycling (6), чтобы добраться до всех велосипедистовнезависимо от типа, он достигнет пользователя после Downhill.

Теперь у меня есть таблицы feed и feed_tags, которые содержат все сообщения и теги, с которыми они связаны:

feed

feed_id  | title              
---------|------------------------------------------
1044     | How to get into cross country racing.
1045     | How to get into downhill racing.

feed_tags

feed_id  | tag_id
---------|----------
1044     | 8
1044     | 7
1044     | 6
1045     | 9
1045     | 7
1045     | 6

А теперь нужно найти в таблице feed интересующие вас элементыпользователь на основе связанных тегов.

Моя попытка:

Сначала я получаю набор результатов пользовательских тегов и кэширую его, чтобы ускорить процесс для каждогоsearch:

SELECT tag_id FROM user_tags WHERE user_id = 1;

Это дает мне следующее:

tag_id
---------
9
7
6

Затем я перебираю модель тегов пользователя, чтобы построить часть соединений в поиске каналов.query:

SELECT f.title
FROM feed AS f
// loop start
INNER JOIN feed_tags AS ft1 ON f.feed_id = ft1.feed_id
    AND ft1.tag_id = 9
INNER JOIN feed_tags AS ft2 ON f.feed_id = ft2.feed_id
    AND ft2.tag_id = 7
INNER JOIN feed_tags AS ft3 ON f.feed_id = ft3.feed_id
    AND ft3.tag_id = 6
// loop end

Кажется, это работает на очень маленьких тестовых данных, которые у меня есть.Приведенный выше запрос возвращает только одну запись «Как попасть в скоростной спуск».и следующие возвращают их обоих:

SELECT f.title FROM feed AS f
INNER JOIN feed_tags AS ft1 ON f.feed_id = ft1.feed_id
    AND ft1.tag_id = 6

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

Isэтот метод я выбрал приемлемый или его можно улучшить?Если да, то как это можно улучшить и почему?

SQLFIDDLE

Ответы [ 4 ]

0 голосов
/ 23 апреля 2019

Мне удалось ответить на это сам после изменения системы категорий на более простую версию. Вместо того, чтобы позволить каждому уровню в системе категорий быть отслеживаемым, я сделал следующие конечные точки следующим:

Cycling [+]
    Mountain Biking [+]
        Cross Country (8)
        Downhill (9)
        Dual Slalom (10)
        Trials (11)

Что заставляет работать следующий запрос:

SELECT
  f.feed_id,
  f.title
FROM feed AS f
LEFT JOIN feed_tags AS ft ON ft.feed_id = f.feed_id
WHERE ft.tag_id IN (
  SELECT
    tag_id
  FROM user_tags
  WHERE user_id = 1
)
GROUP BY f.feed_id
0 голосов
/ 21 апреля 2019
SELECT DISTINCT f.title
FROM feed AS f
INNER JOIN feed_tags AS ft1 ON f.feed_id = ft1.feed_id AND ft1.tag_id in (9,7,6)

Вы также можете поставить

SELECT tag_id FROM user_tags WHERE user_id = 1;

внутри оператора in, если вы не используете его и в других местах.

0 голосов
/ 21 апреля 2019

демо на dbFiddle

результат, который вы получаете, основан на user_id 1 и tag_id 9 . Таким образом, для определенного user_id вы получаете max tag_id и извлекаете заголовок из таблицы каналов.

SELECT f.title
FROM feed AS f
INNER JOIN feed_tags AS ft1 
    ON f.feed_id = ft1.feed_id 
    where ft1.tag_id = (
  SELECT max(tag_id) FROM user_tags WHERE user_id = 1
);

запрос выше для одного user_id. Если у вас другой user_id и вы хотите использовать заголовки, используйте запрос ниже

SELECT f.title,ft1.tag_id
FROM feed AS f
INNER JOIN feed_tags AS ft1 
    ON f.feed_id = ft1.feed_id 
    where ft1.tag_id IN (
  SELECT max(tag_id) FROM user_tags WHERE user_id IN (1,2,3) group by user_id
);
0 голосов
/ 21 апреля 2019
$search_data = $_REQUEST['search']; //your search keyword 

$connect = mysqli_connect("localhost","db_user_name","db_user_password","db_name"); //connect your MySQL database

$select_data = "SELECT * FROM all_posts WHERE post_tag  LIKE '%$search_data%'"; //your search data select on your database 

$select = mysqli_query($connect,$select_data); //your search data

$search_array = mysqli_fetch_array($select); //your search data convert to array
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...