lunar 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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