Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wyciagniecie tagów z mysqla
Forum PHP.pl > Forum > PHP
Dinth
Jestem początkujacy w PHP+MySQL (szczególnie w tym drugim), wiec prosze o wyrozumiałość.

Mam w MySQLu prosta tabele article, a w niej: title (text),text (text),tags (varchar[50]).
Ze skryptem tworzącym "tag cloud" nie mialem wiekszych problemow, w necie jest mnostwo rozwiazan i mozna je latwo dostosowywac do swoich potrzeb.
U mnie wyglada to tak:
  1. <?php
  2. $query = "SELECT tags FROM articles ORDER BY RAND()";
  3. $result = mysql_query($query) or die ('Error : ' . mysql_error());
  4.  
  5. while($t = mysql_fetch_array($result)) {
  6. $db = explode(', ', $t[0]);
  7.  
  8. while(list($key, $value) = each($db)){
  9.  $tags[$value] += 1;
  10. }
  11. }
  12. ?>


Jednak problem zaczął się gdy chce wyciągnać z MySQLa i wyswietlic wszystkie (czy najlepiej 20 ostatnich) artykuly zawierające dany tag. Wogole nie wiem ja sie za to zabrac, ma ktos jakis pomysl?
Kicok
Cytat
w necie jest mnostwo rozwiazan i mozna je latwo dostosowywac do swoich potrzeb.


Trafiłeś na najgorsze rozwiązanie z możliwych tongue.gif


Rozbij to na 3 tabele:
Kod
articles
+------------+-...
| article_id | ...
+------------+-...
|      1     | ...
|      2     | ...
|     23     | ...


Kod
tags
+--------+----------+
| tag_id | tag_name |
+--------+----------+
|    1   |    book  |
|    2   |    comp  |
|    3   |   trees  |
|  123   |    two   |


Kod
articles_tags
+--------+------------+
| tag_id | article_id |
+--------+------------+
|    1   |      1     |
|    1   |      2     |
|    1   |     13     |
|    2   |      1     |
|    2   |     13     |
|   32   |      2     |
|   32   |    111     |
|   34   |     54     |



Następnie poczytaj w manualu MySQL'a o łączeniu tabel w zapytaniach. Przykładowe zapytania:

1. Tagi danego artykułu
  1. SELECT t.tag_name
  2. FROM articles_tags AS at
  3. JOIN tags AS t ON ( at.tag_id = t.tag_id )
  4. WHERE ( at.article_id = 12345 )


2. Artykuły w których występuje dany tag
  1. SELECT a.*
  2. FROM articles_tags AS at
  3. JOIN articles AS a ON ( at.article_id = a.article_id )
  4. WHERE ( at.tag_id = 321 )


3. 5 najpopularniejszych tagów
  1. SELECT t.tag_name, COUNT(*) AS count
  2. FROM article_tags AS at
  3. JOIN tags AS t ON ( at.tag_id = t.tag_id )
  4. GOURP BY t.tag_id
  5. ORDER BY count DESC LIMIT 5




Pisane z palca, więc mogą być błędy. Ale ogólny zarys działania chyba przedstawiłem ;]
Dinth
Hmm w sumie itak to mialem zmieniac w przyszlosci, bo jednym z zalozen serwisu jest to zeby kazdy user mogl tagowac kazdy artykul , a wyswietlane byly tagi najpopularniejsze dla danego artykulu.

Czy twoj sposob da sie zaadoptowac do tego ?
soon
A jak w praktyce wyglądałoby dodawanie artykułów wraz z tagami? Bo nie bardzo umiem to sobie wyobrazić sad.gif
andrew1985
Cytat(Kicok @ 20.09.2007, 11:44:24 ) *
Trafiłeś na najgorsze rozwiązanie z możliwych tongue.gif


Rozbij to na 3 tabele:
Kod
articles
+------------+-...
| article_id | ...
+------------+-...
|      1     | ...
|      2     | ...
|     23     | ...


Kod
tags
+--------+----------+
| tag_id | tag_name |
+--------+----------+
|    1   |    book  |
|    2   |    comp  |
|    3   |   trees  |
|  123   |    two   |


Kod
articles_tags
+--------+------------+
| tag_id | article_id |
+--------+------------+
|    1   |      1     |
|    1   |      2     |
|    1   |     13     |
|    2   |      1     |
|    2   |     13     |
|   32   |      2     |
|   32   |    111     |
|   34   |     54     |



Następnie poczytaj w manualu MySQL'a o łączeniu tabel w zapytaniach. Przykładowe zapytania:

1. Tagi danego artykułu
  1. SELECT t.tag_name
  2. FROM articles_tags AS at
  3. JOIN tags AS t ON ( at.tag_id = t.tag_id )
  4. WHERE ( at.article_id = 12345 )


2. Artykuły w których występuje dany tag
  1. SELECT a.*
  2. FROM articles_tags AS at
  3. JOIN articles AS a ON ( at.article_id = a.article_id )
  4. WHERE ( at.tag_id = 321 )


3. 5 najpopularniejszych tagów
  1. SELECT t.tag_name, COUNT(*) AS count
  2. FROM article_tags AS at
  3. JOIN tags AS t ON ( at.tag_id = t.tag_id )
  4. GOURP BY t.tag_id
  5. ORDER BY count DESC LIMIT 5




Pisane z palca, więc mogą być błędy. Ale ogólny zarys działania chyba przedstawiłem ;]



Tak koncepcja jest jak najbardziej poprawna. Sam taką stworzyłem do serwisu i sprawuje się jak najbardziej OK.

Co do zapisu to najpierw rozbijasz ciąg np. "dupa tag2 jasia bla" funkcją explode, i sprawdzasz SELECTEM czy kolejne taki są w tabeli "tags" jeżeli nie to zapisujesz np,. tag "dupa" do tabeli "tags", natomiast jeżeli istnieje dany tag w bazie to wyciągasz jego ID. Jak masz ID tagu to zapisujesz go wraz z ID artykułu do tabeli "articles_tags". I tak zapisujesz każdy tag z osobna.
soon
no to nieźle kombinowania będzie.

1. - mam powtórzyć zapytanie dla każdego z tagów
1.a - pierw sprawdzam czy istnieje, jeśli tak to wyciągam id,
1.b - jeśli nie to dodaje i wyciągam id
2. - po zakończeniu wszystkich zapytań, mam spis id tagów i id artykułu
3. - dodaje id_tag & id_art tyle razy ile miałem tagów do tabeli arts_tags

A jak mam wykonać punkt 1.b? Tj. jak od razu dostać ID właśnie dodanego rekordu?

takie coś naskrobałem sobie:
  1. <?php
  2. $tags = "blog ciekawostki design film fotografia google gra grafika gry humor";
  3. $one_tag = explode(" ", $tags);
  4. $while = count($one_tag);
  5. $i = 0;
  6. while($i < $while) {
  7. echo $one_tag[$i]; //tu zapytania, nie mam czasu teraz pisać ;)
  8. $i++;
  9. }
  10. ?>


w dobrym kierunku idę?

-------------
EDIT:

Na dziś:
  1. <?php
  2. global $smarty;
  3. global $db;
  4.  
  5. $tags = "blog fajne ciekawostki design film fotografia google gra xxx grafika gry hu
    mor"
    ;
  6. $one_tag = explode(" ", $tags);
  7. $while = count($one_tag);
  8.  
  9. $i = 0;
  10. while($i < $while) {
  11. $sql = "SELECT * FROM tpl_tags WHERE tag_name = '$one_tag[$i]'"; //pytamy o konkretny tag
  12. $result = $db->set_query($sql);
  13.  
  14. if ($result == 0) { // tagu nie ma w bazie
  15. echo $one_tag[$i].' - brak takiego tagu!<br />'; //więc dodajemy
  16. } else { // tag już jest w bazie
  17. echo '<b>'.$one_tag[$i].' - tag znajduje się w bazie! Posiada ID '.$result[0]['tag_id'].'</b><br />'; //więc pobieramy jego ID
  18. }
  19.  
  20. $i++;
  21. }
  22. ?>


Na razie tylko mi wypluwa. Może jutro dokończę.

-----------------------------------
EDIT:

No więc wersja finalna.

  1. <?php
  2. global $smarty;
  3. global $db;
  4.  
  5. $tags = "blog fajne ciekawostki design film fotografia google gra xxx grafika gry hu
    mor"
    ; //spis tagów
  6. $one_tag = explode(" ", $tags); //rozbijamy na pojedyńcze
  7. $while = count($one_tag); //liczymy ilość tagów, potrzebne będzie do wykonania pętli
  8.  
  9. $i = 0;
  10. while($i < $while) {
  11. $result = $db->set_query("SELECT * FROM tpl_tags WHERE tag_name = '$one_tag[$i]'"); //pytamy o konkretny tag
  12.  
  13. if ($result == 0) { // tagu nie ma w bazie
  14. $db->save_query("INSERT INTO tpl_tags (tag_id,tag_name) VALUES('','$one_tag[$i]')"); //dodajemy tag którego nie ma
  15. $show_tag_id = $db->set_query("SELECT * FROM tpl_tags WHERE tag_name = '$one_tag[$i]'"); //wyciągamy ID tagu, który właśnie dodaliśmy
  16. $tag_id = $show_tag_id[0]['tag_id']; //zapisujemy ID do zmiennej
  17. $db->save_query("INSERT INTO tpl_news_tags (tag_tag_id,tag_news_id) VALUES('$tag_id','1')"); //dodajemy ID tagu oraz ID newsu do łączącej je tabeli news_tags
  18. } else { // tag już jest w bazie
  19. $show_tag_id = $db->set_query("SELECT * FROM tpl_tags WHERE tag_name = '$one_tag[$i]'"); //wyciągamy ID tagu, który znajduje się już w bazie
  20. $tag_id = $show_tag_id[0]['tag_id']; //zapisujemy ID do zmiennej
  21. $db->save_query("INSERT INTO tpl_news_tags (tag_tag_id,tag_news_id) VALUES('$tag_id','1')"); //dodajemy ID tagu oraz ID newsu do łączącej je tabeli news_tags
  22. }
  23.  
  24. $i++;
  25. }
  26. ?>


Jeżeli są jakieś błędy i coś można by wykonać inaczej/szybciej to czekam na wasze sugestie.

Pozdrawiam
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.