Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Newsy sortowanie po tagach
Eagle
post 1.02.2009, 18:33:38
Post #1





Grupa: Zarejestrowani
Postów: 170
Pomógł: 14
Dołączył: 16.03.2007

Ostrzeżenie: (0%)
-----


Witam smile.gif

Potrzebuje pobrać wszystkie newsy które są przypisane do danego tagu wraz z tagami z jakimi został utworzony.

Mając w bazie
Kod
       ID | TREŚĆ | PRZYPISANETAGI
       1 | Treść pierwszego newsa | świat;dom;szklanka
       2 | Treść drugiego newsa | świat;czerwony
       3 | Inny news | czerwony;kolorowy;niebieski


i szukając newsa z takiem 'świat' potrzebuje wyświetlnić
Kod
       1 | Treść pierwszego newsa | świat;dom;szklanka
       2 | Treść drugiego newsa | świat;czerwony


Struktura
Kod
       News
       n_id
       tresc
      
       Tag
       tag_id - id
       tag_name - nazwa tagu (np.świat)
      
       News_tags (połączenie tagów z odpowiednim id)
       tag_id
       news_id


Używając zapytania
  1. SELECT `news` . * , GROUP_CONCAT( `tag`.`tag_name`
  2. ORDER BY `tag`.`tag_name`
  3. SEPARATOR ';' ) AS `tags`
  4. FROM `tag` LEFT JOIN `news_tags` ON `news_tags`.`tag_id` = `tag`.`tag_id`
  5. LEFT JOIN `news` ON `news`.`a_id` = `news_tags`.`n_id`
  6. WHERE `tag`.`tag_name` LIKE 'NAZWA_TAGU' OR `tag`.`tag_name` LIKE '%'
  7. GROUP BY `news`.`n_id`


Dostaje to o potrzebuje i dodatkowo bonusowo zwraca mi pusty news (same wartości null) wraz ze wszystkimi możliwymi tagami.
Kod
     NULL | NULL | świat;dom;szklanka;czerwony;kolorowy;konik;ble;zupa.....
     1 | Treść pierwszego newsa | świat;dom;szklanka
     2 | Treść drugiego newsa | świat;czerwony


Gdy zmienie zapytanie na:
  1. SELECT `news` . * , GROUP_CONCAT( `tag`.`tag_name`
  2. ORDER BY `tag`.`tag_name`
  3. SEPARATOR ';' ) AS `tags`
  4. FROM `tag` LEFT JOIN `news_tags` ON `news_tags`.`tag_id` = `tag`.`tag_id`
  5. LEFT JOIN `news` ON `news`.`a_id` = `news_tags`.`n_id`
  6. WHERE `tag`.`tag_name` LIKE 'świat' OR `tag`.`tag_name` LIKE '%' AND `news`.`n_id` != NULL
  7. GROUP BY `news`.`n_id`


To dostaje newsy które powinienem dostać, jednak w polu `tags` mają tylko jeden szukany tag zamiast wszystkich do których został przypisany.

Kod
     1 | Treść pierwszego newsa | świat
       2 | Treść drugiego newsa | świat


Może ktoś wie jak poprawić zapytanie ?
Go to the top of the page
+Quote Post
blooregard
post 1.02.2009, 19:26:33
Post #2


Newsman


Grupa: Moderatorzy
Postów: 2 033
Pomógł: 290
Dołączył: 21.12.2007
Skąd: Łódź




Jeśli masz tabele MyISAM (nie InnoDB), czyli nie używasz transakcji, ustaw sobie na kolumnie z tagami index FULLTEXT i będziesz mógł wyszukiwać z niej dane przy pomocy przeszukiwania pełnotekstowego używając MATCH() ... AGAINST
To uprości Ci sprawę wyszukiwania.

Ten post edytował blooregard 1.02.2009, 19:26:54


--------------------
Life's simple... You make choices and don't look back...
Go to the top of the page
+Quote Post
Eagle
post 2.02.2009, 01:30:39
Post #3





Grupa: Zarejestrowani
Postów: 170
Pomógł: 14
Dołączył: 16.03.2007

Ostrzeżenie: (0%)
-----


Niestety nie uprości. Większość tagów ma długość 3 znaków, wyszukiwanie potrzebuje co najmniej 4

Zastanawiam się bardziej jak wyeliminować pusty wpis który jest na początku wyników.

Edit:
Ustawiłem LIMIT 1,X i jakoś żyje.
Jeżeli ktoś ma inny pomysł rozwiązania to czekam na propozycje.


Edit2:
Właśnie się zastanawiam czemu jest FROM `tag` zamist FROM `news` ...
Po zmianie wszystko działa ok.

Ten post edytował Eagle 2.02.2009, 16:07:50
Go to the top of the page
+Quote Post
złowieszczy_pan
post 2.02.2009, 16:39:51
Post #4





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 24.08.2008

Ostrzeżenie: (0%)
-----


Ja wykombinowałem coś takiego... Mam identyczny układ tabel na swojej stronie, więc przetestowałem. Mam nadzieję, że nie popełniłem błędu w zamianie nazw pól tongue.gif

  1. SELECT M.`n_id` , M.`tresc` , (
  2. SELECT GROUP_CONCAT( T.`tag_id`
  3. ORDER BY T.`tag_id`
  4. SEPARATOR ';' ) AS `tags`
  5. FROM `Tag` T
  6. JOIN `News_tags` KT ON T.`n_id` = KT.`tag_id`
  7. WHERE KT.`news_id` = M.`n_id`
  8. )
  9. FROM `News` M
  10. JOIN `News_tags` MT ON M.`n_id` = MT.`news_id`
  11. WHERE MT.`tag_id` = (SELECT `tag_id` FROM `Tag` WHERE `tag_name` = 'NAZWA TAGA')


Ale nie wydaje mi się to optymalne tongue.gif hahaha biggrin.gif

Pozdrawiam

Ten post edytował złowieszczy_pan 2.02.2009, 16:53:33
Go to the top of the page
+Quote Post
blooregard
post 2.02.2009, 16:42:56
Post #5


Newsman


Grupa: Moderatorzy
Postów: 2 033
Pomógł: 290
Dołączył: 21.12.2007
Skąd: Łódź




Cytat
Niestety nie uprości. Większość tagów ma długość 3 znaków, wyszukiwanie potrzebuje co najmniej 4


Zmieniasz ustawienia w my.cnf i juz nie musi mieć 4 znaków:

[mysqld]
ft_min_word_len= [wartosc]


--------------------
Life's simple... You make choices and don't look back...
Go to the top of the page
+Quote Post
Eagle
post 2.02.2009, 19:29:44
Post #6





Grupa: Zarejestrowani
Postów: 170
Pomógł: 14
Dołączył: 16.03.2007

Ostrzeżenie: (0%)
-----


@złowieszczy_pan:
Twoje zapytanie jest lepsze smile.gif
Bo moje przez % zwraca wszystkie tagi, wiec jakbym nic nie wyszukiwał tylko wyświetlał.
Trzeba pomyśleć jak to da się zoptymalizować (o ile się da ;P)

@blooregard
Tylko nie zawsze ma się odstęp do tego configa.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 22.06.2025 - 14:22