Skip to content
jkraemer edited this page Sep 13, 2010 · 1 revision

Gotchas

Searches for common words return no results

By default aaf uses Ferret’s default analyzer, which will filter out the stop words listed in Ferret::Analysis::FULL_ENGLISH_STOP_WORDS from both your content and your queries. To use an analyzer with an empty (or customized) list of stop words, create your own and add it to your acts_as_ferret call:

STOP_WORDS = []
acts_as_ferret { :fields => [:field1, :field2] }, { :analyzer => Ferret::Analysis::StandardAnalyzer.new(STOP_WORDS) }

Corrupt Index

If you get an error such as

EOFError: End-of-File Error occured at <except.c>:103 in xpop_context
Error occured in store.c:197 - is_refill
        current pos = 0, file length = 35

try removing the index directory.

Continuous Builder, AAF and *nix

When using this combination of tools, beware the ownership of index files as AAF will generate index files while running the Continuous Builder tests. These files will then have permissions that will prevent users other than the CB user (typically svn) from running AAF. My approach is to try to get Continuous Builder to work using group permissions. Here are some tricks to accomplish this and work around the permissions pitfall:

  • Always manipulate the CB environment with umask 0002 (or 000n). This ensures that group permissions are not restricted at creation.
  • Change the permissions of all directories to have the Set GID flag (g+s). This ensures that newly created files have the same group owner as the containing directory instead of the creating user’s default group. I use this command to set the flag recursively:
# sudo find . -type d -exec chmod g+s "{}" \;
  • Change the group owner of all directories and files to be the svn group:
# sudo chgrp -R svn <ProjectDir>/*
  • Change the current permissions of all directories and files to have group permissions equivalent to the user permissions:
# sudo chmod -Rf g=u <ProjectDir>/*

Now you should be able to create files and directories manually (like AAF files) in the CB directory and still use CB succesfully.

Upgrading to Ferret 0.11.1

Doesn’t seem to work…
You get a stack on line 110 in acts_as_ferret.rb when trying to restart mongrel.

RAILS_ROOT/config/../vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:267:in @load_missing_constant’: uninitialized constant Ferret (NameError)

Not to mention it looks like you also need to regenerate your indexes.

Field :id already exists

Getting this error? It seems that Acts_As_Ferret (or Ferret) automagically adds the ‘id’ field to your index. No need to be tell AAF to index over this field manually.

Specifying your own Analyzer

Strange problems when using custom Analyzers

If you get strange errors (like NameError: cannot remove Object::Document) when using your own Analyzer implementation, check how you declared it.

Inheriting from Ferret::Analysis::Analyzer and putting the include Ferret::Analysis inside the class declaration fixed problems for several people (see http://www.ruby-forum.com/topic/90752#188252)

class StemmedAnalyzer < Ferret::Analysis::Analyzer
  include Ferret::Analysis
  def initialize(stop_words = ENGLISH_STOP_WORDS)
    @stop_words = stop_words
  end
  def token_stream(field, str)
    StemFilter.new(StopFilter.new(LowerCaseFilter.new(StandardTokenizer.new(str)), @stop_words))
  end
end

Method signature for the acts_as_ferret method

Pre-0.4.1 versions of aaf take two hashes as arguments:

acts_as_ferret(options={}, ferret_options={})

So that means if you want to pass options, and ferret_options, you need to use:

acts_as_ferret({:fields => {:title => {:store => :yes}, 
                  :body  => {:store => :yes}}, 
                  :store_class_name => true}, 
                 {:analyzer => MyStandardAnalyzer.new})

See: http://osdir.com/ml/lang.ruby.ferret.general/2006-12/msg00037.html for more information on this.

Since 0.4.1, acts_as_ferret also supports the :ferret option in the first hash to make things more obvious:

acts_as_ferret({:fields => { :title => {:store => :yes }, 
                             :body  => {:store => :yes } }, 
                :store_class_name => true, 
                :ferret => { :analyzer => [[MyStandardAnalyzer]].new } )

Using the multi-model search

Requires all indexes to already exist. You must build these indexes first before attempting a multi-model search.

Here’s a rake task — insert your own models:

namespace :ferret do
  desc "Rebuild all Indexes"
  task :rebuild_all_indexes => [:environment] do
    %w(Model1 Model2 Model3).each { |s| s.constantize.rebuild_index }
  end
end