Hi Kevin
The problem with what you are trying to do is that you're mixing
string values with integer rankings, and Sphinx treats both
differently... but I'm thinking there might be a good way forward.
In your Person model, have separate associations for each skill level,
like so:
has_many :expert_skills, :through :abilities, :conditions =>
{:expertise => 3}
has_many :intermediate_skills, :through :abilities, :conditions =>
{:expertise => 2}
has_many :basic_skills, :through :abilities, :conditions =>
{:expertise => 1}
And then, you can create fields for each, and give them specific
weightings:
define_index do
# ...
indexes expert_skills.title, :as => :expert_skills
indexes intermediate_skills.title, :as => :intermediate_skills
indexes basic_skills.title, :as => :basic_skills
set_property :field_weights => {
"expert_skills" => 30,
"intermediate_skills" => 10,
"basic_skills" => 1
}
Of course, tweak those field weights as you wish.
Then a search like:
Person.search "juggling", :match_mode => :extended
Should return people who are experts at juggling before those who are
intermediate, and well before those who are basic.
Hopefully this helps.
Cheers
--
Pat
On 10/04/2009, at 3:52 AM, Kevin Monk wrote:
>
> This is the actual controller from my app
>
> def index
> conditions ||= {}
> keywords ||= nil
> if params[:search]
> model_conditions = {:gender => ['?', params[:search]
> [:search_gender]]} unless params[:search][:search_gender] == 'Either'
> conditions[:tag_standard] = ['?', params[:search]
> [:minimum_standard]] unless params[:search][:minimum_standard] == '0'
> keywords = params[:search][:search_keywords]
> end
> #...@models = Model.search keywords, :include =>
> [:photos, :main_photo], :order => :tag_standard, :conditions =>
> model_conditions, :page => params[:page], :per_page => 20
> m_ids = Tagging.search(keywords, :order_by
> => :tag_standard, :group_by => "model_id", :group_function
> => :attr, :per_page => 10000).map { |t| t.model_id }.flatten.uniq
> @models = Model.find(:all, :include =>
> [:photos, :main_photo], :conditions => ['id IN (?)', m_ids])
> @models = @models.paginate(:page => params[:page], :per_page =>
> 20)
> # look at
> http://stackoverflow.com/questions/79632/rubyrails-collection-to-collection
> #...@models = @skills.collect(&:model) ### THIS CREATES TOO MANY SQL
> CALLS
>
> @lightboxes = Lightbox.find(:all, :include => :models)
> respond_to do |format|
> format.html # index.html.erb
> format.xml # index.xml.erb
> end
> end
>
> and this is the Model file
> ... yes I know I've got a model called Model but that's not the point:
>
> class Model < ActiveRecord::Base
> has_many :picks, :dependent => :destroy
> has_many :lightboxes, :through => :picks
> has_many :taggings, :dependent => :destroy
> has_many :tags, :through => :taggings
> has_many :photos, :dependent => :destroy
> has_one :main_photo, :class_name => 'Photo', :conditions =>
> {:is_main_image => true}
> has_attached_file :featured_photo, :styles => { :thumbnail =>
> "67x67#" },
> :url => "/system/
> featured_photos/:id/:style/:basename.:extension",
> :path => ":rails_root/public/system/
> featured_photos/:id/:style/:basename.:extension"
>
> validates_attachment_presence :featured_photo, :if => :is_featured?
> validates_attachment_size :featured_photo, :less_than => 1.megabytes
> validates_attachment_content_type :featured_photo, :content_type =>
> ['image/jpeg', 'image/png']
> after_update :save_photos
>
> define_index do
> indexes [first_name, surname], :as => :full_name
> indexes gender
> end
>
> and this is the Taggings class
>
> class Tagging < ActiveRecord::Base
> belongs_to :model
> belongs_to :tag
>
> define_index do
> indexes tag(:name), :as => :tag_name
> has taggings.standard, :as => :tag_standard
> has model_id
> end
>
> end
>
>
> I've spent all day trying to find a way to deal with this. Looking
> through the Sphinx documents reading my Peepcode TS PDF and attemtping
> to search over multiple models. None of which seemed to get me to
> where I wanted to be. This still doesn't order by the ability as it's
> only the set of Skills that are ordered. Once these are mapped onto
> the parent models the ordering is lost. I can't be doing anything that
> unusual can I?
>
>
>
> On Apr 8, 4:38 pm, Kevin Monk <[email protected]> wrote:
>> Hello Tom,
>>
>> Once again - Thanks for your response.
>>
>> This still isn't quite what I'm looking for though as It will still
>> produce a list of the expertise as a list of expertise values i.e. a
>> document will have MVA values of 3,2,2,1,2,3,1 but their is no
>> association between the expertise and the skill that it's in.
>>
>> When i tried it as you described it would return people who were
>> experts in something but not necessarily "juggling" and all those who
>> could juggle. I'm going to attack it again and see what I come up
>> with. In the mean time any help would be appreciated.
>>
>> On Apr 7, 8:25 pm, Tom Davies <[email protected]> wrote:
>>
>>> Hey Kevin,
>>
>>> Sorry I misunderstood your question (i.e - skipped over the
>>> important
>>> details :) ).
>>
>>> You may want to look into multi-valued
>>> attributes:http://www.sphinxsearch.com/docs/current.html#mva
>>> . In Thinking Sphinx
>>> you specify them using the :has syntax.
>>
>>> The one catch is the MVAs must be integers.
>>
>>> So you could add:
>>
>>> has abilities.id, :as => :experience_levels
>>
>>> And add:
>>
>>> :conditions => {:experience_levels => 3}
>>
>>> to your search options to get you Persons who are at least an expert
>>> in one thing.
>>
>>> You could also add:
>>
>>> has skills(:id), :as => :skill_ids
>>
>>> And then get back a list of all the skill ids the person has which
>>> could also be used for conditions or faceting.
>>
>>> You can also sort your results like I said before to put someone who
>>> is an experts (in any skill) first:
>>
>>> :order =>"@weight DESC, experience_levels DESC"
>>
>>> This isn't exactly what you are asking but might get you closer :)
>>
>>> Tom
>>
>>> On Apr 6, 6:34 pm, Kevin Monk <[email protected]> wrote:
>>
>>>> Thanks for your response Tom, I don't think that this would work
>>>> though as all the skills would be concatenated into a single
>>>> field and
>>>> so would the expertise. I imagine that a record returned would look
>>>> something like this:
>>
>>>> Name: Joe Bloggs
>>>> Skills: Eating Juggling Fishing German Kung Fu
>>>> Expertise: 3 1 2 2 3
>>
>>>> Joe Bloggs is great at eating and he's great at Kung Fu but if I
>>>> search for "Joe Bloggs", Eating or "Kung Fu" then he should be
>>>> appearing near the top. With the concatenated fields there's no
>>>> way to
>>>> match up Kung Fu with the 3 or Juggling with the 1. If I order by
>>>> the
>>>> expertise then it's merely going to return.... well I don't know
>>>> what
>>>> it'll return but there's no method of identifying the skill with
>>>> the
>>>> expertise. If I do skills search i.e. Skill.search
>>>> "juggling", :order
>>>> => expertise then this would work because I'd have an array of the
>>>> skills and expertise but I also want to search by name which is
>>>> in the
>>>> parent (Person) model.
>>
>>>> The end result is that I want an array of people with either that
>>>> name, or those skills.
>>
>>>> I'm starting to think that my best best is to search Skills and
>>>> group
>>>> by the foreign key - person id. Then retrieve those people and
>>>> combine
>>>> them with a seperate People.search "keywords". I've seen that you
>>>> can
>>>> do a multiple class search but I only want one class type
>>>> (People) to
>>>> be in the search results.
>>
>>>> Confused? I am.
>>
>>>> If I sort this out then I'd be happy to write it up as a Blog
>>>> Post for
>>>> other developers.
>>
>>>> On Apr 5, 8:00 pm, Tom Davies <[email protected]> wrote:
>>
>>>>> For the sorting try (@weight makes sure relevancy is the first
>>>>> sort
>>>>> order with most relevant first):
>>
>>>>> :order =>"@weight DESC, expertise DESC"
>>
>>>>> For the only expert try:
>>
>>>>> :conditions => {:expert => 3}
>>
>>>>> On Apr 2, 8:15 pm, Kevin Monk <[email protected]> wrote:
>>
>>>>>> Apologies for the title. I was thinking for ages before I came
>>>>>> up with
>>>>>> that. I've been racking my brain over this for a few hours now
>>>>>> and
>>>>>> would appreciate any help with this.
>>
>>>>>> I have the following model:
>>
>>>>>> class Person < ActiveRecord::Base
>>
>>>>>> has_many :abilities
>>>>>> has_many :skills, :through => :abilities
>>
>>>>>> define_index do
>>>>>> # fields
>>>>>> indexes [:first_name, :last_name], :as => :name, :sortable
>>>>>> => true
>>>>>> indexes abilities.standard, :as => :expertise, :sortable =>
>>>>>> true
>>>>>> # where 3 - Expert, 2 - Intermediate, 1 - Basic
>>>>>> indexes skills.title, :as => :skills_title
>>>>>> end
>>>>>> end
>>
>>>>>> Supposing I have a single search text box and I wanted to
>>>>>> search for a
>>>>>> person who could "juggle" but i'd like to order the results by
>>>>>> expertise so that the expert jugglers came top. I would like all
>>>>>> jugglers to be returned as search results but with experts being
>>>>>> returned at the top. How might I search for this?
>>
>>>>>> Person.search "juggler", :order => :expertise
>>
>>>>>> This isn't going to work as presumably ....
>>
>>>>>> indexes abilities.standard, :as => :expertise, :sortable => true
>>
>>>>>> ... just concatenates all the standards into a single field
>>>>>> irrespective of whether that ability is in "juggling"
>>
>>>>>> Additionally... How could I set up a condition to only return
>>>>>> expert
>>>>>> jugglers?
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Thinking Sphinx" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/thinking-sphinx?hl=en
-~----------~----~----~----~------~----~------~--~---