Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

+ facets draft (experimental!)

  • Loading branch information...
commit 0d5d8031d0b4923fb6a34a3fb01a5a4f9e4f1272 1 parent d1861f0
@floere authored
View
3  server/lib/maybe_compile.rb
@@ -1,3 +1,6 @@
+# TODO Decide what to do with this.
+#
+
# Note: This is handled toplevel to not confuse compilers.
#
failed = 0
View
1  server/lib/picky/index.rb
@@ -162,6 +162,7 @@ def backend backend = nil
# * category_name: This identifier is used in the front end, but also to categorize query text. For example, “title:hobbit” will narrow the hobbit query on categories with the identifier :title.
#
# === Options
+ # * indexing: Pass in either a tokenizer or tokenizer options.
# * partial: Partial::None.new or Partial::Substring.new(from: starting_char, to: ending_char). Default is Partial::Substring.new(from: -3, to: -1).
# * similarity: Similarity::None.new or Similarity::DoubleMetaphone.new(similar_words_searched). Default is Similarity::None.new.
# * qualifiers: An array of qualifiers with which you can define which category you’d like to search, for example “title:hobbit” will search for hobbit in just title categories. Example: qualifiers: [:t, :titre, :title] (use it for example with multiple languages). Default is the name of the category.
View
14 server/lib/picky/index_facets.rb
@@ -0,0 +1,14 @@
+module Picky
+
+ class Index
+
+ # Return facets for a category in the form:
+ # { text => weight } # or ids.size?
+ #
+ def facets category_identifier
+ self[category_identifier].exact.weights
+ end
+
+ end
+
+end
View
2  server/lib/picky/loader.rb
@@ -243,6 +243,7 @@ def load_user_interface
load_relative 'index_indexed'
load_relative 'index_indexing'
load_relative 'index_realtime'
+ load_relative 'index_facets'
load_relative 'index_convenience'
# Results.
@@ -253,6 +254,7 @@ def load_user_interface
# Search.
#
load_relative 'search'
+ load_relative 'search_facets'
# Interfaces
#
View
8 server/lib/picky/query/indexes.rb
@@ -12,7 +12,13 @@ module Query
# # bundle them in an index bundle.
#
class Indexes
-
+
+ # TODO Only needed for .
+ #
+ delegate :size,
+ :first,
+ :to => :@indexes
+
attr_reader :indexes,
:ignored_categories
View
8 server/lib/picky/query/token.rb
@@ -25,10 +25,10 @@ class Token
# Note:
# Use this if you do not want a normalized token.
#
- def initialize text, original = nil, category = nil
+ def initialize text, original = nil, categories = nil
@text = text
@original = original
- @user_defined_categories = [category] if category
+ @user_defined_categories = categories
end
# Returns a qualified and normalized token.
@@ -214,7 +214,9 @@ def possible_combinations_in index
def similar_tokens_for category
similars = category.bundle_for(self).similar @text
similars.map do |similar|
- self.class.new similar, similar, category
+ # The array describes all possible categories. There is only one here.
+ #
+ self.class.new similar, similar, [category]
end
end
View
26 server/lib/picky/search_facets.rb
@@ -0,0 +1,26 @@
+module Picky
+
+ class Search
+
+ # Returns a list of filtered facets.
+ #
+ # Params
+ # category: The category whose facets to return.
+ # filter_query: (optional) A query to filter the facets with.
+ #
+ # Usage:
+ # search.facets :name, 'surname:peter'
+ #
+ def facets category_identifier, filter_query = nil
+ raise "#{__method__} cannot be used on searches with more than 1 index yet. Sorry!" if indexes.size > 1
+ index = indexes.first
+ weights = index.facets category_identifier
+ return weights unless filter_query
+ weights.select do |key, weight|
+ search("#{filter_query} #{category_identifier}:#{key}", 0, 0).total > 0
+ end
+ end
+
+ end
+
+end
View
125 server/spec/functional/facets_spec.rb
@@ -0,0 +1,125 @@
+# encoding: utf-8
+#
+require 'spec_helper'
+
+# This spec describes
+#
+describe 'facets' do
+
+ describe 'simple example' do
+ let(:index) {
+ index = Picky::Index.new :facets do
+ category :name
+ category :surname
+ end
+
+ thing = Struct.new :id, :name, :surname
+ index.add thing.new(1, 'fritz', 'hanke')
+ index.add thing.new(2, 'kaspar', 'schiess')
+ index.add thing.new(3, 'florian', 'hanke')
+
+ index
+ }
+ let(:finder) { Picky::Search.new index }
+
+ describe 'facets' do
+ it 'is correct' do
+ # Picky has 2 facets with different weights for surname.
+ #
+ index.facets(:surname).should == {
+ 'hanke' => 0.693,
+ 'schiess' => 0
+ }
+
+ # It has 3 facets with the same weight for name.
+ #
+ index.facets(:name).should == {
+ 'fritz' => 0,
+ 'kaspar' => 0,
+ 'florian' => 0
+ }
+ end
+ end
+
+ describe 'filtered_facets' do
+ it 'filters them correctly' do
+ # Passing in no filter query just returns the facets
+ #
+ finder.facets(:surname).should == {
+ 'hanke' => 0.693,
+ 'schiess' => 0.0
+ }
+
+ # It has two facets.
+ #
+ # TODO Rewrite API.
+ #
+ finder.facets(:name, 'surname:hanke').should == {
+ 'fritz' => 0,
+ 'florian' => 0
+ }
+ end
+ end
+ end
+
+ describe 'complex example' do
+ let(:index) {
+ index = Picky::Index.new :facets do
+ category :name
+ category :surname
+ category :age_category
+ end
+
+ thing = Struct.new :id, :name, :surname, :age_category
+ index.add thing.new(1, 'ursula', 'meier', 40)
+ index.add thing.new(2, 'peter', 'meier', 45)
+ index.add thing.new(3, 'peter', 'kunz', 40)
+ index.add thing.new(4, 'peter', 'hanke', 40)
+ index.add thing.new(5, 'annabelle', 'hanke', 35)
+ index.add thing.new(5, 'hans', 'meier', 35)
+
+ index
+ }
+ let(:finder) { Picky::Search.new index }
+
+ describe 'facets' do
+ it 'is correct' do
+ # Picky has 2 facets with different weights for surname.
+ #
+ index.facets(:surname).should == {
+ 'hanke' => 0.693,
+ 'kunz' => 0.0,
+ 'meier' => 1.099
+ }
+
+ # It has 3 facets with the same weight for name.
+ #
+ index.facets(:name).should == {
+ 'annabelle' => 0.0,
+ 'hans' => 0.0,
+ 'peter' => 1.099,
+ 'ursula' => 0.0
+ }
+ end
+ end
+
+ describe 'filtered_facets' do
+ it 'filters them correctly' do
+ # It has one facet.
+ #
+ # TODO Fix problems with alternative qualifiers (like :age).
+ #
+ finder.facets(:age_category, 'surname:meier name:peter').should == {
+ '45' => 0
+ }
+
+ # It has two facets.
+ #
+ finder.facets(:surname, 'age_category:40 name:peter').should == {
+ 'kunz' => 0.0,
+ 'hanke' => 0.693
+ }
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.