swiftype-app-search 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.
- checksums.yaml +4 -4
- data/README.md +49 -57
- data/lib/swiftype-app-search/client/documents.rb +26 -2
- data/lib/swiftype-app-search/client/engines.rb +4 -2
- data/lib/swiftype-app-search/client/search.rb +20 -1
- data/lib/swiftype-app-search/version.rb +1 -1
- data/spec/client_spec.rb +143 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0889b18cde354daea10527a1e192cd972e0d7c539fa4bbee73b2683de3b3822
|
4
|
+
data.tar.gz: 0b65d19dcf830652d055ead107abdc554dcb28f3f5d74d528d2be5d53cf15d63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfe38cefe4f27e5d3056041b6166ce7779f759b77600d10bf345959dfaa2661f76543d44fbaac028814da267620824a5112334b424c18c6b9ed3c1f9bdd49fe8
|
7
|
+
data.tar.gz: 1ceada4a0bbb951a2c4a3885f683a3d5fb148569cdeb386ce9a224d7621d0402a0e33a3e424fada53b017efa9d5c5efc3b2c837a51bca6eff6a411a4a70e5803
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ To install the gem, execute:
|
|
10
10
|
gem install swiftype-app-search
|
11
11
|
```
|
12
12
|
|
13
|
-
Or place `gem 'swiftype-app-search', '~> 0.
|
13
|
+
Or place `gem 'swiftype-app-search', '~> 0.4.0` in your `Gemfile` and run `bundle install`.
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
@@ -42,15 +42,10 @@ document = {
|
|
42
42
|
:body => 'A wonderful video of a magnificent cat.'
|
43
43
|
}
|
44
44
|
|
45
|
-
|
46
|
-
response = client.index_document(engine_name, document)
|
47
|
-
puts response
|
48
|
-
rescue SwiftypeAppSearch::ClientException => e
|
49
|
-
puts e
|
50
|
-
end
|
45
|
+
client.index_document(engine_name, document)
|
51
46
|
```
|
52
47
|
|
53
|
-
#### Indexing: Creating or
|
48
|
+
#### Indexing: Creating or Replacing Documents
|
54
49
|
|
55
50
|
```ruby
|
56
51
|
engine_name = 'favorite-videos'
|
@@ -69,26 +64,37 @@ documents = [
|
|
69
64
|
}
|
70
65
|
]
|
71
66
|
|
72
|
-
|
73
|
-
response = client.index_documents(engine_name, documents)
|
74
|
-
puts response
|
75
|
-
rescue SwiftypeAppSearch::ClientException => e
|
76
|
-
puts e
|
77
|
-
end
|
67
|
+
client.index_documents(engine_name, documents)
|
78
68
|
```
|
79
69
|
|
80
|
-
####
|
70
|
+
#### Indexing: Updating Documents (Partial Updates)
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
engine_name = 'favorite-videos'
|
74
|
+
documents = [
|
75
|
+
{
|
76
|
+
:id => 'INscMGmhmX4',
|
77
|
+
:title => 'Updated title'
|
78
|
+
}
|
79
|
+
]
|
80
|
+
|
81
|
+
client.update_documents(engine_name, documents)
|
82
|
+
```
|
83
|
+
|
84
|
+
#### Retrieving Documents
|
81
85
|
|
82
86
|
```ruby
|
83
87
|
engine_name = 'favorite-videos'
|
84
88
|
document_ids = ['INscMGmhmX4', 'JNDFojsd02']
|
85
89
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
client.get_documents(engine_name, document_ids)
|
91
|
+
```
|
92
|
+
|
93
|
+
#### Listing Documents
|
94
|
+
```ruby
|
95
|
+
engine_name = 'favorite-videos'
|
96
|
+
|
97
|
+
client.list_documents(engine_name)
|
92
98
|
```
|
93
99
|
|
94
100
|
#### Destroying Documents
|
@@ -97,23 +103,13 @@ end
|
|
97
103
|
engine_name = 'favorite-videos'
|
98
104
|
document_ids = ['INscMGmhmX4', 'JNDFojsd02']
|
99
105
|
|
100
|
-
|
101
|
-
response = client.destroy_documents(engine_name, document_ids)
|
102
|
-
puts response
|
103
|
-
rescue SwiftypeAppSearch::ClientException => e
|
104
|
-
puts e
|
105
|
-
end
|
106
|
+
client.destroy_documents(engine_name, document_ids)
|
106
107
|
```
|
107
108
|
|
108
109
|
#### Listing Engines
|
109
110
|
|
110
111
|
```ruby
|
111
|
-
|
112
|
-
response = client.list_engines
|
113
|
-
puts response
|
114
|
-
rescue SwiftypeAppSearch::ClientException => e
|
115
|
-
puts e
|
116
|
-
end
|
112
|
+
client.list_engines
|
117
113
|
```
|
118
114
|
|
119
115
|
#### Retrieving Engines
|
@@ -121,12 +117,7 @@ end
|
|
121
117
|
```ruby
|
122
118
|
engine_name = 'favorite-videos'
|
123
119
|
|
124
|
-
|
125
|
-
response = client.get_engine(engine_name)
|
126
|
-
puts response
|
127
|
-
rescue SwiftypeAppSearch::ClientException => e
|
128
|
-
puts e
|
129
|
-
end
|
120
|
+
client.get_engine(engine_name)
|
130
121
|
```
|
131
122
|
|
132
123
|
#### Creating Engines
|
@@ -134,12 +125,7 @@ end
|
|
134
125
|
```ruby
|
135
126
|
engine_name = 'favorite-videos'
|
136
127
|
|
137
|
-
|
138
|
-
response = client.create_engine(engine_name)
|
139
|
-
puts response
|
140
|
-
rescue SwiftypeAppSearch::ClientException => e
|
141
|
-
puts e
|
142
|
-
end
|
128
|
+
client.create_engine(engine_name)
|
143
129
|
```
|
144
130
|
|
145
131
|
#### Destroying Engines
|
@@ -147,12 +133,7 @@ end
|
|
147
133
|
```ruby
|
148
134
|
engine_name = 'favorite-videos'
|
149
135
|
|
150
|
-
|
151
|
-
response = client.destroy_engine(engine_name)
|
152
|
-
puts response
|
153
|
-
rescue SwiftypeAppSearch::ClientException => e
|
154
|
-
puts e
|
155
|
-
end
|
136
|
+
client.destroy_engine(engine_name)
|
156
137
|
```
|
157
138
|
|
158
139
|
#### Searching
|
@@ -164,12 +145,23 @@ search_fields = { :title => {} }
|
|
164
145
|
result_fields = { :title => { :raw => {} } }
|
165
146
|
options = { :search_fields => search_fields, :result_fields => result_fields }
|
166
147
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
148
|
+
client.search(engine_name, query, options)
|
149
|
+
```
|
150
|
+
|
151
|
+
#### Multi-Search
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
engine_name = 'favorite-videos'
|
155
|
+
|
156
|
+
queries = [{
|
157
|
+
:query => 'cat',
|
158
|
+
:options => { :search_fields => { :title => {} }}
|
159
|
+
},{
|
160
|
+
:query => 'dog',
|
161
|
+
:options => { :search_fields => { :body => {} }}
|
162
|
+
}]
|
163
|
+
|
164
|
+
client.multi_search(engine_name, queries)
|
173
165
|
```
|
174
166
|
|
175
167
|
## Running Tests
|
@@ -5,13 +5,23 @@ module SwiftypeAppSearch
|
|
5
5
|
class Client
|
6
6
|
module Documents
|
7
7
|
|
8
|
-
# Retrieve Documents from the API
|
8
|
+
# Retrieve all Documents from the API for the {App Search API}[https://swiftype.com/documentation/app-search/]
|
9
9
|
#
|
10
10
|
# @param [String] engine_name the unique Engine name
|
11
|
-
# @
|
11
|
+
# @option options see the {App Search API}[https://swiftype.com/documentation/app-search/] for supported options.
|
12
12
|
#
|
13
13
|
# @return [Array<Hash>] an Array of Documents
|
14
|
+
def list_documents(engine_name, options = {})
|
15
|
+
params = Utils.symbolize_keys(options)
|
16
|
+
request(:get, "engines/#{engine_name}/documents/list", params)
|
17
|
+
end
|
14
18
|
|
19
|
+
# Retrieve Documents from the API by IDs for the {App Search API}[https://swiftype.com/documentation/app-search/]
|
20
|
+
#
|
21
|
+
# @param [String] engine_name the unique Engine name
|
22
|
+
# @param [Array<String>] ids an Array of Document IDs
|
23
|
+
#
|
24
|
+
# @return [Hash] list results
|
15
25
|
def get_documents(engine_name, ids)
|
16
26
|
get("engines/#{engine_name}/documents", ids)
|
17
27
|
end
|
@@ -46,6 +56,20 @@ module SwiftypeAppSearch
|
|
46
56
|
post("engines/#{engine_name}/documents", documents)
|
47
57
|
end
|
48
58
|
|
59
|
+
# Update a batch of documents using the {App Search API}[https://swiftype.com/documentation/app-search/].
|
60
|
+
#
|
61
|
+
# @param [String] engine_name the unique Engine name
|
62
|
+
# @param [Array] documents an Array of Document Hashes including valid ids
|
63
|
+
#
|
64
|
+
# @return [Array<Hash>] an Array of processed Document Status hashes
|
65
|
+
#
|
66
|
+
# @raise [SwiftypeAppSearch::InvalidDocument] when any documents have processing errors returned from the api
|
67
|
+
# @raise [Timeout::Error] when timeout expires waiting for statuses
|
68
|
+
def update_documents(engine_name, documents)
|
69
|
+
documents.map! { |document| normalize_document(document) }
|
70
|
+
patch("engines/#{engine_name}/documents", documents)
|
71
|
+
end
|
72
|
+
|
49
73
|
# Destroy a batch of documents given a list of IDs
|
50
74
|
#
|
51
75
|
# @param [Array<String>] ids an Array of Document IDs
|
@@ -11,8 +11,10 @@ module SwiftypeAppSearch
|
|
11
11
|
get("engines/#{engine_name}")
|
12
12
|
end
|
13
13
|
|
14
|
-
def create_engine(engine_name)
|
15
|
-
|
14
|
+
def create_engine(engine_name, language = nil)
|
15
|
+
params = { :name => engine_name }
|
16
|
+
params[:language] = language if language
|
17
|
+
post("engines", params)
|
16
18
|
end
|
17
19
|
|
18
20
|
def destroy_engine(engine_name)
|
@@ -7,11 +7,30 @@ module SwiftypeAppSearch
|
|
7
7
|
# @param [String] query the search query
|
8
8
|
# @option options see the {App Search API}[https://swiftype.com/documentation/app-search/] for supported search options.
|
9
9
|
#
|
10
|
-
# @return [
|
10
|
+
# @return [Hash] search results
|
11
11
|
def search(engine_name, query, options = {})
|
12
12
|
params = Utils.symbolize_keys(options).merge(:query => query)
|
13
13
|
request(:post, "engines/#{engine_name}/search", params)
|
14
14
|
end
|
15
|
+
|
16
|
+
# Run multiple searches for documents on a single request
|
17
|
+
#
|
18
|
+
# @param [String] engine_name the unique Engine name
|
19
|
+
# @param [{query: String, options: Hash}] searches to execute
|
20
|
+
# see the {App Search API}[https://swiftype.com/documentation/app-search/] for supported search options.
|
21
|
+
#
|
22
|
+
# @return [Array<Hash>] an Array of searh sesults
|
23
|
+
def multi_search(engine_name, searches)
|
24
|
+
params = searches.map do |search|
|
25
|
+
search = Utils.symbolize_keys(search)
|
26
|
+
query = search[:query]
|
27
|
+
options = search[:options] || {}
|
28
|
+
Utils.symbolize_keys(options).merge(:query => query)
|
29
|
+
end
|
30
|
+
request(:post, "engines/#{engine_name}/multi_search", {
|
31
|
+
queries: params
|
32
|
+
})
|
33
|
+
end
|
15
34
|
end
|
16
35
|
end
|
17
36
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -98,6 +98,143 @@ describe SwiftypeAppSearch::Client do
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
describe '#update_documents' do
|
103
|
+
let(:documents) { [document, second_document] }
|
104
|
+
let(:second_document_id) { 'another_id' }
|
105
|
+
let(:second_document) { { 'id' => second_document_id, 'url' => 'https://www.youtube.com/watch?v=9T1vfsHYiKY' } }
|
106
|
+
let(:updates) { [ {
|
107
|
+
'id' => second_document_id,
|
108
|
+
'url' => 'https://www.example.com'
|
109
|
+
} ] }
|
110
|
+
|
111
|
+
subject { client.update_documents(engine_name, updates) }
|
112
|
+
|
113
|
+
before do
|
114
|
+
client.index_documents(engine_name, documents)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Note that since indexing a document takes up to a minute,
|
118
|
+
# we don't expect this to succeed, so we simply verify that
|
119
|
+
# the request responded with the correct 'id', even though
|
120
|
+
# the 'errors' object likely contains errors.
|
121
|
+
it 'should update existing documents' do
|
122
|
+
response = subject
|
123
|
+
expect(subject).to match(['id' => second_document_id, 'errors' => anything])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#get_documents' do
|
128
|
+
let(:documents) { [first_document, second_document] }
|
129
|
+
let(:first_document_id) { 'id' }
|
130
|
+
let(:first_document) { { 'id' => first_document_id, 'url' => 'https://www.youtube.com/watch?v=v1uyQZNg2vE' } }
|
131
|
+
let(:second_document_id) { 'another_id' }
|
132
|
+
let(:second_document) { { 'id' => second_document_id, 'url' => 'https://www.youtube.com/watch?v=9T1vfsHYiKY' } }
|
133
|
+
|
134
|
+
subject { client.get_documents(engine_name, [first_document_id, second_document_id]) }
|
135
|
+
|
136
|
+
before do
|
137
|
+
client.index_documents(engine_name, documents)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'will return documents by id' do
|
141
|
+
response = subject
|
142
|
+
expect(response.size).to eq(2)
|
143
|
+
expect(response[0]['id']).to eq(first_document_id)
|
144
|
+
expect(response[1]['id']).to eq(second_document_id)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#list_documents' do
|
149
|
+
let(:documents) { [first_document, second_document] }
|
150
|
+
let(:first_document_id) { 'id' }
|
151
|
+
let(:first_document) { { 'id' => first_document_id, 'url' => 'https://www.youtube.com/watch?v=v1uyQZNg2vE' } }
|
152
|
+
let(:second_document_id) { 'another_id' }
|
153
|
+
let(:second_document) { { 'id' => second_document_id, 'url' => 'https://www.youtube.com/watch?v=9T1vfsHYiKY' } }
|
154
|
+
|
155
|
+
before do
|
156
|
+
client.index_documents(engine_name, documents)
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'when no options are specified' do
|
160
|
+
it 'will return all documents' do
|
161
|
+
response = client.list_documents(engine_name)
|
162
|
+
expect(response['results'].size).to eq(2)
|
163
|
+
expect(response['results'][0]['id']).to eq(first_document_id)
|
164
|
+
expect(response['results'][1]['id']).to eq(second_document_id)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'when options are specified' do
|
169
|
+
it 'will return all documents' do
|
170
|
+
response = client.list_documents(engine_name, {page: { size: 1, current: 2}})
|
171
|
+
expect(response['results'].size).to eq(1)
|
172
|
+
expect(response['results'][0]['id']).to eq(second_document_id)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'Search' do
|
179
|
+
# Note that since indexing a document takes up to a minute,
|
180
|
+
# don't actually expect results to be present, just that
|
181
|
+
# the request was made
|
182
|
+
|
183
|
+
before do
|
184
|
+
client.create_engine(engine_name) rescue SwiftypeAppSearch::BadRequest
|
185
|
+
end
|
186
|
+
|
187
|
+
after do
|
188
|
+
client.destroy_engine(engine_name) rescue SwiftypeAppSearch::NonExistentRecord
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '#search' do
|
192
|
+
subject { client.search(engine_name, query, options) }
|
193
|
+
let (:query) { '' }
|
194
|
+
let (:options) { { 'page' => { 'size' => 1 } } }
|
195
|
+
|
196
|
+
it 'should execute a search query' do
|
197
|
+
response = subject
|
198
|
+
expect(response).to have_key('meta')
|
199
|
+
expect(response).to have_key('results')
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#multi_search' do
|
204
|
+
subject { client.multi_search(engine_name, queries) }
|
205
|
+
|
206
|
+
context 'when options are provided' do
|
207
|
+
let (:queries) { [
|
208
|
+
{'query': 'foo', 'options' => { 'page' => { 'size' => 1 } }},
|
209
|
+
{'query': 'bar', 'options' => { 'page' => { 'size' => 1 } }}
|
210
|
+
] }
|
211
|
+
|
212
|
+
it 'should execute a multi search query' do
|
213
|
+
response = subject
|
214
|
+
expect(response.size).to eq(2)
|
215
|
+
expect(response[0]).to have_key('results')
|
216
|
+
expect(response[0]).to have_key('meta')
|
217
|
+
expect(response[1]).to have_key('results')
|
218
|
+
expect(response[1]).to have_key('meta')
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'when options are omitted' do
|
223
|
+
let (:queries) { [
|
224
|
+
{'query': 'foo' },
|
225
|
+
{'query': 'bar' }
|
226
|
+
] }
|
227
|
+
|
228
|
+
it 'should execute a multi search query' do
|
229
|
+
response = subject
|
230
|
+
expect(response.size).to eq(2)
|
231
|
+
expect(response[0]).to have_key('results')
|
232
|
+
expect(response[0]).to have_key('meta')
|
233
|
+
expect(response[1]).to have_key('results')
|
234
|
+
expect(response[1]).to have_key('meta')
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
101
238
|
end
|
102
239
|
|
103
240
|
context 'Engines' do
|
@@ -112,6 +249,12 @@ describe SwiftypeAppSearch::Client do
|
|
112
249
|
expect { client.get_engine(engine_name) }.to_not raise_error
|
113
250
|
end
|
114
251
|
|
252
|
+
it 'should accept an optional language parameter' do
|
253
|
+
expect { client.get_engine(engine_name) }.to raise_error(SwiftypeAppSearch::NonExistentRecord)
|
254
|
+
client.create_engine(engine_name, 'da')
|
255
|
+
expect(client.get_engine(engine_name)).to match('name' => anything, 'type' => anything, 'language' => 'da')
|
256
|
+
end
|
257
|
+
|
115
258
|
it 'should return an engine object' do
|
116
259
|
engine = client.create_engine(engine_name)
|
117
260
|
expect(engine).to be_kind_of(Hash)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swiftype-app-search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Quin Hoxie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|