:store => :yes doesn't work in some cases

I’m not really sure if this is a bug, but it makes my search results
look a bit strange. I have an acts_as_ferret declaration that looks
like:

acts_as_ferret :store_class_name => true, :remote => true, :fields =>
{
:ferret_name => { :store => :yes, :boost => 2 },
:ferret_content => { :store => :yes } }

I store both fields so that I don’t need to load each result model from
the rails DB when displaying the results. This is the code that I use to
show each result:

highlighted_name = result.highlight(params[:q], :field => :ferret_name,
:pre_tag => “”, :post_tag => “”, :excerpt_length =>
150, :num_excerpts => 1)

highlighted_content = result.highlight(params[:q], :field =>
:ferret_content, :pre_tag => “”, :post_tag => “”,
:excerpt_length => 150, :num_excerpts => 1)

Generally this all works fine. The problem happens when the ferret_name
of my model is a word that is skipped by the ferret tokenize. For
example if I have a model with:

ferret_name: about
ferret_content: rails

Then when I do a search for ‘rails’ the result will be found, but the
results highlighted_name will be blank. So I don’t see the name of the
model in the result. This seems to be a special case, because generally
words like “about” and “the” that are skipped by the tokenizer will
still be stored when :store => :yes when they are in a phrase.

I hope that makes some sense. For now I can get around the problem by
checking for the blank case and loading the value from the model
directly, but things would be easier if :store => :yes would just always
store the field value.

Thanks for any help,
Jesse

Hi!

Imho the highlight method is supposed to return nil when nothing to
highlight is there. In this case just retrieve the content of the field
with result.name or doc[:name] if working with Ferret directly.

I just checked with a plain Ferret script and it had no problems
retrieving field contents that were just a stop word. If we don’t
get this to work there might be an aaf bug, though :wink:

On Thu, Jun 07, 2007 at 04:54:57PM +0200, Jesse G. wrote:

I’m not really sure if this is a bug, but it makes my search results
look a bit strange. I have an acts_as_ferret declaration that looks
like:

acts_as_ferret :store_class_name => true, :remote => true, :fields =>
{
:ferret_name => { :store => :yes, :boost => 2 },
:ferret_content => { :store => :yes } }

[…]

Then when I do a search for ‘rails’ the result will be found, but the
results highlighted_name will be blank. So I don’t see the name of the
model in the result. This seems to be a special case, because generally
words like “about” and “the” that are skipped by the tokenizer will
still be stored when :store => :yes when they are in a phrase.

I hope that makes some sense. For now I can get around the problem by
checking for the blank case and loading the value from the model
directly, but things would be easier if :store => :yes would just always
store the field value.

What do you mean with ‘loading the value directly’?

If you used aaf’s :lazy => true option when searching, aaf would by
default not query your db in the first place, and only do so if you ask
for a non-stored field.

You can read more about this feature there:
http://www.jkraemer.net/2007/3/26/lazy-loading-with-acts_as_ferret


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

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa

Thanks for responding, I didn’t know about the :lazy option. Or at least
I didn’t understand how it worked, thanks.

Imho the highlight method is supposed to return nil when nothing to
highlight is there. In this case just retrieve the content of the field
with result.name or doc[:name] if working with Ferret directly.

Ok that’s easy enough to do, thanks.

I just checked with a plain Ferret script and it had no problems
retrieving field contents that were just a stop word. If we don’t
get this to work there might be an aaf bug, though :wink:

No that’s working correctly, I just didn’t realize that that wasn’t
loading my models (if the fields were stored).

What do you mean with ‘loading the value directly’?

If you used aaf’s :lazy => true option when searching, aaf would by
default not query your db in the first place, and only do so if you ask
for a non-stored field.

You can read more about this feature there:
http://www.jkraemer.net/2007/3/26/lazy-loading-with-acts_as_ferret

Thanks I was missing that part. Now it’s working, or almost. The on
trouble spot is that when I highlight my results the models do get
loaded. I guess is this because FerretResult doesn’t have a highlight
method, and that causes it to load the underlying model.

To get around this I’ve changed from:

result.highlight(…)

to:

result.model.aaf_index.highlight(result.id, result.model.name…)

After doing that the database is no longer hit when displaying
highlighted ferret results, but to do that I needed to add
“attr_accessor :model” to ActsAsFerret > ResultAttributes. Is there a
better way to do that? If not could you add that attr_accessor to ferret
proper?

It might also make sense to also add the highlight method to
FerretResult to avoid the model load, but I’d still like some way to
access the model class without requiring a model load since I need that
to generate the right link the the original page for each result.

I hope at least some of that makes sense :slight_smile:

Thanks again for the great toolkit.

Jesse

Jesse G. wrote:

access the model class without requiring a model load since I need that
to generate the right link the the original page for each result.

I just posted a ticket that implements this, preventing use of the
highlight method from triggering unnecessary loading of the real AR
record:

http://projects.jkraemer.net/acts_as_ferret/ticket/161


We develop, watch us RoR, in numbers too big to ignore.