PDA

View Full Version : یافتن کلمات کلیدی که بیشترین تکرار را داشته اند در php



kabootar_y
چهارشنبه 28 آبان 1393, 11:18 صبح
با سلام من در دیتابیسم دو تا جدول دارم یکی جدول articles و دیگری keywords
می خوام کلمات کلیدی که که بیشترین تکرار را داشته اند رو پیدا کنم. البته تعداد رکورد هام خیلی زیاده و فکر نمی کنم با for,foreach,while و اینها به نتیجه برسم

اگه میشه راهنمایی کنید که آیا راهی هست که با همان کد sql کلمات کلیدی که بیشترین تکرار رو داشتند رو پیدا کنیم؟



جدول article
---------------------------------
| id | title | text | Keywords_id |
---------------------------------
| 1 | abcde | eftd | "1","3","9" |
---------------------------------
| 2 | zargf | ells | "29","34" |
---------------------------------
| 3 | tkjls | xmnr | "1","29","2"|
---------------------------------


حدول keywords
-----------------------
| id | keyword_name |
-----------------------
| 1 | books |
-----------------------
| 2 | computer |
-----------------------
| 3 | facebook |
-----------------------
| 9 | internet |
-----------------------
| 29 | mobile |
-----------------------
| 34 | newspaper |
-----------------------

arash691
چهارشنبه 28 آبان 1393, 19:16 عصر
بهتره یک رابطه یک به N از جدول article به tags بزنی اینطوری فیلد با مقدار مرکب نداری

ashkufaraz
چهارشنبه 28 آبان 1393, 21:58 عصر
مقاله ای تعدادی کلمه کلیدی دارد و هر کلمه کلیدی می تواند در تعدادی مقاله باشد بنابراین رابطه چند به چند دارن و یک جدول واسط براش درنظر می گرفتی با دو تا فیلد id_artice,id_keyword من زیاد توی کوئری نوشتن قوی نیستم و به نظرم کوئری پیچیده ای می شه ولی با زبانی مثل سی شارپ یا هر چی دیگه می تونی راحت تک تک رکورد ها را بگیری و بعد فیلد keywords_id جدول article را با ، مقادیرش رو split کنی یک آرایه بدست.یک آرایه result هم داشته باشی که تعدا خانه هاش به تعداد keyWordهای جدول keyword باشد.


result[split(["keyWord"],',')[0]]++
result[split(["keyWord"],',')[1]]++
result[split(["keyWord"],',')[3]]++
result[split(["keyWord"],',')[len("keyword")]]++

kabootar_y
چهارشنبه 28 آبان 1393, 22:15 عصر
مقاله ای تعدادی کلمه کلیدی دارد و هر کلمه کلیدی می تواند در تعدادی مقاله باشد بنابراین رابطه چند به چند دارن و یک جدول واسط براش درنظر می گرفتی با دو تا فیلد id_artice,id_keyword من زیاد توی کوئری نوشتن قوی نیستم و به نظرم کوئری پیچیده ای می شه ولی با زبانی مثل سی شارپ یا هر چی دیگه می تونی راحت تک تک رکورد ها را بگیری و بعد فیلد keywords_id جدول article را با ، مقادیرش رو split کنی یک آرایه بدست.یک آرایه result هم داشته باشی که تعدا خانه هاش به تعداد keyWordهای جدول keyword باشد.


دوست عزیز از نظر شما متشکرم اما:

اولا کار من از این حرفا گذشته که جدول واسطی که گفتید رو اضافه کنم چون تعداد مطالب من الان حدود 500000 تا است.

دوما به نظر من اگه جدول واسط باشه هم باز فرقی نمیکنه که؟ شاید هم من اشتباه میکنم

HaZeM+
چهارشنبه 28 آبان 1393, 22:18 عصر
این کد ایجاد table ها

CREATE TABLE articles
(
id int auto_increment primary key,
title varchar(100),
`text` text
);
CREATE TABLE tags
(
id int auto_increment primary key,
name varchar(100)
);

CREATE TABLE tag_relations
(
id int auto_increment primary key,
article_id int,
tag_id int
);

INSERT INTO articles
(title, `text`)
VALUES
('ONVAN1', 'MATN1'),
('ONVAN2', 'MATN2');

INSERT INTO tag_relations
(article_id, tag_id)
VALUES
(1, 1),
(1, 2),
(2, 2),
(2, 3);

INSERT INTO tags
(name)
VALUES
('tag1'),
('tag2'),
('tag3'),
('tag4');

...

اینم query

SELECT t.* FROM tags AS t LEFT JOIN tag_relations AS tr ON t.id = tr.tag_id GROUP BY t.id ORDER BY COUNT(t.id) DESC LIMIT 30


...

پیروز باشی دوست خوبم :)

kabootar_y
چهارشنبه 28 آبان 1393, 22:22 عصر
از پاسختون کمال تشکر رو دارم.
اگه لطف کنید یه توضیح مختصری هم درموردش بدین دیگه خیلی شرمنده کردید بنده رو

HaZeM+
چهارشنبه 28 آبان 1393, 22:30 عصر
از پاسختون کمال تشکر رو دارم.
اگه لطف کنید یه توضیح مختصری هم درموردش بدین دیگه خیلی شرمنده کردید بنده رو

تو تیبل tags واسه هر تگ یه id تعیین میشه ! و تو تیبل tag_relations پست رو به تگ وصل می کنه
این query میاد بر اساس تعداد تکرار تگ تو tag_relations تگ هارو مرتب میکنه

kabootar_y
چهارشنبه 28 آبان 1393, 22:47 عصر
تا اینجاش خیلی عالی بود و باز هم تشکر فراوان از شما دوست عزیز

فقط یه راهی سراغ دارید که بتونم تمام id های تگ های ثبت شده رو در جدول جدید این طوری ثبت کنم؟

یعنی میشه کوئری نوشت که با اجرای اون همه id های ثبت شده رو در چند مرحله در جدول جدید
tag_relations ثبت کرد؟

تعداد رکوردهام در جدول article حدود 500,000 تا و در keywords حدود 300,000 تا است.

HaZeM+
چهارشنبه 28 آبان 1393, 22:56 عصر
میتونید تو یه حلقه دیتا رو تو تیبل های جدید پخش کنید .
یعنی با SELECT تیبل هارو دریافت کنید و تو حلقه قرار بدید .
بعد تو حلقه تک تک INSERT کنید جوری که میخواید .

kabootar_y
چهارشنبه 28 آبان 1393, 23:21 عصر
باز هم تشکر از جواب های مفید و همکاری صادقانه شما
برایتان آرزوی سلامتی و سربلندی می کنم

bagherok
چهارشنبه 28 آبان 1393, 23:32 عصر
مثل اینکه صورت سوالتون به کل عوض شد!!!

قبلش یه بک آپ داشته باشید از جدولتون

بعد
اول این
split procedure
رو اجرا کنید



DELIMITER $$
DROP PROCEDURE IF EXISTS create_view $$
CREATE PROCEDURE create_view( table_name VARCHAR(256), field_name VARCHAR(256), prefix VARCHAR(256) )
BEGIN
DROP VIEW IF EXISTS table_view;
SET @stm = CONCAT( 'CREATE VIEW table_view AS SELECT ', field_name, ', ', prefix, ' FROM ', table_name );
PREPARE stmt FROM @stm;
EXECUTE stmt;
DEALLOCATE prepare stmt;
END; $$
DELIMITER ;

DELIMITER $$
DROP PROCEDURE IF EXISTS split_table $$
CREATE PROCEDURE split_table( field_name VARCHAR(256), prefix VARCHAR(256), delim VARCHAR(16) )
BEGIN
DECLARE read_field VARCHAR(256);
DECLARE read_prefix VARCHAR(256);
DECLARE occurance int default 0;
DECLARE i INT DEFAULT 0;
DECLARE splitted_field VARCHAR(60);
DECLARE done int default 0;
DECLARE cur CURSOR FOR SELECT * FROM table_view;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET @stm = CONCAT( 'DROP TABLE IF EXISTS ', field_name, '_list' );
PREPARE stmt FROM @stm;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @stm = CONCAT( 'CREATE TABLE ', field_name, '_list( ', prefix, ' VARCHAR(256), ', field_name, ' VARCHAR(256) )' );
PREPARE stmt FROM @stm;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
OPEN cur;
read_loop: LOOP
FETCH cur INTO read_prefix, read_field;
IF done THEN
LEAVE read_loop;
END IF;
SET occurance = (SELECT LENGTH(read_field) - LENGTH(REPLACE(read_field, delim, '') ) + 1 );
SET i = 1;
WHILE i <= occurance DO
SET splitted_field = REPLACE( (SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(read_field, delim, i), length(SUBSTRING_index(read_field, delim, i - 1)) + 1), ',', '') ), delim, '');
SET @stm = CONCAT( 'INSERT INTO ', field_name, '_list VALUES ("', read_prefix, '", "', splitted_field, '")' );
PREPARE stmt FROM @stm;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET i = i + 1;
END WHILE;
END LOOP;
CLOSE cur;
END; $$
DELIMITER ;

DELIMITER $$
DROP PROCEDURE IF EXISTS split_column $$
CREATE PROCEDURE split_column( table_name VARCHAR(256), field_name VARCHAR(256), prefix VARCHAR(256), delim VARCHAR(16) )
BEGIN
CALL create_view( table_name, prefix, field_name );
CALL split_table( field_name, prefix, delim );
DROP VIEW IF EXISTS table_view;
END; $$
DELIMITER ;

وبعد اینا رو

CALL split_column('article', 'id', 'Keywords_id', ',' );
CREATE TABLE articles_id__Keywords_id SELECT * FROM article;

وبعد فیلد Keywords_id از جدول article رو حذف کنید.

به همین سادگی:گیج: