cloud_search 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/Guardfile +10 -0
- data/README.md +27 -13
- data/cloud_search.gemspec +3 -0
- data/lib/cloud_search.rb +7 -2
- data/lib/cloud_search/config.rb +2 -2
- data/lib/cloud_search/document.rb +94 -0
- data/lib/cloud_search/indexer.rb +54 -0
- data/lib/cloud_search/invalid_document.rb +11 -0
- data/lib/cloud_search/search_response.rb +23 -0
- data/lib/cloud_search/searcher.rb +48 -0
- data/lib/cloud_search/version.rb +1 -1
- data/spec/cloud_search/config_spec.rb +2 -2
- data/spec/cloud_search/document_spec.rb +315 -0
- data/spec/cloud_search/indexer_spec.rb +108 -0
- data/spec/cloud_search/invalid_document_spec.rb +9 -0
- data/spec/cloud_search/search_response_spec.rb +60 -0
- data/spec/cloud_search/searcher_spec.rb +39 -0
- data/spec/fixtures/full.yml +218 -0
- data/spec/fixtures/vcr_cassettes/index/request/add.yml +38 -0
- data/spec/fixtures/vcr_cassettes/index/request/add_in_batch.yml +40 -0
- data/spec/fixtures/vcr_cassettes/index/request/delete.yml +37 -0
- data/spec/spec_helper.rb +5 -0
- metadata +76 -7
- data/lib/cloud_search/search.rb +0 -35
- data/spec/cloud_search/search_spec.rb +0 -39
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CloudSearch::Indexer do
|
4
|
+
let(:indexer) { described_class.new }
|
5
|
+
|
6
|
+
describe "#documents" do
|
7
|
+
it "returns the list of documents to be indexed" do
|
8
|
+
doc1 = stub.as_null_object
|
9
|
+
doc2 = stub.as_null_object
|
10
|
+
indexer << doc1
|
11
|
+
indexer << doc2
|
12
|
+
expect(indexer.documents).to eq([doc1, doc2])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns a frozen version of the documents list" do
|
16
|
+
expect {
|
17
|
+
indexer.documents << stub
|
18
|
+
}.to raise_error(RuntimeError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#<<" do
|
23
|
+
let(:document) { stub :valid? => true }
|
24
|
+
|
25
|
+
it "adds a new item to the list of documents" do
|
26
|
+
indexer << document
|
27
|
+
expect(indexer.documents).to have(1).item
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is aliased to #add" do
|
31
|
+
indexer.add document
|
32
|
+
expect(indexer.documents).to have(1).item
|
33
|
+
end
|
34
|
+
|
35
|
+
it "raises an exception if the document is invalid" do
|
36
|
+
expect {
|
37
|
+
indexer << stub(:valid? => false, :errors => {})
|
38
|
+
}.to raise_error(CloudSearch::InvalidDocument)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#index" do
|
43
|
+
let(:document) { CloudSearch::Document.new(
|
44
|
+
:type => type,
|
45
|
+
:id => 678,
|
46
|
+
:version => version,
|
47
|
+
:lang => :en,
|
48
|
+
:fields => {:actor => ["Cassio Marques", "Willian Fernandes"], :director => ["Lucas, George"], :title => "Troy Wars"}
|
49
|
+
) }
|
50
|
+
let(:indexer) { described_class.new }
|
51
|
+
|
52
|
+
context "adding a new document" do
|
53
|
+
around do |example|
|
54
|
+
VCR.use_cassette "index/request/add", &example
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:type) { "add" }
|
58
|
+
let(:version) { 1 }
|
59
|
+
|
60
|
+
it "succeeds" do
|
61
|
+
indexer << document
|
62
|
+
resp, message = indexer.index
|
63
|
+
expect(resp["status"]).to eq("success")
|
64
|
+
expect(resp["adds"]).to eq(1)
|
65
|
+
expect(resp["deletes"]).to eq(0)
|
66
|
+
expect(message).to match(/^200/)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "adding a batch of documents" do
|
71
|
+
around do |example|
|
72
|
+
VCR.use_cassette "index/request/add_in_batch", &example
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:type) { "add" }
|
76
|
+
let(:version) { 5 }
|
77
|
+
|
78
|
+
it "succeeds" do
|
79
|
+
indexer << document
|
80
|
+
document2 = CloudSearch::Document.new :type => type, :version => version, :id => 679, :lang => :en, :fields => {:title => "Fight Club"}
|
81
|
+
document3 = CloudSearch::Document.new :type => type, :version => version, :id => 680, :lang => :en, :fields => {:title => "Lord of the Rings"}
|
82
|
+
indexer << document2
|
83
|
+
indexer << document3
|
84
|
+
resp, message = indexer.index
|
85
|
+
expect(resp["adds"]).to eq(3)
|
86
|
+
expect(resp["status"]).to eq("success")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "deleting a document" do
|
91
|
+
around do |example|
|
92
|
+
VCR.use_cassette "index/request/delete", &example
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:type) { "delete" }
|
96
|
+
let(:version) { 2 }
|
97
|
+
|
98
|
+
it "succeeds" do
|
99
|
+
indexer << document
|
100
|
+
resp, message = indexer.index
|
101
|
+
expect(resp["status"]).to eq("success")
|
102
|
+
expect(resp["adds"]).to eq(0)
|
103
|
+
expect(resp["deletes"]).to eq(1)
|
104
|
+
expect(message).to match(/^200/)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CloudSearch::InvalidDocument do
|
4
|
+
let(:document) { CloudSearch::Document.new }
|
5
|
+
|
6
|
+
it "has a message with the document errors" do
|
7
|
+
expect(described_class.new(document).message).to eq("id: can't be blank; version: can't be blank; type: can't be blank; lang: can't be blank; fields: can't be empty")
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CloudSearch::SearchResponse do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
before do
|
7
|
+
subject.body = YAML.load_file File.expand_path("../../fixtures/full.yml", __FILE__)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when there are results" do
|
11
|
+
describe "#results" do
|
12
|
+
it "list matched documents" do
|
13
|
+
subject.results.inject([]){ |acc, i| acc << i['data']['title']}.flatten(1)
|
14
|
+
.should == ["Star Wars: The Clone Wars",
|
15
|
+
"Star Wars",
|
16
|
+
"Star Wars: Episode II - Attack of the Clones",
|
17
|
+
"Star Wars: Episode V - The Empire Strikes Back",
|
18
|
+
"Star Wars: Episode VI - Return of the Jedi",
|
19
|
+
"Star Wars: Episode I - The Phantom Menace",
|
20
|
+
"Star Wars: Episode III - Revenge of the Sith"]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#hits" do
|
25
|
+
it "returns number of hits" do
|
26
|
+
subject.hits.should == 7
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#found?" do
|
31
|
+
it "returns true when found documents" do
|
32
|
+
subject.should be_found
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when there aren't results" do
|
38
|
+
before do
|
39
|
+
subject.body = {}
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#results" do
|
43
|
+
it "list matched documents" do
|
44
|
+
subject.results.size.should == 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#hits" do
|
49
|
+
it "returns number of hits" do
|
50
|
+
subject.hits.should == 0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#found?" do
|
55
|
+
it "returns false when not found documents" do
|
56
|
+
subject.should_not be_found
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CloudSearch::Searcher do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
describe "#search" do
|
7
|
+
before do
|
8
|
+
subject
|
9
|
+
.with_fields(:actor, :director, :title, :year, :text_relevance)
|
10
|
+
.query("star wars")
|
11
|
+
end
|
12
|
+
|
13
|
+
around { |example| VCR.use_cassette "search/request/full", &example }
|
14
|
+
|
15
|
+
context "given valid parameters" do
|
16
|
+
it "returns http 200 code" do
|
17
|
+
resp = subject.search
|
18
|
+
resp.http_code.should == 200
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has found results" do
|
22
|
+
resp = subject.search
|
23
|
+
resp.should be_found
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns number of hits" do
|
27
|
+
resp = subject.search
|
28
|
+
expect(resp.hits).to be == 7
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns Episode II" do
|
32
|
+
resp = subject.search
|
33
|
+
resp.results.inject([]){|acc, i| acc << i['data']['title']}.flatten
|
34
|
+
.should include "Star Wars: Episode II - Attack of the Clones"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,218 @@
|
|
1
|
+
---
|
2
|
+
rank: -text_relevance
|
3
|
+
match-expr: (label 'star wars')
|
4
|
+
hits:
|
5
|
+
found: 7
|
6
|
+
start: 0
|
7
|
+
hit:
|
8
|
+
- id: tt1185834
|
9
|
+
data:
|
10
|
+
actor:
|
11
|
+
- Abercrombie, Ian
|
12
|
+
- Baker, Dee Bradley
|
13
|
+
- Burton, Corey
|
14
|
+
- Eckstein, Ashley
|
15
|
+
- Futterman, Nika
|
16
|
+
- Kane, Tom
|
17
|
+
- Lanter, Matt
|
18
|
+
- Taber, Catherine
|
19
|
+
- Taylor, James Arnold
|
20
|
+
- Wood, Matthew
|
21
|
+
director:
|
22
|
+
- Filoni, Dave
|
23
|
+
text_relevance:
|
24
|
+
- '308'
|
25
|
+
title:
|
26
|
+
- ! 'Star Wars: The Clone Wars'
|
27
|
+
year:
|
28
|
+
- '2008'
|
29
|
+
- id: tt0076759
|
30
|
+
data:
|
31
|
+
actor:
|
32
|
+
- Baker, Kenny
|
33
|
+
- Cushing, Peter
|
34
|
+
- Daniels, Anthony
|
35
|
+
- De Aragon, Maria
|
36
|
+
- Diamond, Peter
|
37
|
+
- Fisher, Carrie
|
38
|
+
- Ford, Harrison
|
39
|
+
- Goffe, Rusty
|
40
|
+
- Guinness, Alec
|
41
|
+
- Hamill, Mark
|
42
|
+
- Johnston, Joe
|
43
|
+
- Jones, James Earl
|
44
|
+
- Lyons, Derek
|
45
|
+
- Mayhew, Peter
|
46
|
+
- McCallum, Rick
|
47
|
+
- Prowse, David
|
48
|
+
- Rimmer, Shane
|
49
|
+
- Tierney, Malcolm
|
50
|
+
- Tippett, Phil
|
51
|
+
- Ward, Larry
|
52
|
+
director:
|
53
|
+
- Lucas, George
|
54
|
+
text_relevance:
|
55
|
+
- '271'
|
56
|
+
title:
|
57
|
+
- Star Wars
|
58
|
+
year:
|
59
|
+
- '1977'
|
60
|
+
- id: tt0121765
|
61
|
+
data:
|
62
|
+
actor:
|
63
|
+
- Allen, Amy
|
64
|
+
- August, Pernilla
|
65
|
+
- Christensen, Hayden
|
66
|
+
- Csokas, Marton
|
67
|
+
- Fantl, Nicole
|
68
|
+
- Jackson, Samuel L.
|
69
|
+
- Johnson, Fiona
|
70
|
+
- Lee, Christopher
|
71
|
+
- Logan, Daniel
|
72
|
+
- Lucas, Amanda
|
73
|
+
- Lucas, Jett
|
74
|
+
- Lucas, Katie
|
75
|
+
- McDiarmid, Ian
|
76
|
+
- McGregor, Ewan
|
77
|
+
- Morrison, Temuera
|
78
|
+
- Oz, Frank
|
79
|
+
- Portman, Natalie
|
80
|
+
- Smits, Jimmy
|
81
|
+
- Thompson, Jack
|
82
|
+
- Wood, Matthew
|
83
|
+
director:
|
84
|
+
- Lucas, George
|
85
|
+
text_relevance:
|
86
|
+
- '269'
|
87
|
+
title:
|
88
|
+
- ! 'Star Wars: Episode II - Attack of the Clones'
|
89
|
+
year:
|
90
|
+
- '2002'
|
91
|
+
- id: tt0080684
|
92
|
+
data:
|
93
|
+
actor:
|
94
|
+
- Anderson, Bob
|
95
|
+
- Baker, Kenny
|
96
|
+
- Bonehill, Richard
|
97
|
+
- Capri, Mark
|
98
|
+
- Daniels, Anthony
|
99
|
+
- Diamond, Peter
|
100
|
+
- Fisher, Carrie
|
101
|
+
- Ford, Harrison
|
102
|
+
- Guinness, Alec
|
103
|
+
- Hamill, Mark
|
104
|
+
- Jones, James Earl
|
105
|
+
- Mayhew, Peter
|
106
|
+
- McQuarrie, Ralph
|
107
|
+
- Morse, Ralph
|
108
|
+
- Oz, Frank
|
109
|
+
- Prowse, David
|
110
|
+
- Santiago, Michael
|
111
|
+
- Williams, Billy Dee
|
112
|
+
- Williams, Treat
|
113
|
+
- Wingreen, Jason
|
114
|
+
director:
|
115
|
+
- Kershner, Irvin
|
116
|
+
text_relevance:
|
117
|
+
- '268'
|
118
|
+
title:
|
119
|
+
- ! 'Star Wars: Episode V - The Empire Strikes Back'
|
120
|
+
year:
|
121
|
+
- '1980'
|
122
|
+
- id: tt0086190
|
123
|
+
data:
|
124
|
+
actor:
|
125
|
+
- Altman, John
|
126
|
+
- Bonehill, Richard
|
127
|
+
- Brooke, Paul
|
128
|
+
- Burtt, Ben
|
129
|
+
- Daniels, Anthony
|
130
|
+
- Diamond, Peter
|
131
|
+
- Fisher, Carrie
|
132
|
+
- Ford, Harrison
|
133
|
+
- Hamill, Mark
|
134
|
+
- Jones, James Earl
|
135
|
+
- Marquand, Richard
|
136
|
+
- Mayhew, Peter
|
137
|
+
- McDiarmid, Ian
|
138
|
+
- McRae, Hilton
|
139
|
+
- Oz, Frank
|
140
|
+
- Roy, Deep
|
141
|
+
- Shaw, Sebastian
|
142
|
+
- Ward, Larry
|
143
|
+
- Welsh, Pat
|
144
|
+
- Williams, Billy Dee
|
145
|
+
director:
|
146
|
+
- Marquand, Richard
|
147
|
+
text_relevance:
|
148
|
+
- '268'
|
149
|
+
title:
|
150
|
+
- ! 'Star Wars: Episode VI - Return of the Jedi'
|
151
|
+
year:
|
152
|
+
- '1983'
|
153
|
+
- id: tt0120915
|
154
|
+
data:
|
155
|
+
actor:
|
156
|
+
- Armitage, Richard
|
157
|
+
- August, Pernilla
|
158
|
+
- Best, Ahmed
|
159
|
+
- Burtt, Ben
|
160
|
+
- Chiang, Doug
|
161
|
+
- Coppola, Roman
|
162
|
+
- Daniels, Anthony
|
163
|
+
- Ford Davies, Oliver
|
164
|
+
- Hamill, Nathan
|
165
|
+
- Knoll, John
|
166
|
+
- Lau, Kamay
|
167
|
+
- Lloyd, Jake
|
168
|
+
- McCallum, Rick
|
169
|
+
- McDiarmid, Ian
|
170
|
+
- McGregor, Ewan
|
171
|
+
- Menezes, João Costa
|
172
|
+
- Neeson, Liam
|
173
|
+
- Portman, Natalie
|
174
|
+
- Quarshie, Hugh
|
175
|
+
- Wood, Matthew
|
176
|
+
director:
|
177
|
+
- Lucas, George
|
178
|
+
text_relevance:
|
179
|
+
- '268'
|
180
|
+
title:
|
181
|
+
- ! 'Star Wars: Episode I - The Phantom Menace'
|
182
|
+
year:
|
183
|
+
- '1999'
|
184
|
+
- id: tt0121766
|
185
|
+
data:
|
186
|
+
actor:
|
187
|
+
- Bai, Ling
|
188
|
+
- Bryant, Gene
|
189
|
+
- Castle-Hughes, Keisha
|
190
|
+
- Christensen, Hayden
|
191
|
+
- Cooke, Ben
|
192
|
+
- Daniels, Anthony
|
193
|
+
- Jackson, Samuel L.
|
194
|
+
- Jones, James Earl
|
195
|
+
- Knoll, John
|
196
|
+
- Lee, Christopher
|
197
|
+
- Lucas, George
|
198
|
+
- McDiarmid, Ian
|
199
|
+
- McGregor, Ewan
|
200
|
+
- Oz, Frank
|
201
|
+
- Portman, Natalie
|
202
|
+
- Smits, Jimmy
|
203
|
+
- Spence, Paul
|
204
|
+
- Steen, Suzie
|
205
|
+
- Yamaguchi, Masa
|
206
|
+
- de Souza Correa, Caroline
|
207
|
+
director:
|
208
|
+
- Lucas, George
|
209
|
+
text_relevance:
|
210
|
+
- '266'
|
211
|
+
title:
|
212
|
+
- ! 'Star Wars: Episode III - Revenge of the Sith'
|
213
|
+
year:
|
214
|
+
- '2005'
|
215
|
+
info:
|
216
|
+
rid: d1b8bf24ec64151ed54a357e94f64bd8b1dadc1d67f6f2dcbc042ac86407c68b91582fba82640f4d
|
217
|
+
time-ms: 3
|
218
|
+
cpu-time-ms: 4
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: http://doc-imdb-movies-pl6u4t3elu7dhsbwaqbsy3y6be.us-east-1.cloudsearch.amazonaws.com/2011-02-01/documents/batch
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '[{"type":"add","id":"678","version":1,"lang":"en","fields":{"actor":["Cassio
|
9
|
+
Marques","Willian Fernandes"],"director":["Lucas, George"],"title":"Troy Wars"}}]'
|
10
|
+
headers:
|
11
|
+
Content-Type:
|
12
|
+
- application/json
|
13
|
+
response:
|
14
|
+
status:
|
15
|
+
code: 200
|
16
|
+
message: OK
|
17
|
+
headers:
|
18
|
+
!binary "Q29udGVudC1UeXBl":
|
19
|
+
- !binary |-
|
20
|
+
YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
|
21
|
+
!binary "RGF0ZQ==":
|
22
|
+
- !binary |-
|
23
|
+
VHVlLCAxNiBPY3QgMjAxMiAxODowNzozOCBHTVQ=
|
24
|
+
!binary "U2VydmVy":
|
25
|
+
- !binary |-
|
26
|
+
U2VydmVy
|
27
|
+
!binary "Q29udGVudC1MZW5ndGg=":
|
28
|
+
- !binary |-
|
29
|
+
NDY=
|
30
|
+
!binary "Q29ubmVjdGlvbg==":
|
31
|
+
- !binary |-
|
32
|
+
Q2xvc2U=
|
33
|
+
body:
|
34
|
+
encoding: US-ASCII
|
35
|
+
string: ! '{"status": "success", "adds": 1, "deletes": 0}'
|
36
|
+
http_version:
|
37
|
+
recorded_at: Tue, 16 Oct 2012 18:07:42 GMT
|
38
|
+
recorded_with: VCR 2.2.5
|