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.
- data/README.markdown +3 -1
- data/VERSION +1 -1
- data/lib/lunar.rb +34 -29
- data/lib/lunar/connection.rb +12 -1
- data/lib/lunar/fuzzy_word.rb +9 -1
- data/lib/lunar/index.rb +2 -2
- data/lib/lunar/result_set.rb +5 -7
- data/lib/lunar/stopwords.rb +2 -0
- data/lunar.gemspec +1 -1
- metadata +2 -2
data/README.markdown
CHANGED
@@ -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.
|
1
|
+
0.5.1
|
data/lib/lunar.rb
CHANGED
@@ -4,7 +4,7 @@ require 'nest'
|
|
4
4
|
require 'text'
|
5
5
|
|
6
6
|
module Lunar
|
7
|
-
VERSION = '0.5.
|
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
|
-
|
85
|
+
sets = find_and_combine_sorted_sets_for(namespace, options)
|
86
|
+
key = try_intersection_of_sorted_sets(namespace, sets)
|
86
87
|
|
87
|
-
|
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
|
-
|
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
|
data/lib/lunar/connection.rb
CHANGED
@@ -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
|
data/lib/lunar/fuzzy_word.rb
CHANGED
@@ -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
|
data/lib/lunar/index.rb
CHANGED
data/lib/lunar/result_set.rb
CHANGED
@@ -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
|
-
#
|
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
|
data/lib/lunar/stopwords.rb
CHANGED
data/lunar.gemspec
CHANGED