lunar 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,8 @@
1
1
  Lunar: full text searching on top of Redis
2
2
  ==========================================
3
3
 
4
+ Read the documentation at http://sinefunc.github.com/lunar/doc
5
+
4
6
  But why?
5
7
  --------
6
8
  We have been using Redis as our datastore exclusively for a lot of projects.
@@ -113,4 +115,4 @@ Note on Patches/Pull Requests
113
115
 
114
116
  ### Copyright
115
117
 
116
- Copyright (c) 2010 Cyril David. See LICENSE for details.
118
+ Copyright (c) 2010 Cyril David. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
@@ -4,7 +4,7 @@ require 'nest'
4
4
  require 'text'
5
5
 
6
6
  module Lunar
7
- VERSION = '0.5.0'
7
+ VERSION = '0.5.1'
8
8
 
9
9
  autoload :Connection, "lunar/connection"
10
10
  autoload :LunarNest, "lunar/lunar_nest"
@@ -23,7 +23,7 @@ module Lunar
23
23
  # Index any document using a namespace. The namespace can
24
24
  # be a class, or a plain Symbol/String.
25
25
  #
26
- # @example:
26
+ # @example
27
27
  #
28
28
  # Lunar.index Gadget do |i|
29
29
  # i.text :name, 'iphone 3gs'
@@ -54,7 +54,7 @@ module Lunar
54
54
 
55
55
  # Search for a document, scoped under a namespace.
56
56
  #
57
- # @example:
57
+ # @example
58
58
  #
59
59
  # Lunar.search Gadget, :q => "apple"
60
60
  # # returns all gadgets with `text` apple.
@@ -82,32 +82,10 @@ module Lunar
82
82
  #
83
83
  # @return Lunar::ResultSet an Enumerable object.
84
84
  def self.search(namespace, options, finder = lambda { |id| namespace[id] })
85
- ns = nest[namespace]
85
+ sets = find_and_combine_sorted_sets_for(namespace, options)
86
+ key = try_intersection_of_sorted_sets(namespace, sets)
86
87
 
87
- sets =
88
- options.map do |key, value|
89
- if value.is_a?(Range)
90
- RangeMatches.new(nest[namespace], key, value).distkey
91
- elsif key == :fuzzy
92
- value.map do |fuzzy_key, fuzzy_value|
93
- FuzzyMatches.new(nest[namespace], fuzzy_key, fuzzy_value).distkey
94
- end
95
- else
96
- KeywordMatches.new(nest[namespace], key, value).distkey
97
- end
98
- end
99
-
100
- sets = sets.flatten
101
-
102
- key =
103
- if sets.size == 1
104
- sets.first
105
- else
106
- ns[options.hash].zinterstore sets
107
- ns[options.hash]
108
- end
109
-
110
- ResultSet.new(key, ns, finder)
88
+ ResultSet.new(key, nest[namespace], finder)
111
89
  end
112
90
 
113
91
  # @private internally used for determining the metaphone of a word.
@@ -124,4 +102,31 @@ module Lunar
124
102
  def self.nest
125
103
  LunarNest.new(:Lunar, redis)
126
104
  end
127
- end
105
+
106
+ private
107
+ def self.find_and_combine_sorted_sets_for(namespace, options)
108
+ options.inject([]) do |sets, (key, value)|
109
+ if value.is_a?(Range)
110
+ sets << RangeMatches.new(nest[namespace], key, value).distkey
111
+ elsif key == :fuzzy
112
+ fuzzy_matches = value.map { |fuzzy_key, fuzzy_value|
113
+ FuzzyMatches.new(nest[namespace], fuzzy_key, fuzzy_value).distkey
114
+ }
115
+ sets.push(*fuzzy_matches)
116
+ else
117
+ sets << KeywordMatches.new(nest[namespace], key, value).distkey
118
+ end
119
+
120
+ sets
121
+ end
122
+ end
123
+
124
+ def self.try_intersection_of_sorted_sets(namespace, sets)
125
+ if sets.size == 1
126
+ sets.first
127
+ else
128
+ nest[namespace][options.hash].zinterstore sets
129
+ nest[namespace][options.hash]
130
+ end
131
+ end
132
+ end
@@ -1,4 +1,15 @@
1
1
  module Lunar
2
+ # This is actually taken from Ohm (http://ohm.keyvalue.org). The Lunar module
3
+ # extends this to make the API easier to use.
4
+ #
5
+ # Lunar.connect(:host => "127.0.0.1", :port => "6380")
6
+ # Lunar.redis
7
+ # # basically returns Redis.new(:host => "127.0.0.1", :port => "6380")
8
+ #
9
+ # # If you don't provide any connection, it assumes you are referring
10
+ # # to the default redis host / port (127.0.0.1 on port 6379)
11
+ # Lunar.redis
12
+ #
2
13
  module Connection
3
14
  # Connect to a redis database.
4
15
  #
@@ -48,4 +59,4 @@ module Lunar
48
59
  @options || []
49
60
  end
50
61
  end
51
- end
62
+ end
@@ -1,7 +1,15 @@
1
1
  module Lunar
2
+ # @private A helper for producing all the characters of a word.
3
+ #
4
+ # @example
5
+ #
6
+ # expected = %w(a ab abr abra abrah abraha abraham)
7
+ # FuzzyWord.new("Abraham").partials == expected
8
+ # # => true
9
+ #
2
10
  class FuzzyWord < String
3
11
  def partials
4
12
  (1..length).map { |i| self[0, i].downcase }
5
13
  end
6
14
  end
7
- end
15
+ end
@@ -31,7 +31,7 @@ module Lunar
31
31
  end
32
32
 
33
33
  # Get / Set the id of the document
34
- # @example:
34
+ # @example
35
35
  #
36
36
  # # Wrong usage:
37
37
  # Lunar.index :Gadget do |i|
@@ -239,4 +239,4 @@ module Lunar
239
239
  end
240
240
  end
241
241
  end
242
- end
242
+ end
@@ -2,8 +2,6 @@ module Lunar
2
2
  # This wraps a Lunar search result set. You can do all the
3
3
  # expected operations with an Enumerable.
4
4
  #
5
- # @example:
6
- #
7
5
  # results = Lunar.search(Gadget, :q => "Apple Macbook Pro")
8
6
  # results.class == Lunar::ResultSet
9
7
  # # => true
@@ -11,8 +9,8 @@ module Lunar
11
9
  # results.kind_of?(Enumerable)
12
10
  # # => true
13
11
  #
14
- # `sort` and `sort_by` commands are available and directly calls
15
- # the Redis SORT command.
12
+ # {Lunar::ResultSet#sort} and {Lunar::ResultSet#sort_by} commands are
13
+ # available and directly calls the Redis SORT command.
16
14
  #
17
15
  # results = Lunar.search(Gadget, :q => "Apple Macbook Pro")
18
16
  # results.sort(:by => :name, :order => "ALPHA")
@@ -40,7 +38,7 @@ module Lunar
40
38
 
41
39
  # Provides syntatic sugar for `sort`.
42
40
  #
43
- # @example:
41
+ # @example
44
42
  #
45
43
  # results = Lunar.search(Gadget, :q => "apple")
46
44
  # results.sort(:by => :votes)
@@ -60,7 +58,7 @@ module Lunar
60
58
  # Gives the ability to sort the search results via a `sortable` field
61
59
  # in your index.
62
60
  #
63
- # @example:
61
+ # @example
64
62
  #
65
63
  # Lunar.index Gadget do |i|
66
64
  # i.id 1001
@@ -97,4 +95,4 @@ module Lunar
97
95
  ids.map(&@finder)
98
96
  end
99
97
  end
100
- end
98
+ end
@@ -1,4 +1,6 @@
1
1
  module Lunar
2
+ # @private Internally used by {Lunar::Words} to filter out
3
+ # common words like an, the, etc.
2
4
  module Stopwords
3
5
  def include?(word)
4
6
  stopwords.include?(word)
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{lunar}
8
- s.version = "0.5.0"
8
+ s.version = "0.5.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril David"]
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 0
9
- version: 0.5.0
8
+ - 1
9
+ version: 0.5.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cyril David