Witam!
Mam bazę z tagowanymi przedmiotami, każdy ma ich kilka.
Wyszukiwarka składa się z pola tekstowego, w który wpisujemy tagi.
I tu moje pytanie…czy i jak można użyć tutaj auto_complete abo dla każdego kolejnego tagu (po przecinku) były wyświetlane możliwe tagi?
I jeszcze druga kwestia - jak zrobić aby wyniki wyszukiwania sortowane były wg trafności, tzn im więcej tagów pasuje?
Z góry dziękuje za wszelkie podpowiedzi:)
Co?
Ja bym to zrobił pewnie przez acts_as_ferret indeksujące cached_tag_list, ale mam trochę zboczenie ostatnio na punkcie Ferreta, więc jestem nieobiektywny.
Co?[/quote]
Pole tekstowe -> wpisuje po kolei tagi, oddzielając przecinkiem, ale - przy tym wpisywaniu, po każdym przecinku znów włączane jest autouzupełnianie.
Schemat działania:
w pole wpisuje “kom”, wyskakuje podpowiedź “komputery” klikam, pisze przecinek, wpisuje “dru” wyskakuje “drukarki” itp
Wiem jak to zrobić z jednym wyrazem/frazą ale jak to się ma do kilku tagów?
jquery.autocomplete jeśli używasz jQuery -> http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
Do samego searcha (backend) zastosuj jakiś silnik pełno tekstowy tak jak pisał Tomash, może być ferret, sphinx.
Jeśli Prototype i Scriptaculous to Autocompleter ma opcję tokens (control.js):
// Tokenized incremental autocompletion is enabled automatically
// when an autocompleter is instantiated with the ‘tokens’ option
// in the options parameter, e.g.:
// new Ajax.Autocompleter(‘id’,‘upd’, ‘/url/’, { tokens: ‘,’ });
// will incrementally autocomplete with a comma as the token.
// Additionally, ‘,’ in the above example can be replaced with
// a token array, e.g. { tokens: [’,’, ‘\n’] } which
// enables autocompletion on multiple tokens. This is most
// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
Testy sphinxa + thinking sphinx wykazały, że użycie w moim przypadku pełnotekstowej wyszukiwarki jest chyba błędne. Tutaj wyszukiwarka znajduje kontent który zawiera wszystkie wpisane słowa a mi chodzi o to aby był dobry “matching”.
Czyli jeśli mam otagowany produkt to wpisując w wyszukiwarce jakieś tagi ma znaleźć produkt, który został maksymalnie określony (czyli do wyszukiwarki zostały wpisane wszystkie tagi które on posiada). Przykład może lepiej zobrazuje mój cel:
produkt1 posiada tagi: zielony, żółty, czarny
produkt2 posiada tagi: zielony, czerwony
produkt3 posiada tagi: zielony, czerwony, niebieski
do wyszukiwarki wpisujemy: czerwony, zielony
wyniki posortowane:
produkt2 (wszystkie tagi użyte)
produkt3 (brakuje jednego tagu)
produkt1 (brakuje więcej tagów)
Ostatecznie wykorzystałem plugin acts_as_taggable. Ok, ale teraz ciągle pozostaje kwestia sortowania. Jakieś pomysły, propozycje, podpowiedzi?
Sprawa wydaje się dość prosta. Otóż najpierw wyszukujemy id tagów po czym robimy zapytanie w którym ma nam podać count taggingsów które tag_id mają jeden z wyszukanej wartości grupowany po product_id, sortowany to count. Czyli otrzymujemy ostatecznie pary [product_id, searched_tags_count] co chyba w całości rozwiązuje problem?
Dopiero się uczę, więc byłbym wdzięczny jeśli rozpisałbyś to w formie kodu.
Poczytaj o takich parametrach zapytań SQL (oraz odpowiadających im opcjom Activerecord) jak GROUP BY oraz COUNT. Poczytaj też jak działa / co można robić za pomocą acts_as_taggable(_on_steroids).
Więcej nie bardzo mogę teraz napisać (kolega Imanel takoż), bo wyjeżdżamy właśnie na Masters of Rock do Vizovic
Najpierw wyszukujemy id tagów(to jakaś specjalna funkcja acts_as_taggable - nie pamiętam nazwy więc to zostawię Tobie)
Dalej mając tablicę tags_ids dajemy:
Taggings.count( :group => :product_id, :conditions => { :tag_id => tags_id } )
Dzięki temu otrzymujemy tablicę typu:
[ [ product_id, count ], [product_id, count] … ]
Pewnie będzie trzeba dodać jakieś sortowanie czy limity bo(jak powiedział Tomash) nie za bardzo mamy teraz czas to sprawdzać, ale myślę że nie powinno być to trudne
Ciągle nie wiem czy dobrze mnie zrozumieliście. Oczywiście dzięki za fatyge:)
Jestem na takim etapie - mam już znalezione wszystkie rekordy, które mają przynajmniej jeden z wyszukiwanych tagów. Teraz jest taka kwestia - aby w każdym ze znalezionych rekordów policzyć ile tagów brakuje i wg tego grupować wyniki. Na górze te, które mają 0 itd. I tu kolejne pytanie początkującego - gdzie? W modelu, kontrolerze? I jakim sposobem dodać gdzieś tą informacje(ilość brakujących tagów).
Jeszcze raz dzięki za pomoc!
@products = Product.tagged_with(params[:search].split(/,?\s/), :on => :tags)
@tags = Tag.find_by_name(params[:search].split(/,?\s/))
Mam listę znalezionych produktów i tagów, które zostały wpisane w wyszukiwarkę, ale co dalej biorąc pod uwagę moje poprzednie pytanie?