lunar 0.3.0 → 0.4.0
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/DATA +41 -0
- data/README.md +9 -0
- data/VERSION +1 -1
- data/lib/lunar.rb +1 -0
- data/lib/lunar/result_set.rb +0 -1
- data/lib/lunar/search.rb +11 -4
- data/lunar.gemspec +3 -2
- data/test/test_lunar_search.rb +57 -51
- metadata +4 -3
data/DATA
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
Item
|
3
|
+
- id: 1
|
4
|
+
- name: 'iphone 3g'
|
5
|
+
- tags: 'apple mobile'
|
6
|
+
|
7
|
+
Item
|
8
|
+
- id: 2
|
9
|
+
- name: 'nokia n95'
|
10
|
+
- tags: 'symbian mobile'
|
11
|
+
|
12
|
+
q: mobile
|
13
|
+
|
14
|
+
|
15
|
+
Item:name:iphone => 1004 1001
|
16
|
+
Item:name:3gs => 1001
|
17
|
+
Item:name:apple => 1004 1003 1002
|
18
|
+
Item:name:macbook => 1003 1002
|
19
|
+
Item:name:pro => 1003 1002
|
20
|
+
Item:name:17 => 1003 1002
|
21
|
+
Item:desc:iphone => 1004 1003 1002
|
22
|
+
Item:desc:4g => 1004 1003
|
23
|
+
|
24
|
+
Keywords Only
|
25
|
+
-------------
|
26
|
+
iphone => 1004 1001 1003 1002
|
27
|
+
3gs => 1001
|
28
|
+
apple => 1004 1003 1002
|
29
|
+
macbook => 1002 1003
|
30
|
+
pro => 1002 1003
|
31
|
+
17 => 17
|
32
|
+
4g => 1003 1004
|
33
|
+
|
34
|
+
Key value pairs
|
35
|
+
---------------
|
36
|
+
name: iphone => 1001 1004
|
37
|
+
name: iphone, desc: iphone => 1004
|
38
|
+
name: iphone, desc: 4g => 1004
|
39
|
+
name: apple, desc: iphone => 1002, 1003, 1004
|
40
|
+
name: apple macbook pro, desc: iphone => 1002 1003
|
41
|
+
name: apple macbook pro 17, desc: 4g => 1003
|
data/README.md
CHANGED
@@ -69,3 +69,12 @@ Examples
|
|
69
69
|
# Or using the pagination gem with this:
|
70
70
|
@items = Lunar.search(Item, "iphone")
|
71
71
|
paginate @items, :per_page => 10, :page => 1
|
72
|
+
|
73
|
+
# If you want to be cheap about CPU cycles you can increase the
|
74
|
+
# default `:ttl` of search results (which is 30)
|
75
|
+
|
76
|
+
# Somewhere in config/initializers or init.rb, you decide...
|
77
|
+
Lunar.ttl = 300 # search results would be the same for 5 minutes.
|
78
|
+
# for high write public sites, this may be a good
|
79
|
+
# option as people don't really expect their stuff to
|
80
|
+
# be searchable right away on public content sites.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/lunar.rb
CHANGED
@@ -7,6 +7,7 @@ module Lunar
|
|
7
7
|
autoload :Words, 'lunar/words'
|
8
8
|
autoload :Search, 'lunar/search'
|
9
9
|
autoload :Sets, 'lunar/sets'
|
10
|
+
autoload :FuzzySets, 'lunar/sets'
|
10
11
|
autoload :SortedResultSet, 'lunar/result_set'
|
11
12
|
autoload :UnsortedResultSet, 'lunar/result_set'
|
12
13
|
autoload :FuzzyWord, 'lunar/fuzzy_word'
|
data/lib/lunar/result_set.rb
CHANGED
data/lib/lunar/search.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Lunar
|
2
2
|
class Search
|
3
|
-
attr :sets, :prefix, :search_identifier, :fuzzy_sets
|
3
|
+
attr :sets, :prefix, :search_identifier, :fuzzy_sets, :key_value_sets
|
4
4
|
|
5
5
|
def initialize(prefix, keywords)
|
6
6
|
if keywords.is_a?(Hash)
|
@@ -10,9 +10,9 @@ module Lunar
|
|
10
10
|
}
|
11
11
|
@search_identifier = fuzzy_hash.hash
|
12
12
|
else
|
13
|
-
@
|
14
|
-
|
15
|
-
|
13
|
+
@key_value_sets =
|
14
|
+
keywords.map { |field, val| Sets.new(prefix, val, field) }.flatten
|
15
|
+
|
16
16
|
@search_identifier = keywords.hash
|
17
17
|
end
|
18
18
|
else
|
@@ -39,6 +39,13 @@ module Lunar
|
|
39
39
|
end
|
40
40
|
SortedResultSet.new(dist_key, &block)
|
41
41
|
end
|
42
|
+
elsif key_value_sets
|
43
|
+
if key_value_sets.empty?
|
44
|
+
return []
|
45
|
+
else
|
46
|
+
Lunar.redis.zinter dist_key, key_value_sets.size, *key_value_sets
|
47
|
+
SortedResultSet.new(dist_key, &block)
|
48
|
+
end
|
42
49
|
elsif fuzzy_sets
|
43
50
|
if fuzzy_sets.empty?
|
44
51
|
return []
|
data/lunar.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lunar}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
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"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-10}
|
13
13
|
s.description = %q{uses sorted sets and sets, sorting by score}
|
14
14
|
s.email = %q{cyx.ucron@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
|
+
"DATA",
|
22
23
|
"LICENSE",
|
23
24
|
"README.md",
|
24
25
|
"Rakefile",
|
data/test/test_lunar_search.rb
CHANGED
@@ -16,6 +16,7 @@ end
|
|
16
16
|
|
17
17
|
class LunarSearchTest < Test::Unit::TestCase
|
18
18
|
setup do
|
19
|
+
Lunar.redis(Redis.new(:host => "127.0.0.1", :port => 6380))
|
19
20
|
Lunar.redis.flushdb
|
20
21
|
end
|
21
22
|
|
@@ -43,7 +44,17 @@ class LunarSearchTest < Test::Unit::TestCase
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
+
# This is how the scheme appears
|
48
|
+
# Item:name:iphone => 1004 1001
|
49
|
+
# Item:name:3gs => 1001
|
50
|
+
# Item:name:apple => 1004 1003 1002
|
51
|
+
# Item:name:macbook => 1003 1002
|
52
|
+
# Item:name:pro => 1003 1002
|
53
|
+
# Item:name:17 => 1003 1002
|
54
|
+
# Item:desc:iphone => 1004 1003 1002
|
55
|
+
# Item:desc:4g => 1004 1003
|
56
|
+
#
|
57
|
+
context "given the schema appearing above" do
|
47
58
|
setup do
|
48
59
|
Lunar::Index.create "Item" do |i|
|
49
60
|
i.key 1001
|
@@ -64,82 +75,77 @@ class LunarSearchTest < Test::Unit::TestCase
|
|
64
75
|
i.float :voting_quotient, '35.5'
|
65
76
|
end
|
66
77
|
|
78
|
+
Lunar::Index.create "Item" do |i|
|
79
|
+
i.key 1004
|
80
|
+
i.attr :name, 'iphone apple'
|
81
|
+
i.attr :desc, 'iphone 4G'
|
82
|
+
end
|
67
83
|
end
|
68
84
|
|
69
|
-
should "
|
70
|
-
items = Lunar.search(Item, "iphone")
|
71
|
-
|
72
|
-
assert items.map(&:id).include?('1001')
|
73
|
-
assert items.map(&:id).include?('1002')
|
74
|
-
end
|
75
|
-
|
76
|
-
should "be able to search by keyword iphone apple and return the 2 items" do
|
77
|
-
items = Lunar.search(Item, "iphone apple") { |id| Item.new(id) }
|
85
|
+
should "return all 4 when searching iphone" do
|
86
|
+
items = Lunar.search(Item, "iphone")
|
78
87
|
|
79
|
-
|
80
|
-
assert items.map(&:id).include?('1002')
|
88
|
+
assert_equal %w(1001 1002 1003 1004), items.map(&:id).sort
|
81
89
|
end
|
82
90
|
|
83
|
-
should "
|
84
|
-
items = Lunar.search(Item,
|
91
|
+
should "return only 1001 when searching 3gs" do
|
92
|
+
items = Lunar.search(Item, '3gs')
|
85
93
|
|
86
|
-
|
94
|
+
assert_equal %w(1001), items.map(&:id)
|
87
95
|
end
|
88
96
|
|
89
|
-
should
|
90
|
-
items = Lunar.search(Item, '
|
97
|
+
should "return only 1002 1003 1004 when searching apple" do
|
98
|
+
items = Lunar.search(Item, 'APPle')
|
91
99
|
|
92
|
-
|
100
|
+
assert_equal %w(1002 1003 1004), items.map(&:id).sort
|
93
101
|
end
|
94
102
|
|
95
|
-
should "
|
96
|
-
|
103
|
+
should "return only 1002 1003 when searching macbook, pro, or 17" do
|
104
|
+
macbook = Lunar.search(Item, 'macbook')
|
105
|
+
pro = Lunar.search(Item, 'pro')
|
106
|
+
_17 = Lunar.search(Item, '17')
|
107
|
+
all = Lunar.search(Item, 'macbook pro 17')
|
97
108
|
|
98
|
-
|
109
|
+
assert_equal %w(1002 1003), macbook.map(&:id).sort
|
110
|
+
assert_equal %w(1002 1003), pro.map(&:id).sort
|
111
|
+
assert_equal %w(1002 1003), _17.map(&:id).sort
|
112
|
+
assert_equal %w(1002 1003), all.map(&:id).sort
|
99
113
|
end
|
100
114
|
|
101
|
-
should "
|
102
|
-
items = Lunar.search(Item,
|
115
|
+
should "return only 1003 1004 when searching 4g" do
|
116
|
+
items = Lunar.search(Item, '4g')
|
103
117
|
|
104
|
-
|
118
|
+
assert_equal %w(1003 1004), items.map(&:id).sort
|
105
119
|
end
|
106
120
|
|
107
|
-
should "
|
121
|
+
should "return 1001 1004 given name: iphone" do
|
108
122
|
items = Lunar.search(Item, :name => 'iphone')
|
109
|
-
|
110
|
-
assert items.map(&:id).include?('1001')
|
111
|
-
assert ! items.map(&:id).include?('1002')
|
123
|
+
assert_equal %w(1001 1004), items.map(&:id).sort
|
112
124
|
end
|
113
|
-
|
114
|
-
should "be able to search by name: ['iphone', 'apple']" do
|
115
|
-
items = Lunar.search(Item, :name => ['iphone', 'apple'])
|
116
125
|
|
117
|
-
|
118
|
-
|
119
|
-
|
126
|
+
should "return 1004 given name: iphone, desc: iphone" do
|
127
|
+
items = Lunar.search(Item, :name => 'iphone', :desc => 'iphone')
|
128
|
+
assert_equal %w(1004), items.map(&:id).sort
|
120
129
|
end
|
121
130
|
|
122
|
-
should "
|
123
|
-
items = Lunar.search(Item, :name =>
|
124
|
-
|
125
|
-
assert items.map(&:id).include?('1001')
|
126
|
-
assert items.map(&:id).include?('1002')
|
127
|
-
assert items.map(&:id).include?('1003')
|
131
|
+
should "return 1004 given name: iphone, desc: 4g" do
|
132
|
+
items = Lunar.search(Item, :name => 'iphone', :desc => '4g')
|
133
|
+
assert_equal %w(1004), items.map(&:id).sort
|
128
134
|
end
|
129
135
|
|
130
|
-
should "
|
131
|
-
items = Lunar.search(Item, '
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
+
should "return 1002 1003 1004 given name: apple, desc: iphone" do
|
137
|
+
items = Lunar.search(Item, :name => 'apple', :desc => 'iphone')
|
138
|
+
assert_equal %w(1002 1003 1004), items.map(&:id).sort
|
139
|
+
end
|
140
|
+
|
141
|
+
should "return 1002 1003 given name: apple macbook pro, desc: iphone" do
|
142
|
+
items = Lunar.search(Item, :name => 'apple macbook pro', :desc => 'iphone')
|
143
|
+
assert_equal %w(1002 1003), items.map(&:id).sort
|
136
144
|
end
|
137
145
|
|
138
|
-
should "
|
139
|
-
items = Lunar.search(Item, :name => '
|
140
|
-
|
141
|
-
assert items.map(&:id).include?('1001')
|
142
|
-
assert items.map(&:id).include?('1002')
|
146
|
+
should "return 1003 given name: apple macbook pro 17, desc: 4g" do
|
147
|
+
items = Lunar.search(Item, :name => 'apple macbook pro 17', :desc => '4g')
|
148
|
+
assert_equal %w(1003), items.map(&:id).sort
|
143
149
|
end
|
144
150
|
|
145
151
|
should "be able to search by cost range: 2000..2700" do
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 4
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Cyril David
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-10 00:00:00 +08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -53,6 +53,7 @@ extra_rdoc_files:
|
|
53
53
|
files:
|
54
54
|
- .document
|
55
55
|
- .gitignore
|
56
|
+
- DATA
|
56
57
|
- LICENSE
|
57
58
|
- README.md
|
58
59
|
- Rakefile
|