Boost Sorting with Acts_as_ferret?

Hey guys,

Simple question here.

I have a single index of recipes, from which I'm looking at the

following fields: Name, Ingredient Text, Tags, and Description.

The key is, I want to show all the results that come from Name,

before I show any of the results from Ingredient Text, Tags, or
Description.

I tried doing this:

acts_as_ferret :fields => {
:name => {:boost => 9000, :store => :yes},
:ingredients => {:boost => 6000, :store => :yes},
:tags => {:boost => 3000, :store => :yes},
:description => {:boost => 1, :store => :yes}}

I figured if I put huge boost on my fields, the "name" results would

always come before ingredients (no matter what the score).

Can anyone throw me any ideas on how one might do this?  Here is an

explain of one of my first results. Perhaps I need to change the
rounding of my score? I dunno.

Basque chicken scored 1.0
3291.866 = product of:
6583.732 = sum of:
674.6201 = weight(ingredients_without_brackets:chicken in 12670),
product of:
0.2805449 = query_weight(ingredients_without_brackets:chicken),
product of:
3.13109 = idf(doc_freq=2145)
0.08959977 = query_norm
2404.677 = field_weight(ingredients_without_brackets:chicken in
12670), product of:
1.0 = tf(term_freq(ingredients_without_brackets:chicken)=1)
3.13109 = idf(doc_freq=2145)
768.0 = field_norm(field=ingredients_without_brackets,
doc=12670)
5909.112 = weight(tags_with_spaces:chicken in 12670), product of:
0.4547729 = query_weight(tags_with_spaces:chicken), product of:
5.075603 = idf(doc_freq=306)
0.08959977 = query_norm
12993.54 = field_weight(tags_with_spaces:chicken in 12670),
product of:
1.0 = tf(term_freq(tags_with_spaces:chicken)=1)
5.075603 = idf(doc_freq=306)
2560.0 = field_norm(field=tags_with_spaces, doc=12670)
0.5 = coord(2/4)

Thanks in advance,

-Gregg

Hi!

On Sat, Feb 03, 2007 at 01:00:49AM +0100, Gregg P. wrote:

I tried doing this:

acts_as_ferret :fields => {
:name => {:boost => 9000, :store => :yes},
:ingredients => {:boost => 6000, :store => :yes},
:tags => {:boost => 3000, :store => :yes},
:description => {:boost => 1, :store => :yes}}

I figured if I put huge boost on my fields, the "name" results would

always come before ingredients (no matter what the score).

souunds reasonable.

Can anyone throw me any ideas on how one might do this?  Here is an

explain of one of my first results. Perhaps I need to change the
rounding of my score? I dunno.

Scores are always between 0 and 1. You might want to set some less
aggressive values for your boost values, it’s more the relation between
them that counts, than their absolute value.

However that way you won’t have a guarantee that the sorting will be
as you intend. If this really is that important, run an explicit
search only against the name field, and then one against all fields,
excluding the hits you got with the first search:

get results where name fields match (might be good to escape at least

‘(’ and ‘)’ in query):

name_results = Recipe.find_by_contents(%{name:(#{query})})

now get results where other fields match, but exclude those we already

have:

ids = name_results.map(&:id).join ’ OR ’
other_results = Recipe.find_by_contents(%{#{query} -id:(#{ids})"})

Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

Jens,

Thanks for the suggestion.  However, in this case the #ids field 

could contain a thousand ids, which I’m not sure is good.

However, you just gave me another idea that involves 4 queries, but 

it doesn’t seem to be working as it should. Can you see why?

q = “chicken”

lets get the total (where it’s found in all the fields)

total = index.search_each(q) do |doc, score| end
puts “Total should be = #{total}”

find count of just name results

query = qp.parse("+name:(#{q})")
puts query.to_s
total = index.search_each(query) do |doc, score| end
puts “total with name = #{total}”

find all results where query is in ingredients but excluding the name

results
query = qp.parse("+ingredients:(#{q}) -name:(#{q})")
puts query.to_s
total = index.search_each(query) do |doc, score| end
puts “total with ingredients = #{total}”

query = qp.parse("+tags:(#{q}) -name:(#{q}) -ingredients:(#{q})")
puts query.to_s
total = index.search_each(query) do |doc, score| end
puts “total with tags = #{total}”

query = qp.parse("+description:(#{q}) -name:(#{q}) -ingredients:(#{q})
-tags:(#{q})")
puts query.to_s
total = index.search_each(query) do |doc, score| end
puts “total with desc = #{total}”

You would think that these fields would add up, but here are the 

results:

Total should be = 2225

name:chicken
total with name = 1028

+ingredients:chicken -name:chicken
total with ingredients = 2115

+tags:chicken -name:chicken -ingredients:chicken
total with tags = 18

+description:chicken -name:chicken -ingredients:chicken -tags:chicken
total with desc = 1

As you can see, the numbers aren’t adding up, but shouldn’t they be?

Thanks in advance for your help.