Wyszukiwarka, auto_complete

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 :smiley:

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 :slight_smile:

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?