Skip to content

Commit

Permalink
case insensitive search + correct ordering of results + some smaller …
Browse files Browse the repository at this point in the history
…refactorings
  • Loading branch information
grosser committed Nov 18, 2008
1 parent 7af3bc2 commit 545e398
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 30 deletions.
4 changes: 4 additions & 0 deletions TESTING
Expand Up @@ -9,4 +9,8 @@ rake spec

if you have test errors by HyperEstraier cache matter
edit '${estraier_index_dir}/_conf' and set 'cachernum' parameter to 0.
(Ubuntu: /var/lib/hyperestraier/estmaster/_conf)
then restart hyperestraier
(Ubuntu: sudo /etc/init.d/hyperestraier restart)


42 changes: 24 additions & 18 deletions lib/search_do/backends/hyper_estraier.rb
Expand Up @@ -138,30 +138,36 @@ def add_attributes_to(attributes,condition)
condition.add_attr attr
end
when Hash then
attributes.each do |k,v|
next if v.blank? or k.blank?
column = @ar_class.columns_hash[k.to_s]
search_by = ((column and column.number?) ? 'NUMEQ' : 'STRINC')
k = translate_attribute_name_to_he(k)
condition.add_attr "#{k} #{search_by} #{v}"
attributes.each do |attribute,value|
next if value.blank? or attribute.blank?
search_type = search_type_for_attribute(attribute)
attribute = translate_attribute_name_to_he(attribute)
condition.add_attr "#{attribute} #{search_type} #{value}"
end
else raise
end
end

#FIXME translate numerical and date columns to NUMD/A and strings to ??/??
def search_type_for_attribute(attribute)
column_type_of(attribute) == :numeric ? 'NUMEQ' : 'iSTRINC'
end

def translate_order_to_he(order)
order_parts = order.to_s.downcase.strip.split(' ')
return order if order_parts.size > 2
return order unless a_or_d(order_parts[1])

translated = translate_attribute_name_to_he(order_parts[0])

if column = @ar_class.columns_hash[order_parts[0]]
if column.number? or [:datetime,:time,:date,:timestamp].include?(column.type)
return "#{translated} #{numd_or_numa(order_parts[1])}"
end
end
order
sort_word = (column_type_of(order_parts[0])==:numeric) ? 'NUM' : 'STR'
"#{translated} #{sort_word}#{a_or_d(order_parts[1])}"
end

#is the column numeric(numbers/dates) or string(else) ?
def column_type_of(attribute)
column = @ar_class.columns_hash[attribute.to_s]
return :string unless column
return :numeric if column.number? or [:datetime,:time,:date,:timestamp].include?(column.type)
return :string
end

def translate_attribute_name_to_he(name)
Expand All @@ -174,11 +180,11 @@ def translate_attribute_name_to_he(name)
end

#pre: string is downcased & stripped
def numd_or_numa(order_end)
def a_or_d(order_end)
case order_end
when 'asc' then "NUMA"
when 'desc','',nil then "NUMD"
else order_end
when 'asc' then "A"
when 'desc','',nil then "D"
else nil
end
end

Expand Down
31 changes: 23 additions & 8 deletions spec/backends/hyper_estraier_spec.rb
Expand Up @@ -88,7 +88,7 @@ def condition(options)
end

it "parses a simple hash" do
condition(:attributes=>{:a=>'b'}).attrs.should == ['a STRINC b']
condition(:attributes=>{:a=>'b'}).attrs.should == ['a iSTRINC b']
end

it "parses a blank hash" do
Expand All @@ -104,15 +104,15 @@ def condition(options)
end

it "parses a string column to string search" do
condition(:attributes=>{'title'=>12}).attrs.should == ['title STRINC 12']
condition(:attributes=>{'title'=>12}).attrs.should == ['title iSTRINC 12']
end

it "translates columns" do
condition(:attributes=>{'id'=>1}).attrs.should == ['db_id NUMEQ 1']
end

it "parses a unknown column to string search" do
condition(:attributes=>{'xxx'=>'x'}).attrs.should == ['xxx STRINC x']
condition(:attributes=>{'xxx'=>'x'}).attrs.should == ['xxx iSTRINC x']
end

it "parses a date or time" do
Expand All @@ -128,7 +128,18 @@ def condition(options)
def translated_order(order)
@backend.send(:build_fulltext_condition,'',:order=>order).order
end


it "translates strings to STRA" do
translated_order('title ASC').should == 'title STRA'
translated_order('title asc').should == 'title STRA'
end

it "translates strings to STRD" do
translated_order('title').should == 'title STRD'
translated_order('title DESC').should == 'title STRD'
translated_order('title desc').should == 'title STRD'
end

it "translates dates to NUMD" do
translated_order(:written_on).should == "written_on NUMD"
end
Expand All @@ -145,8 +156,8 @@ def translated_order(order)
translated_order("popularity ASC").should == "popularity NUMA"
end

it "does not translate non-columns" do
translated_order("paid_at ASC").should == "paid_at ASC"
it "translate non-columns to string" do
translated_order("paid_at ASC").should == "paid_at STRA"
end

describe "translating rails-terms" do
Expand All @@ -158,6 +169,10 @@ def type;:date;end
Story.columns_hash["created_on"] = FakeColumn.new
Story.columns_hash["updated_on"] = FakeColumn.new
end

after :all do
Story.reset_column_information
end

#symbols and desc <-> DESC only need testing once, to see if order values get normalized
['updated_at','updated_on',:updated_at,'updated_at DESC','updated_at desc'].each do |order|
Expand All @@ -176,8 +191,8 @@ def type;:date;end
end
end

it "does not translate strange extras" do
translated_order('id strange').should == 'db_id strange'
it "does not translate strange things" do
translated_order('id strange').should == 'id strange'
end

it "does not translate long orders" do
Expand Down
4 changes: 2 additions & 2 deletions spec/dirty_tracking/bridge_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path("../spec_helper", File.dirname(__FILE__))

describe "need_update_index?" do
describe :need_update_index? do
def needs
@story.send(:need_update_index?)
end
Expand All @@ -18,7 +18,7 @@ def needs
needs.should be_true
end

it "needs update when a non-column changes" do
it "needs update when a indexed non-column changes" do
pending do
@story.non_column = "new value"
needs.should be_true
Expand Down
20 changes: 18 additions & 2 deletions spec/search_do_spec.rb
Expand Up @@ -177,7 +177,7 @@ def fulltext_search(query='hoge')
sleep 1
end

before(:each) do
before do
@story = Story.find_by_title("むかしむかし")
end

Expand All @@ -198,9 +198,25 @@ def fulltext_search(query='hoge')
end

it "finds using attributes" do
#FIXME this fails if iSTRAND is used, why?
Story.fulltext_search('',:attributes=>{:body=>'るとこ'}).size.should == 1
end


it "finds using long strings in attributes" do
Story.fulltext_search('',:attributes=>{:body=>'testing makes'}).size.should == 1
end

it "finds using long strings using and in attributes" do
pending do
#FIXME this works if iSTRAND is used, but then "finds using attributes" fails
Story.fulltext_search('',:attributes=>{:body=>'testing makes happy'}).size.should == 1
end
end

it "finds using upper or lowercase attributes" do
Story.fulltext_search('',:attributes=>{:body=>'MakeS'}).size.should == 1
end

it "finds using non_column attributes" do
pending do
Story.fulltext_search('',:attributes=>{:non_column=>'non column value'}).size.should == 1
Expand Down

0 comments on commit 545e398

Please sign in to comment.