10 February 2025

HashTag System Improvement

HashTag System Improvement for PlayTube (Advanced User Only)

Education

454 Views

1 Share

Advertisement

Advertise With Vidude



The current HashTag System Issues and Suggested Improvements

 

  1. Hashtags Stored as Raw Text Instead of a Relationship

    • The system searches for # in title and description, which is inefficient.
    • Solution: Implement a video_hashtags table to directly associate videos with hashtags.
  2. Inefficient Query Performance

    • The current query requires a LIKE search on large text fields, which is slow.
    • Solution: Instead of text search, store hashtag-video relationships in a separate table and use indexed video_id lookups.
  3. No Tracking of Hashtag Usage

    • There is no count of how often a hashtag is used.
    • Solution: Add a usage_count column in hashtags and update it whenever a hashtag is added to a video.
  4. No Auto-Suggestion for Trending Hashtags

    • The system does not suggest hashtags to users.
    • Solution: Fetch and display trending hashtags based on usage_count.

 

Full Step-by-Step Implementation Plan for Fixing the Hashtag System

 

This plan will:

  1. Create and modify database tables for an optimized hashtag system.
  2. Update PHP functions to store and fetch hashtags efficiently.
  3. Modify AJAX files (submit-video.php, ffmpeg-submit.php, etc.) to ensure correct hashtag storage.
  4. Fix sources/hashtag/content.php so it correctly fetches videos by hashtags.
  5. Ensure the system scales for large databases with 500K+ videos.

Step 1: Create and Modify Database Tables

We will create the video_hashtags table and update the hashtags table.

Step 1.1: Create video_hashtags Table

Run this SQL command in your database:

sql
CREATE TABLE `video_hashtags` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `video_id` INT(11) NOT NULL, -- Links to `videos.id` `hashtag_id` INT(11) NOT NULL, -- Links to `hashtags.id` PRIMARY KEY (`id`), INDEX (`video_id`), -- Optimized lookup for videos INDEX (`hashtag_id`) -- Optimized lookup for hashtags ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

Now, hashtags will be stored in a separate table instead of the video title and description.


Step 1.2: Modify hashtags Table to Track Usage

Run this SQL to add a usage_count column:

sql
ALTER TABLE hashtags ADD COLUMN `usage_count` INT(11) NOT NULL DEFAULT 0;

This will track how often a hashtag is used.


Step 1.3: Add Table Definitions to tables.php

Open tables.php and add these lines at the bottom:

php
define('T_VIDEO_HASHTAGS', 'video_hashtags'); define('T_VIDEOS', 'videos'); define('T_HASHTAGS', 'hashtags');

Now, all scripts can reference these tables dynamically.


Step 2: Modify PHP Functions to Handle Hashtags

We need to update functions_one.php to correctly:

  • Store hashtags from title and description in video_hashtags
  • Increase the usage_count in hashtags
  • Fetch videos efficiently

Step 2.1: Fix getHashTagId() to Ensure Hashtag Exists

Location: functions_one.php

Find this:

php
function getHashTagId($tag = '')

Replace it with this:

php
function getHashTagId($tag = '') { global $sqlConnect, $db, $pt; $tagData = $db->where('tag', $tag)->getOne(T_HASHTAGS); if (!empty($tagData)) { // Increase usage count $db->where('id', $tagData->id)->update(T_HASHTAGS, ['usage_count' => $db->inc(1)]); return $tagData->id; } else { // Insert new hashtag $id = $db->insert(T_HASHTAGS, [ 'tag' => $tag, 'time' => time(), 'usage_count' => 1 // Set initial usage to 1 ]); return !empty($id) ? $id : 0; } }

Now, hashtags are always stored properly with a usage count.


Step 2.2: Fix addToHashTags() to Store Hashtags in video_hashtags

Find:

php
function addToHashTags($text, $video_id)

Replace it with this:

php
function addToHashTags($text, $video_id) { global $sqlConnect, $db, $pt; if ($pt->config->hashtag_system == 'off') { return $text; } $hashtag_regex = '/#([^`~!@$%^&*\\#()\\-+=\\\\|\\/\\.,<>?\\\'\\":;{}\\[\\]* ]+)/i'; preg_match_all($hashtag_regex, $text, $matches); foreach ($matches[1] as $match) { $match = strtolower($match); $tagID = getHashTagId($match); if (!empty($tagID)) { // Store in video_hashtags if (!empty($video_id) && $video_id > 0) { $existingEntry = $db->where('video_id', $video_id) ->where('hashtag_id', $tagID) ->getOne(T_VIDEO_HASHTAGS); if (empty($existingEntry)) { $db->insert(T_VIDEO_HASHTAGS, [ 'video_id' => $video_id, 'hashtag_id' => $tagID ]); } } } } return $text; }

Now, hashtags are correctly linked to videos without duplicates.


Step 3: Modify AJAX Files for Hashtag Storage

Now, we need to update submit-video.php, ffmpeg-submit.php, and edit-video.php to store hashtags correctly.

Step 3.1: Fix submit-video.php

Find this:

php
$db->insert(T_VIDEOS, [ 'title' => $_POST['title'], 'description' => $_POST['description'], 'is_short' => $_POST['is_short'], ]);

Replace it with this:

php
$video_id = $db->insert(T_VIDEOS, [ 'title' => $_POST['title'], 'description' => $_POST['description'], 'is_short' => $_POST['is_short'], ]); // Ensure video_id is valid before storing hashtags if (!empty($video_id) && $video_id > 0) { addToHashTags($_POST['title'], $video_id); addToHashTags($_POST['description'], $video_id); }

Now, hashtags are correctly extracted and stored when a video is uploaded.


Step 4: Fix sources/hashtag/content.php to Fetch Videos

Find this:

php
$videos = $db->where("(title LIKE '%#[".$tag_data->id."]%' OR description LIKE '%#[".$tag_data->id."]%')")

Replace it with this:

php
$videos = $db->join(T_VIDEO_HASHTAGS . " vh", "vh.video_id=v.id", "INNER") ->where("vh.hashtag_id", $tag_data->id) ->where('v.privacy', 0) ->where('v.user_id', $pt->blocked_array , 'NOT IN') ->where('v.is_movie', 0) ->where('v.live_time', 0) ->where('v.approved', 1) ->orderBy('v.views', 'DESC') ->objectbuilder() ->paginate(T_VIDEOS . " v", $pt->page_number);

Now, hashtags are fetched using video_hashtags, not slow LIKE queries.


Final Steps

1️⃣ Create video_hashtags table and modify hashtags.
2️⃣ Update functions_one.php to store hashtags properly.
3️⃣ Modify submit-video.php, ffmpeg-submit.php, and edit-video.php.
4️⃣ Fix sources/hashtag/content.php to fetch videos correctly.
5️⃣ Test by uploading and searching for hashtags.

 

Optimizing Website Speed & Video Handling with Redis

To speed up, we can optimize video search, metadata fetching, and frequently accessed pages using Redis caching.


1️⃣ What Can We Cache in Redis?

Video Metadata (Title, Views, Thumbnails, etc.)
Search Results (Hashtags, Popular Videos, User Queries)
Homepage Trending Videos
User Profiles


2️⃣ Caching Video Metadata in Redis

Every time a user views a video, instead of fetching details from MySQL every time, cache it in Redis for quick access.

Modify PT_GetVideoByID($video_id) in functions_one.php

Original Code (Slow MySQL Query)

php
function PT_GetVideoByID($video_id) { global $db; return $db->where('id', $video_id)->getOne(T_VIDEOS); }

Optimized with Redis

php
function PT_GetVideoByID($video_id) { global $db; $redis = new Redis(); $redis->connect('172.17.0.2', 6379); // Use Redis container IP $cache_key = "video:$video_id"; // ? Check Redis first if ($redis->exists($cache_key)) { return json_decode($redis->get($cache_key)); } // ❌ Not in Redis? Fetch from MySQL $video = $db->where('id', $video_id)->getOne(T_VIDEOS); if (!empty($video)) { $redis->setex($cache_key, 3600, json_encode($video)); // Cache for 1 hour } return $video; }

Result

  • Faster page loads (No need to query MySQL every time)
  • Reduced database load
  • Boosted site performance

3️⃣ Speed Up Video Search with Redis

Instead of searching directly in MySQL, store popular hashtag searches in Redis.

Modify content.php for Hashtag Search

Original Code (Slow)

php
$videos = $db->where("title LIKE '%#[".$tag_data->id."]%' OR description LIKE '%#[".$tag_data->id."]%'") ->orderBy('views', 'DESC')->objectbuilder()->paginate(T_VIDEOS, $pt->page_number);

Optimized with Redis

php
$redis = new Redis(); $redis->connect('172.17.0.2', 6379); $cache_key = "hashtag_videos:{$tag_data->id}"; if ($redis->exists($cache_key)) { $videos = json_decode($redis->get($cache_key)); } else { $videos = $db->join(T_VIDEO_HASHTAGS . " vh", "v.id = vh.video_id", "INNER") ->where("vh.hashtag_id", $tag_data->id) ->orderBy("v.views", "DESC") ->objectbuilder() ->paginate(T_VIDEOS . " v", $pt->page_number); $redis->setex($cache_key, 600, json_encode($videos)); // Cache for 10 mins }

Result

  • 5x Faster hashtag search
  • Less MySQL load

4️⃣ Speed Up Trending Videos on Homepage

Instead of querying trending videos every page load, cache it for 5 minutes.

Modify home.php

php
$redis = new Redis(); $redis->connect('172.17.0.2', 6379); $cache_key = "trending_videos"; if ($redis->exists($cache_key)) { $trending_videos = json_decode($redis->get($cache_key)); } else { $trending_videos = $db->where('privacy', 0)->orderBy('views', 'DESC')->get(T_VIDEOS, 10); $redis->setex($cache_key, 300, json_encode($trending_videos)); // Cache for 5 mins }

Result

  • Homepage loads instantly
  • No heavy MySQL queries

5️⃣ How to Clear Cache When Video Updates?

Whenever a user uploads or edits a video, clear the cache.

Modify edit-video.php

php
$redis = new Redis(); $redis->connect('172.17.0.2', 6379); // Clear cache when video is updated $redis->del("video:$id"); $redis->del("trending_videos");

 

Now, your hashtag system is fully optimized and scalable for 10M+ videos! 


0
 
0

5 Comments

Such an underrated post! More people need to see this because it offers a perspective that’s rarely discussed. Thank you for this! 💙
0 0 Reply

Anish Malhotra

21 days ago
I love when an article makes me feel smarter after reading it! This was packed with so much valuable information. 💡
0 0 Reply

josetteb93234

21 days ago
I love when an article makes me feel smarter after reading it! This was packed with so much valuable information. 💡
0 0 Reply

IsraelLoan

22 days ago
This post really made me think! The arguments were well-structured, and I can tell a lot of thought went into crafting this. I’ll definitely be sharing it! 🤯
0 0 Reply

The Web Wizard

23 days ago
Wow, I actually learned something new today! This post made me see things in a different light, and I’m so glad I stumbled upon it. 🎯
0 0 Reply
Show more

Related Articles