Permalink
Browse files

+ 3.1.11 with realtime indexing support for similarity~

  • Loading branch information...
1 parent 6f15db8 commit 80e63d41b93f323dfdcd92b39a05157cd97fd772 @floere committed Oct 24, 2011
View
@@ -1,5 +1,10 @@
h2. Upcoming Version
+h2. Version 3.1.11
+
+* hanke: (server) See last release. This release adds support for similarity searches on a realtime index.
+* Please only use realtime indexing for experimental purposes.
+
h2. Version 3.1.10
* hanke: (server) This release holds an *experimental* release of realtime indexing for 3.2: An index now supports @#add(object_responding_to_id_and_categories)@, @#remove(id_of_added_object)@, @#replace(object_responding_to_id_and_categories)@. Replace is simply remove+add. Replacing a non-existent object behaves like an add. I suggest using solely @replace@. Notes: Only works in single-process, single-threaded servers. Does not persist. Only yet works when starting from an empty index, e.g. @source []@.
@@ -19,7 +19,7 @@ def add id, tokens
text = text.to_sym
indexed_exact.add id, text
- # TODO Beautify.
+ # TODO Refactor.
#
indexed_partial.partial_strategy.each_partial text do |partial_text|
indexed_partial.add id, partial_text
@@ -16,9 +16,12 @@ def remove id
ids = @inverted[sym]
ids.delete id
+ encoded = self.similarity_strategy.encoded sym
+
if ids.empty?
- @inverted.delete sym
- @weights.delete sym
+ @inverted.delete sym
+ @weights.delete sym
+ @similarity.delete encoded # Since no element uses this sym anymore, we can delete the similarity for it.
else
@weights[sym] = self.weights_strategy.weight_for ids.size
end
@@ -35,6 +38,8 @@ def add id, sym
syms = @realtime_mapping[id]
syms = (@realtime_mapping[id] = []) unless syms # TODO Nicefy.
+ # Inverted.
+ #
ids = if syms.include? sym
ids = @inverted[sym]
ids.delete id # Move id
@@ -45,7 +50,21 @@ def add id, sym
inverted.unshift id
end
+ # Weights.
+ #
@weights[sym] = self.weights_strategy.weight_for ids.size
+
+ # Similarity.
+ #
+ if encoded = self.similarity_strategy.encoded(sym)
+ similarity = @similarity[encoded] ||= []
+ if similarity.include? sym
+ similarity.delete sym # Not completely correct, as others will also be affected, but meh.
+ similarity.unshift sym #
+ else
+ similarity.unshift sym
+ end
+ end
end
end
@@ -8,7 +8,7 @@
@weights = Picky::Generators::Weights::Default
@partial = Picky::Generators::Partial::Default
- @similarity = stub :similarity
+ @similarity = Picky::Generators::Similarity::DoubleMetaphone.new 3
@bundle = described_class.new :some_name, @category, Picky::Backends::Memory.new, @weights, @partial, @similarity
end
@@ -21,6 +21,9 @@
it 'is by default empty' do
@bundle.inverted.should == {}
end
+ it 'is by default empty' do
+ @bundle.similarity.should == {}
+ end
describe 'combined' do
it 'works correctly' do
@@ -29,7 +32,8 @@
@bundle.realtime_mapping.should == { 1 => [:title], 2 => [:title] }
@bundle.inverted.should == { :title => [2,1] }
- @bundle.weights.should == { :title => 0.6931471805599453 }
+ @bundle.weights.should == { :title => 0.6931471805599453 }
+ @bundle.similarity.should == { :TTL => [:title] }
end
it 'works correctly' do
@bundle.add 1, :title
@@ -38,8 +42,9 @@
@bundle.remove 2
@bundle.realtime_mapping.should == {}
- @bundle.weights.should == {}
+ @bundle.weights.should == {}
@bundle.inverted.should == {}
+ @bundle.similarity.should == {}
end
it 'works correctly' do
@bundle.add 1, :title
@@ -48,8 +53,9 @@
@bundle.remove 1
@bundle.realtime_mapping.should == {}
- @bundle.weights.should == {}
+ @bundle.weights.should == {}
@bundle.inverted.should == {}
+ @bundle.similarity.should == {}
end
it 'works correctly' do
@bundle.add 1, :title
@@ -58,8 +64,9 @@
@bundle.remove 1
@bundle.realtime_mapping.should == { 2 => [:thing] }
- @bundle.weights.should == { :thing => 0.0 }
+ @bundle.weights.should == { :thing => 0.0 }
@bundle.inverted.should == { :thing => [2] }
+ @bundle.similarity.should == { :"0NK" => [:thing] }
end
it 'works correctly' do
@bundle.add 1, :title
@@ -68,6 +75,7 @@
@bundle.realtime_mapping.should == { 1 => [:title] }
@bundle.weights.should == { :title => 0.0 }
@bundle.inverted.should == { :title => [1] }
+ @bundle.similarity.should == { :TTL => [:title] }
end
it 'works correctly' do
@bundle.add 1, :title
@@ -77,6 +85,7 @@
@bundle.realtime_mapping.should == {}
@bundle.weights.should == {}
@bundle.inverted.should == {}
+ @bundle.similarity.should == {}
end
end
@@ -97,8 +106,9 @@
it 'works correctly' do
@bundle.add 1, :title
- @bundle.weights.should == { :title => 0.0 }
+ @bundle.weights.should == { :title => 0.0 }
@bundle.inverted.should == { :title => [1] }
+ @bundle.similarity.should == { :TTL => [:title] }
end
end
@@ -11,7 +11,13 @@ def initialize id, title, author
end
end
- let(:index) { Picky::Index.new(:test) { source []; category :title; category :author } }
+ let(:index) do
+ Picky::Index.new(:test) do
+ source []
+ category :title
+ category :author, similarity: Picky::Generators::Similarity::DoubleMetaphone.new(3)
+ end
+ end
let(:books) { Picky::Search.new index }
before(:each) do
@@ -120,11 +126,74 @@ def initialize id, title, author
it 'handles more complex cases' do
index.remove 1
- books.search('Title"').ids.should == []
+ books.search('Titl').ids.should == []
index.replace Book.new(1, "Title New", "Author New")
- books.search('title:New"').ids.should == [1]
+ books.search('title:Ne').ids.should == [1]
+ end
+ end
+
+ context 'similarity' do
+ it 'finds the first entry' do
+ books.search('Authr~').ids.should == [1]
+ end
+
+ it 'allows removing something' do
+ index.remove 1
+ end
+ it 'is not findable anymore after removing' do
+ books.search('Authr~').ids.should == [1]
+
+ index.remove 1
+
+ books.search('Authr~').ids.should == []
+ end
+
+ it 'allows adding something' do
+ index.add Book.new(2, "Title2", "Author2")
+ end
+ it 'is findable after adding' do
+ books.search('Authr~').ids.should == [1]
+
+ index.add Book.new(2, "Title New", "Author New")
+
+ books.search('Authr~').ids.should == [2,1]
+ end
+
+ it 'allows replacing something' do
+ index.replace Book.new(1, "Title New", "Author New")
+ end
+ it 'is findable after replacing' do
+ books.search('Nuw~').ids.should == []
+
+ index.replace Book.new(1, "Title New", "Author New")
+
+ books.search('Nuw~').ids.should == [1, 1] # TODO FIXME Not really what I'd expect.
+ end
+ it 'handles more complex cases' do
+ books.search('Now~').ids.should == []
+
+ index.replace Book.new(1, "Title New", "Author New")
+
+ books.search('author:Now~').ids.should == [1]
+ end
+ it 'handles more complex cases' do
+ index.remove 1
+
+ books.search('Athr~').ids.should == []
+
+ index.replace Book.new(1, "Title New", "Author New")
+
+ books.search('author:Athr~').ids.should == [1]
+ end
+ it 'handles more complex cases' do
+ books.search('Athr~').ids.should == [1]
+
+ index.replace Book.new(2, "Title New", "Author New")
+ index.add Book.new(3, "TTL", "AUTHR")
+
+ books.search('author:Athr~').ids.should == [2, 1, 3] # TODO Is that what I'd expect?
end
end
View
@@ -1,3 +1,3 @@
module Picky
- VERSION = '3.1.10'
+ VERSION = '3.1.11'
end

0 comments on commit 80e63d4

Please sign in to comment.